依靠ja-netfilter插件解决smartgit新版本key验证不通过的问题 (增加Regexp支持)

很长一段时间 知了大佬都没有提供smartgit后续版本的激活办法, 一直止步于21.3版本支持(java11), 近期又见各位大佬们使用ja-netfilter做了不少软件的适配, 所以我最近一直在研究ja-netfilter在smartgit上的适配方法, 也终于做一个简易版本出来, 目前适配的是23.1.2版本.
代码仓库见:

由于smartgit混淆后的代码各种难读, 干脆放弃正面找验证点的方式, 采用java remote debugging
具体方式如下:
首先在smartgit的vmoption文件中添加

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005

然后随便建一个java工程, 将smartgit.jar添加到工程里面, 然后从smargit的日志里面找到验证license失败的报错的类开始断点跟踪, 最后终于找到了验证不通过并报错的地方, 位于 smartgit.Xs类中

  private void a(byte[] var1, MessageDigest var2, MessageDigest var3, Xq var4) {
    int var5 = a(var1);
    TN var6 = var4.b();
    TN var7 = var4.a();
    TN var8;
    if (this.a && var6 != null) {
      var8 = a(var6, this.a, this.b);
      a(var8, var3, var5);
    } else {
      if (this.a || var7 == null) {
        throw new Xp();
      }

      var8 = a(var7, this.a, this.b);
      a(var8, var2, var5);
    }
  }

接下来就是我们插件出场了, 按照国际惯例,纠正这个函数对我们的license肆意报错的不礼貌行为, 我们都知道license不对, 但是只有我们能说它不对, 这个函数说它不对就不行

  public byte[] transform(String className, byte[] classBytes, int order) throws Exception {
    ClassReader classReader = new ClassReader(classBytes);
    ClassNode classNode = new ClassNode(ASM5);
    classReader.accept(classNode, 0);
    for (MethodNode mn : classNode.methods) {
      if (methodName.equals(mn.name) && methodDesc.equals(mn.desc)) {
        DebugInfo.debug(String.format("method %s.%s (%s) matched", this.className, this.methodName,
            this.methodDesc));
        mn.instructions.clear();
        mn.instructions.insert(new InsnNode(Opcodes.RETURN));
        mn.visitEnd();
      }
    }
    ClassWriter writer = new ClassWriter(0);
    classNode.accept(writer);
    return writer.toByteArray();
  }

在对应的配置文件里面配置一下要匹配的class|method|description, 如下:

[Methods]
EQUAL,smartgit/Xs|a|(Lsmartgit/TN;Ljava/security/MessageDigest;I)V

打包编译好jar包, 复制到 ja-netfitler的plugin 目录, 配置conf目录的xxx.conf.
然后回到 smartgit.vmoption, 添加上经典的参数:

-javaagent:<ja-netfilter.jar location>
--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
--add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED

启动 smartgit, 就会发现你们从 zhile大佬那里继承来的license文件又受欢迎了 :crossed_fingers:

==================== 2024-04-26T16:00:00Z ============================
由于新版本发布时类名和函数名会产生变化, 以及smartsvn的相关需求, 在 @Neon 的建议下, 做了稍稍修改, 参见 v1.1.0, 相关配置可以修改为

[Methods]
REGEXP,smartgit/.*|.*|\([^;]+;Ljava/security/MessageDigest;I\)V

理论上应该可以进一步调整实现同时兼容smartgit 和 smartsvn什么的吧 :thinking: (没测试过), 另, 如果正则表达式里面需要有 “|”, 请用"\|" 替换

[Methods]
REGEXP,smart(git\|svn)/.*|.*|\([^;]+;Ljava/security/MessageDigest;I\)V
40 个赞

好贴不要沉

2 个赞

又是好东西

2 个赞

好东西啊

2 个赞

插件不错,如果能mock带返回值的就更好了

1 个赞

牛哥们牛!

1 个赞

天,太需要了

1 个赞

哈哈 只能我们说它不对,插件验证函数不能说它不对,太霸道了佬友

1 个赞

真会玩

1 个赞

好像懂了又好像没懂 :rofl:,回去试试

1 个赞

portable也可以使用

mark

666

牛啊,收藏了,这个要得

坛除我佬哇

牛啊,我也收藏一下,这个真要的

好东西啊!学以致用!

1 个赞

怎么我这里没成功,哪里出问题了?是需要删除appdata内某些文件吗

把vmoption发出来看下呢, 是不是ja-netfilter的配置问题哦

1 个赞

下载的是官方portable版本 smartgit_23.1.2_portable.7z

-Dsmartboot.sourceDirectory=.updates
-Dsmartgit.settings=${smartgit.installation}.settings
-XX:ErrorFile=%EXE4J_EXEDIR%….settings\hs_err_pid%p.log
#-XX:StartFlightRecording=filename=recording.jfr,dumponexit=true

–add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
–add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED

-javaagent:D:\cache\Java\jetbra\ja-netfilter.jar=smartgit

试过不加=smartgit,也是一样的

image

image