首页
论坛
课程
招聘
[原创]IDEA 2019.1版本的破解文件JetbrainsCrack.jar分析
2019-5-28 16:35 32312

[原创]IDEA 2019.1版本的破解文件JetbrainsCrack.jar分析

2019-5-28 16:35
32312
收藏
点赞6
打赏
分享
最新回复 (44)
雪    币: 2415
活跃值: 活跃值 (604)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guduzhe 活跃值 2021-4-26 16:31
26
0
nevinhappy 你这个是还原的,还是自己写的?

还原的,premain里这样调用就可以了

//第二个参数一定要设置为true
inst.addTransformer(new IdeaTransformer(),true);

try {//addTransformer第二个参数设置为true时生效
    inst.retransformClasses(new Class[]{Class.forName("java.lang.String")});
    inst.retransformClasses(new Class[]{Class.forName("java.util.Timer")});
    inst.retransformClasses(new Class[]{Class.forName("java.util.Base64")});
    inst.retransformClasses(new Class[]{Class.forName("java.io.ByteArrayInputStream")});
    inst.retransformClasses(new Class[]{Class.forName("java.util.Arrays")});
    inst.retransformClasses(new Class[]{Class.forName("java.net.URL")});
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}


雪    币: 2415
活跃值: 活跃值 (604)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guduzhe 活跃值 2021-4-26 16:33
27
0
nevinhappy 你这个是还原的,还是自己写的?


还原的,premain里这样调用就可以了

//第二个参数一定要设置为true
inst.addTransformer(new IdeaTransformer(),true);

try {//addTransformer第二个参数设置为true时生效
    inst.retransformClasses(new Class[]{Class.forName("java.lang.String")});
    inst.retransformClasses(new Class[]{Class.forName("java.util.Timer")});
    inst.retransformClasses(new Class[]{Class.forName("java.util.Base64")});
    inst.retransformClasses(new Class[]{Class.forName("java.io.ByteArrayInputStream")});
    inst.retransformClasses(new Class[]{Class.forName("java.util.Arrays")});
    inst.retransformClasses(new Class[]{Class.forName("java.net.URL")});
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}


雪    币: 2415
活跃值: 活跃值 (604)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guduzhe 活跃值 2021-4-26 16:34
28
0

以为没回复成功,没想到在第二页,怎么删除回复。

最后于 2021-4-26 16:37 被guduzhe编辑 ,原因:
雪    币: 834
活跃值: 活跃值 (1898)
能力值: ( LV9,RANK:176 )
在线值:
发帖
回帖
粉丝
nevinhappy 活跃值 2 2021-4-26 17:06
29
0
guduzhe 还原的,premain里这样调用就可以了//第二个参数一定要设置为true inst.addTransformer(new IdeaTransformer(),true); ...
怎么还原?我是通过DUMP出来的补丁,自己写出来的。内容和还原的一样。
雪    币: 2415
活跃值: 活跃值 (604)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guduzhe 活跃值 2021-4-26 17:33
30
0
nevinhappy 怎么还原?我是通过DUMP出来的补丁,自己写出来的。内容和还原的一样。

ZKM的INVOKEDYNAMIC指令都是一样,比如下面这条

INVOKEDYNAMIC Y (JJ)Z handle[H_INVOKESTATIC fuck_you/b1.a(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;] args[]

INVOKEDYNAMIC后面的Y,都是通过计算来区分调用类型的,比如Field是静态的getter和setter方法还是动态,Method是findVirtual、findStatic还是findSpecial,这些用处不大。

只需要关注这个dynamic指令解析类,这里是fuck_you/b1,找类的(JJ)Ljava/lang/reflect/Field;和(JJ)Ljava/lang/reflect/Method;这两个方法就行,注入输出就可以,根据long数值搜索实际做了什么操作。

java代理参数没有限制,我们在其他代理类之前执行就可以了。


如果有人能解出这些long数值的计算方法,估计就不用输出,直接还原正常代码了。

最后于 2021-4-26 17:36 被guduzhe编辑 ,原因:
雪    币: 834
活跃值: 活跃值 (1898)
能力值: ( LV9,RANK:176 )
在线值:
发帖
回帖
粉丝
nevinhappy 活跃值 2 2021-4-27 15:25
31
0
guduzhe nevinhappy 怎么还原?我是通过DUMP出来的补丁,自己写出来的。内容和还原的一样。 ZKM的INVOKEDYNAMIC指令都是一样,比 ...
对这两句没有太理解,有没有啥具体的内容。
···
只需要关注这个dynamic指令解析类,这里是fuck_you/b1,找类的(JJ)Ljava/lang/reflect/Field;和(JJ)Ljava/lang/reflect/Method;这两个方法就行,注入输出就可以,根据long数值搜索实际做了什么操作。
···
雪    币: 2415
活跃值: 活跃值 (604)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guduzhe 活跃值 2021-4-27 15:44
32
0
nevinhappy 对这两句没有太理解,有没有啥具体的内容。 ··· 只需要关注这个dynamic指令解析类,这里是fuck_you/b1,找类的(JJ)Ljava/lang/reflect/Field;和(JJ)L ...

拦截结果

-3802705931672136433:95462646008613:public abstract void java.lang.instrument.Instrumentation.addTransformer(java.lang.instrument.ClassFileTransformer,boolean)
8923367779079012573:73296439639028:public static boolean fuck_you.ao.b
8925782691333146343:73296439639028:public boolean java.lang.String.equals(java.lang.Object)
8925782691333146343:73296439639028:public boolean java.lang.String.equals(java.lang.Object)
8925782691333146343:73296439639028:public boolean java.lang.String.equals(java.lang.Object)


用recaf看字节码就行了,比如这两个long,实际只能看到第一个long,第二个是xor得到的,这个无关紧要,因为一个方法内第二个long都是一致的

8923367779079012573:73296439639028:public static boolean fuck_you.ao.b


这样的局限就是只能显示这个方法内运行流程中调用的方法,没有用到的可以自己修改,比如zkm 15.0,自己改的

public static String a(String mark, long var4, long var6) {
    int type = mark.charAt(0) ^ ((int) var6) & 7;
    String rtn;
    if (type == 106 || type == 107 || type == 105 || type == 109) {//105:i 106:j 107:k 109:m
        Field field = aae.c(var4, var6);
        if (type == 106) {
            rtn = "findGetter";
        } else if (type == 107) {
            rtn = "findSetter";
        } else if (type == 105) {
            rtn = "findStaticGetter";
        } else {
            rtn = "findStaticSetter";
        }
        rtn = rtn + ":" + field.toString();
    } else {
        Method method = aae.d(var4, var6);
        if (type == 110) {
            rtn = "findVirtual";
        } else if (type == 113) {
            rtn = "findStatic";
        } else {
            rtn = "findSpecial";
        }
        rtn = rtn + ":" + method.toString();
    }
    return rtn;
}


mark就是INVOKEDYNAMIC后面跟的字符,后面两个long就是拦截到的,因为第二个long通用,所以方法内的所有都能解析出来。我一般在arthas里用

ognl '@com.zelix.tool.Tool@a("l",-4720786595021763945L,140189597281954L)'


雪    币: 834
活跃值: 活跃值 (1898)
能力值: ( LV9,RANK:176 )
在线值:
发帖
回帖
粉丝
nevinhappy 活跃值 2 2021-4-28 15:58
33
0
guduzhe 拦截结果-3802705931672136433:95462646008613:public abstract void java.lang.in ...

我使用的工具的还原结果如下图,我试着理解一下你的过程,就是通过上面插入指令的输出内容,再通过agent向bv.a()中插入代码,在调用的时候输出具体的调用函数信息对吧 ?

另外,从你的还原结果和源码结构比较接近,对流程和这些打印信息怎么生成那个反混淆结果 ?根据内容整理的还是说能还原出来指令再反编译的 ?

最后于 2021-4-28 16:08 被nevinhappy编辑 ,原因:
雪    币: 2415
活跃值: 活跃值 (604)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guduzhe 活跃值 2021-4-28 18:33
34
0
nevinhappy guduzhe 拦截结果-3802705931672136433:95462646008613:public abstract& ...

根据这个值


查拦截的结果

-3802705931672136433:95462646008613:public abstract void java.lang.instrument.Instrumentation.addTransformer(java.lang.instrument.ClassFileTransformer,boolean)
8923367779079012573:73296439639028:public static boolean fuck_you.ao.b
8925782691333146343:73296439639028:public boolean java.lang.String.equals(java.lang.Object)
8925782691333146343:73296439639028:public boolean java.lang.String.equals(java.lang.Object)
8925782691333146343:73296439639028:public boolean java.lang.String.equals(java.lang.Object)

这不就直接知道运行什么方法,做了什么操作了么。这是最简单最笨,同样很繁琐的,每行代码都要去看。


既然知道方法了,这样可以通过recaf来还原指令,用recaf修改都是手工的。


现在尝试用asm去修改java字节码,用程序修改会快很多,现在大体有构想了,还只是能打印单个方法中的字符串,以后慢慢去完善。




下一步就可以修改指令,将这几行字节码用LDC指令替换就可以了。


这个是修改invokedynamic的方法获取字符串,然后再考虑去修invokedynamic调用的方法。


一步步来,现在只能单个方法,但是能省去许多手工执行命令的步骤。


静态分析太难,一些动态的可以交给arthas去做,动静结合,效果会好点。

雪    币: 341
活跃值: 活跃值 (311)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xdnice 活跃值 2021-4-30 08:14
35
0
guduzhe nevinhappy 同步更新一个: 现在的破解失效,原来就是密钥被取消了,/etc/hosts屏蔽掉这个地址就可以了127.0.0.1& ...
谢谢分享。
雪    币: 2415
活跃值: 活跃值 (604)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guduzhe 活跃值 2021-5-1 21:34
36
0

rover12421的特殊字符给去掉了,可以研究了,应该没有修改坏了jar文件。

最后于 2021-5-1 21:38 被guduzhe编辑 ,原因: 去掉jar包里的签名验证
上传的附件:
雪    币: 2415
活跃值: 活跃值 (604)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guduzhe 活跃值 2021-5-11 13:04
37
2

idea的证书验证有官方代码

4. Add marketplace license verification calls to the plugin code—JetBrains Marketplace

或者

JetBrains/marketplace-makemecoffee-plugin (github.com)


key结构里面也有,减号分割的四部分,第一部分位id,第二部分就是BASE64编码的字符串,也就是证书内容,第三部分是签名,第四部分是证书。

    String[] licenseParts = key.split("-");
    if (licenseParts.length !=  4) {
      return false; // invalid format
    }

    final String licenseId = licenseParts[0];
    final String licensePartBase64 = licenseParts[1];
    final String signatureBase64 = licenseParts[2];
    final String certBase64 = licenseParts[3];

前两部分随便改,只要可以替换签名和证书就行了,可以自己生成证书进行签名,然后替换掉agent代码中的证书就可以了。至于agent中java/util/Arrays两个比较,分别为Certificate.getEncoded()和Certificate.getPublicKey().getEncoded()的结果经特定算法计算而来的,然后与那两个变量比较,这两个比较的值是硬编码写在idea.jar中的,只不过不是BASE64格式,二是16进制字符串,加密过的,直接搜索不到的。


给一个修改过的agent和key。


D02JT2S8T0-eyJsaWNlbnNlSWQiOiJEMDJKVDJTOFQwIiwibGljZW5zZWVOYW1lIjoi5Lit5Zu954mb6YC8IiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IiIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiSUkiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkFDIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJEUE4iLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUlNDIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBTIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU0YiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiR08iLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRNIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IkNMIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSUzAiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUkMiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUkQiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IlBDIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSU1YiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUlNVIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJSTSIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiV1MiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6ZmFsc2V9LHsiY29kZSI6IkRCIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJEQyIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQREIiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUFdTIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBHTyIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQUFMiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUFBDIiwicGFpZFVwVG8iOiIyMDk5LTEyLTMxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBSQiIsInBhaWRVcFRvIjoiMjA5OS0xMi0zMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQU1ciLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiRFAiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUlMiLCJwYWlkVXBUbyI6IjIwOTktMTItMzEiLCJleHRlbmRlZCI6dHJ1ZX1dLCJtZXRhZGF0YSI6IjAxMjAyMDA3MjhFUEpBMDA4MDA2IiwiaGFzaCI6IjE1MDIxMzU0LzA6LTEyNTExMTQ3MTciLCJncmFjZVBlcmlvZERheXMiOjAsImF1dG9Qcm9sb25nYXRlZCI6ZmFsc2UsImlzQXV0b1Byb2xvbmdhdGVkIjpmYWxzZX0=-GM19H3TS7ztsQa4n/tzRGnDU3fN2hGC17Zp6Y4l4Lbw4C9YEnby7Xa6sx3mwBOB2wKKhYOxSe/AWfL0og8SlpeD7VjfNfbcVQJsaV12uTHsXnZtCa4HybZq48lcSKHlm4yeewSErSssrDYdw4Zfxgdf37RlV0qznGHW3SJBX+6gegkkgrpUQYOmv3Pxv/H7Hwhp4Gabe9UuGa5wfl1WWyHSMe43WveXhptZE6unDWItCM+ZHZbKyWhV0NBjlQ8nFt2Q7UdIRZgsbqzWxYBViJunDjQGEfyAiQg//9Okm8y0bCuUdjk/He5/ay6N+msQHFkjMxrQhhxiEqIzTddJemg==-MIIDpDCCAoygAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMCAXDTE4MTEwMTEyMjA0NloYDzIwOTkwODA5MDIyNjA3WjBoMQswCQYDVQQGEwJDWjEOMAwGA1UECAwFTnVzbGUxDzANBgNVBAcMBlByYWd1ZTEZMBcGA1UECgwQSmV0QnJhaW5zIHMuci5vLjEdMBsGA1UEAwwUcHJvZDN5LWZyb20tMjAxODExMDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8zN/3v/FJOYmWXm9NZ9C8kbfji3AC4m6gI6LtF4yneuCT3zPv8XbC083t9LnfMLEnhnkQMJATSaRbbrWhSDtdUrwE00EBc7DTBn9Fhm7VbCX0XRL9hEaHUtyjRCJ1ajtuPg+/BmGF0ecul/rcT3EcXwrMSiRCKjgaRnrUbtYBca1cBqG3iibG6XotwCJo26FaDbMXbkolemRGzYKcMt8QM9qVN8uIftDbmls1KLv92MKfliVJvztyUUF2v6Jz4FiyO97C9gl31wSfkSBoQ6bgWy4mU2wvqHTQW9C0PX23W3dAOmBpFaSQNi3+JArWMVnzyVrmpweZPxBHlQIb9GkDAgMBAAGjgaYwgaMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUYSkb2hkZx8swY0GRjtKAeIwaBNwwSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQCpNbQatJpW3LhNNgu84cuP5jhcMeLqaUmC49Ng3dZd8cSvKnUSGV1TDj0SsR0tbyzdUgDQfscWzt1uqXyJ/5XYJZgUWL8WAU10Wx+ZRgLf8mH9h4/UkNFMu3CeG0TIvhvJ7HPyEgOdS709Za3hqjoER+er8H6t+xyIPp1gfTroUFbvDLgPtRADf/lxDTyv9HqTMW5Pc3hlDvf3veJCPrQP4pfC49zH8dSVSYewVZocER6mTQ3uV9s967XdvoGnGxZOoQimGsHjwwQtJ8CwxeEf2YK+ssYrag7GvDqYk1+GvAbq3oPFLgmhaPBMg8f3rqofbnSQBP/q1gXUrVZB4dqT


最后于 2021-5-14 15:14 被guduzhe编辑 ,原因:
上传的附件:
雪    币: 37
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
sf_dream 活跃值 2021-6-17 18:41
38
0
卧槽,各位神仙打架
雪    币: 37
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
sf_dream 活跃值 2021-6-17 18:50
39
0
大佬,请教一下,这段话中的【至于agent中java/util/Arrays两个比较,分别为Certificate.getEncoded()和Certificate.getPublicKey().getEncoded()的结果经特定算法计算而来的,然后与那两个变量比较】两个变量是什么东西呀?是idea官方内置的字符串吗?
雪    币: 2415
活跃值: 活跃值 (604)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guduzhe 活跃值 2021-6-21 08:38
40
0
sf_dream 大佬,请教一下,这段话中的【至于agent中java/util/Arrays两个比较,分别为Certificate.getEncoded()和Certificate.getPublicKey().ge ...
是的,在idea.jar中,用于验证key中证书是不是伪造的。
雪    币: 37
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
sf_dream 活跃值 2021-6-21 11:40
41
0
guduzhe 是的,在idea.jar中,用于验证key中证书是不是伪造的。
哦,那他既然写死了,肯定是有一定的计算规则生成的这个字符串,我们利用自己生成的证书去比对,能成功吗?特定的算法是什么算法,这块儿能再解惑一下吗,我感觉是不是进入思维误区了
雪    币: 5
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_zjwuturb 活跃值 2021-7-5 17:26
42
0
sf_dream 哦,那他既然写死了,肯定是有一定的计算规则生成的这个字符串,我们利用自己生成的证书去比对,能成功吗?特定的算法是什么算法,这块儿能再解惑一下吗,我感觉是不是进入思维误区了[em_78]
https://github.com/alphazero/Blake2b
雪    币: 37
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
sf_dream 活跃值 2021-7-20 15:16
43
0
mb_zjwuturb https://github.com/alphazero/Blake2b
感谢
雪    币: 241
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
努力吧 活跃值 2021-7-21 21:57
44
0
我怎么感觉像是在看天书呀
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
git_12977huolongguo10 活跃值 2021-7-22 13:38
45
0
努力吧 我怎么感觉像是在看天书呀[em_12]
刚开始都这样,可以看看《加密与解密》
游客
登录 | 注册 方可回帖
返回