首页
社区
课程
招聘
[原创]IDEA 2019.1版本的破解文件JetbrainsCrack.jar分析
发表于: 2019-5-28 16:35 53112

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

2019-5-28 16:35
53112

从网上找到IDEA的破解文件,好像各个版本都进行了保护处理,但是确实想了解它的实现,主要是关心它打补丁的类和对应处理,所以整理一下。
对应分析版本见附件,分析如下。

这个jar文件从逆向的结果看应该是做了字符加密和混淆,考虑看是否可以反混淆:

从上面的信息可以知道是使用了ZKM(Zelix Klassmaster)工具处理保护,所以配置对应的transformers:
由于支持有限,可以进行字符解密,得到了没有字符加密的jar文件。

通过Manifest.mf中的配置信息,定位premain为Premain-Class: fuck_the_regulations.fN :
premain()
+-ew.main() # 作者信息打印
+-bk.b(instrumentation) # 重点分析
作者信息字符串:

调用处理函数:

可以看到字符串已经解密了,对于javaagent的关键代码应该是addTransformer操作,从上面的字符串信息应该在fuck_the_regulations.c0处理。
找到对应的fuck_the_regulations.c0:
transform函数就是进行破解修改的核心函数,它的原型:
public byte[] transform(final ClassLoader loader, final String className, final Class<?> classBeingRedefined, final ProtectionDomain protectionDomain, final byte[] classfileBuffer)
至此对这个破解文件中的热代理修改就清楚了,通过查找类sun/security/rsa/RSASignature和sun/net/www/protocol/https/Handler,再定位到修改类,调用javaassist进行代码更新.

通过和javassist的代码分析:
bN ===> javassist.CtClass
aO ===> javassist.ClassPool
dd ===> javassist.CtField
dc ===> javassist.CtConstructor
dL ===> javassist.CtBehavior ###
dH ===> javassist.CtNewMethod

在配置了对应的javaagent参数后,开始进行激活,同时监控idea发送的数据包信息:
1,PING
/rpc/ping.action
2,获取证书信息:
/rpc/obtainTicket.action
因此从这个分析中,它会配置激活服务器:http://jetbrains-license-server,上面的代码中有一处对应处理:


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2019-12-26 09:30 被nevinhappy编辑 ,原因: Upload My Source code .
上传的附件:
收藏
免费 14
支持
分享
最新回复 (60)
雪    币: 452
活跃值: (6128)
能力值: ( LV12,RANK:580 )
在线值:
发帖
回帖
粉丝
2
2019-5-28 16:45
0
雪    币: 233
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
2019-5-28 16:53
0
雪    币: 5182
活跃值: (9697)
能力值: ( LV9,RANK:181 )
在线值:
发帖
回帖
粉丝
4
更新了测试代码,算是结束了,这个作者的思路和其它在码云上找到的版本还有一些不同,学习了一把。
2019-6-5 18:59
0
雪    币: 5182
活跃值: (9697)
能力值: ( LV9,RANK:181 )
在线值:
发帖
回帖
粉丝
5
整了这么久,怎么没人出来提点啥? 哪怕说上次提供的代码不能用也行!!!
2019-6-19 19:24
0
雪    币: 12197
活跃值: (4152)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不错啊,还差生成证书自签就完整了
2019-6-19 20:17
0
雪    币: 5182
活跃值: (9697)
能力值: ( LV9,RANK:181 )
在线值:
发帖
回帖
粉丝
7
已经有参考了,估计需要按版本区分验证算法和生成公、私钥就可以了。
https://gitee.com/zrla/JetBrains-License-Server
2019-6-20 09:04
0
雪    币: 1887
活跃值: (360)
能力值: ( LV8,RANK:121 )
在线值:
发帖
回帖
粉丝
8
感谢分享思路 
2019-6-20 12:00
0
雪    币: 89
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
感谢楼主!!
最后于 2019-6-22 16:16 被kyleo编辑 ,原因: 无
2019-6-22 15:57
0
雪    币: 732
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
0x1.1, 反混淆 执行下面的命令后
java -jar deobfuscator-1.0.0.jar --config detect.yml 
没有生成 jar,是为何?
2019-12-26 00:03
0
雪    币: 5182
活跃值: (9697)
能力值: ( LV9,RANK:181 )
在线值:
发帖
回帖
粉丝
11
MrChuck 0x1.1, 反混淆 执行下面的命令后 java -jar deobfuscator-1.0.0.jar --config detect.yml 没有生成 jar,是为何?
进行反混淆有两步,第一步是使用detect.yml,进行混淆探测,通过查看探测到的信息,进行反混淆transformer的配置;第二步,通过配置后的config.yml,再生成反混淆后的结果。
2019-12-26 09:28
0
雪    币: 732
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
nevinhappy 进行反混淆有两步,第一步是使用detect.yml,进行混淆探测,通过查看探测到的信息,进行反混淆transformer的配置;第二步,通过配置后的config.yml,再生成反混淆后的结果。
多谢
2019-12-26 22:13
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
所以作者的认证服务器挂了, 那些激活码都没用了。 如果有本地的更好
2020-1-6 11:49
0
雪    币: 5
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
The line
       aP.a("jetbrains-license-server", InetAddress.getByName("v2.wowchina.me").getHostAddress());
resolves v2.wowchina.me and adds the ip to java hosts file associating the simbolic name jetbrains-license-server

It modifies
       sun.security.rsa.RSASignature.engineInitVerify(java.security.PublicKey p)
adding
       private static final PublicKey __k_joca;
    private static final PublicKey __k_jnca;
    private static final PublicKey __k_loca;
    private static final PublicKey __k_lnca;
    private static final BigInteger ______e=new BigInteger("65537");

 try{
       __k_joca=KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(new BigInteger("<JetProfileCAModulus>"),______e));
       __k_jnca=KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(new BigInteger("<FakeJetProfileCAModulus>"),______e));
       __k_loca=KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(new BigInteger("<JetbrainsModulus"),______e));
       __k_lnca=KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(new BigInteger("<FakeJetbrainsModulus>"),______e));
       } catch(Exception e){
               throw new RuntimeException(e);
       }
       if($1.equals(__k_joca))
               $1=__k_jnca;
       else if($1.equals(__k_loca))
               $1=__k_lnca;
       
So here is the key replacement.
       
There are two other transformers that are similar among them but seems that are not used:
       fuck_the_regulations.eQ
       fuck_the_regulations.Y
       
Seems that xml response contains a comment with signature and fake certificate that should pair with server fake private key.
2020-1-11 23:47
1
雪    币: 201
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
https://bayfiles.com/d0d7S5Mcna/jetbrains-agent-latest_zip
2020-1-15 21:27
0
雪    币: 24
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
4-10号的jetbrains-agent用deobfuscator 已经不能成功了
2020-5-31 16:44
0
雪    币: 3246
活跃值: (374)
能力值: (RANK:20 )
在线值:
发帖
回帖
粉丝
17
不知道有人验证过这个模拟floating server的keygen working不
2020-5-31 19:40
0
雪    币: 216
活跃值: (370)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
18
感谢你的内容,在你的基础上研究了下,已经都搞明白了。
服务端也自己写了,你这个还是重用原作者的。
已经成功搞定目前的2020系列全家桶。
同时改动很小,理论上只需要 HOOK 一个函数
(连那个sun/net/www/protocol/https/Handler都好像不必须,因为在线验证好像没了,anyway,还留着它。)

2020-7-8 22:01
1
雪    币: 48
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
goldenegg 感谢你的内容,在你的基础上研究了下,已经都搞明白了。 服务端也自己写了,你这个还是重用原作者的。 已经成功搞定目前的2020系列全家桶。 同时改动很小,理论上只需要 HOOK 一个函数 (连那 ...
大牛,可以参考一下吗,谢谢
2020-7-16 10:10
0
雪    币: 35
活跃值: (242)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
goldenegg 感谢你的内容,在你的基础上研究了下,已经都搞明白了。 服务端也自己写了,你这个还是重用原作者的。 已经成功搞定目前的2020系列全家桶。 同时改动很小,理论上只需要 HOOK 一个函数 (连那 ...
大牛有分析思路么,想学习学习
2020-8-4 19:52
0
雪    币: 30
活跃值: (22)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
小白不懂求问,早期jetbrains破解都是keygen,keygen里的私钥cracker是怎么获得的?
2020-9-3 15:01
0
雪    币: 5182
活跃值: (9697)
能力值: ( LV9,RANK:181 )
在线值:
发帖
回帖
粉丝
22

同步更新一个:

上传的附件:
2021-3-19 09:12
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
2021-3-19 09:40
0
雪    币: 4014
活跃值: (5665)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
nevinhappy 同步更新一个:

现在的破解失效,原来就是密钥被取消了,/etc/hosts屏蔽掉这个地址就可以了


127.0.0.1     bs.studycoder.com


BetterIntelliJ-1.20的代码

package com.asm.test;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.Iterator;
import java.util.List;

public class IdeaTransformer implements ClassFileTransformer {

    @Override
    public byte[] transform(ClassLoader var1, String var2, Class var3, ProtectionDomain var4, byte[] var5) throws IllegalClassFormatException {
        if (var2.equals("java/io/ByteArrayInputStream")) {
            ClassReader var9 = new ClassReader(var5);
            ClassNode var10 = new ClassNode();
            var9.accept(var10, 0);

            List var11 = var10.methods;
            Iterator var12 = var11.iterator();
            while (var12.hasNext()) {
                MethodNode var13 = var12.next();
                if (var13.name.equals("") && var13.desc.equals("([B)V")) {
                    InsnList var14 = var13.instructions;
                    InsnList var15 = new InsnList();

                    //非static方法,变量0为this对象

                    //调用父类构造方法
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/io/InputStream", "", "()V", false));

                    //修改mark值为0
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new InsnNode(Opcodes.ICONST_0));
                    var15.add(new FieldInsnNode(Opcodes.PUTFIELD, "java/io/ByteArrayInputStream", "mark", "I"));

                    //将构造方法参数byte[]经过base64编码后存入变量2
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Base64", "getEncoder", "()Ljava/util/Base64$Encoder;", false));
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 1));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Base64$Encoder", "encodeToString", "([B)Ljava/lang/String;", false));
                    var15.add(new VarInsnNode(Opcodes.ASTORE, 2));

                    //字符串和变量2比较是否一致
                    var15.add(new LdcInsnNode("MIIEPjCCAiagAwIBAgIBBTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE1MTEwMjA4MjE0OFoXDTE4MTEwMTA4MjE0OFowETEPMA0GA1UEAwwGcHJvZDN5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQC9WZuYgQedSuOc5TOUSrRigMw4/+wuC5EtZBfvdl4HT/8vzMW/oUlIP4YCvA0XKyBaCJ2iX+ZCDKoPfiYXiaSiH+HxAPV6J79vvouxKrWg2XV6ShFtPLP+0gPdGq3x9R3+kJbmAm8w+FOdlWqAfJrLvpzMGNeDU14YGXiZ9bVzmIQbwrBA+c/F4tlK/DV07dsNExihqFoibnqDiVNTGombaU2dDup2gwKdL81ua8EIcGNExHe82kjF4zwfadHk3bQVvbfdAwxcDy4xBjs3L4raPLU3yenSzr/OEur1+jfOxnQSmEcMXKXgrAQ9U55gwjcOFKrgOxEdek/Sk1VfOjvS+nuM4eyEruFMfaZHzoQiuw4IqgGc45ohFH0UUyjYcuFxxDSU9lMCv8qdHKm+wnPRb0l9l5vXsCBDuhAGYD6ss+Ga+aDY6f/qXZuUCEUOH3QUNbbCUlviSz6+GiRnt1kA9N2Qachl+2yBfaqUqr8h7Z2gsx5LcIf5kYNsqJ0GavXTVyWh7PYiKX4bs354ZQLUwwa/cG++2+wNWP+HtBhVxMRNTdVhSm38AknZlD+PTAsWGu9GyLmhti2EnVwGybSD2Dxmhxk3IPCkhKAK+pl0eWYGZWG3tJ9mZ7SowcXLWDFAk0lRJnKGFMTggrWjV8GYpw5bq23VmIqqDLgkNzuoog=="));
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 2));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false));

                    //创建两个标签,用于跳转,创建位置随意,主要看添加位置
                    LabelNode var16 = new LabelNode();
                    LabelNode var17 = new LabelNode();

                    //字符比较结果,一致为true,true时跳转到var16标签位置
                    var15.add(new JumpInsnNode(Opcodes.IFNE, var16));

                    //不一致继续比较下一个字符串
                    var15.add(new LdcInsnNode("MIIFOzCCAyOgAwIBAgIJANJssYOyg3nhMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0EwHhcNMTUxMDAyMTEwMDU2WhcNNDUxMDI0MTEwMDU2WjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0tQuEA8784NabB1+T2XBhpB+2P1qjewHiSajAV8dfIeWJOYGy+ShXiuedj8rL8VCdU+yH7Ux/6IvTcT3nwM/E/3rjJIgLnbZNerFm15Eez+XpWBlm5fDBJhEGhPc89Y31GpTzW0vCLmhJ44XwvYPntWxYISUrqeR3zoUQrCEp1C6mXNXEpqIGIVbJ6JVa/YI+pwbfuP51o0ZtF2rzvgfPzKtkpYQ7m7KgA8g8ktRXyNrz8boiwg7RRPeqs4uL/RK8d2KLpgLqcAB9WDpcEQzPWegbDrFO1F3z4UVNH6hrMfOLGVAxoiQhNFhZj6RumBXlPS0rmCOCkUkWrDr3l6Z3spUVgoeea+QdX682j6t7JnakaOwjzwY777SrZoi9mFFpLVhfb4haq4IWyKSHR3/0BlWXgcgI6w6LXm+V+ZgLVDON52FLcxnfftaBJz2yclEwBohq38rYEpb+28+JBvHJYqcZRaldHYLjjmb8XXvf2MyFeXrSopYkdzCvzmiEJAewrEbPUaTllogUQmnv7Rv9sZ9jfdJ/cEn8e7GSGjHIbnjV2ZMQ9vTpWjvsT/cqatbxzdBo/iEg5i9yohOC9aBfpIHPXFw+fEj7VLvktxZY6qThYXRRus1WErPgxDzVpNp+4gXovAYOxsZak5oTV74ynv1aQ93HSndGkKUE/qA/JECAwEAAaOBhzCBhDAdBgNVHQ4EFgQUo562SGdCEjZBvW3gubSgUouX8bMwSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAjrPAZ4xC7sNiSSqh69s3KJD3Ti4etaxcrSnD7r9rJYpKBMviCKZRKFbLv+iaF5JK5QWuWdlgA37ol7mLeoF7aIA9b60Ag2OpgRICRG79QY7ouLviF/yRMqm6yno7NYkGLd61e5Huu+BfT459MWG9RVkG/DY0sGfkyTHJS5xrjBV6hjLG0lf3orwqOlqSNRmhvn9sMzwAP3ILLM5VJC5jNF1zAk0jrqKz64vuA8PLJZlLS9TZJIYwdesCGfnN2AETvzf3qxLcGTF038zKOHUMnjZuFW1ba/12fDK5GJ4i5y+nfDWVZVUDYOPUixEZ1cwzmf9Tx3hR8tRjMWQmHixcNC8XEkVfztID5XeHtDeQ+uPkX+jTDXbRb+77BP6n41briXhm57AwUI3TqqJFvoiFyx5JvVWG3ZqlVaeU/U9e0gxn8qyR+ZA3BGbtUSDDs8LDnE67URzK+L+q0F2BC758lSPNB2qsJeQ63bYyzf0du3wB/gb2+xJijAvscU3KgNpkxfGklvJD/oDUIqZQAnNcHe7QEf8iG2WqaMJIyXZlW3me0rn+cgvxHPt6N4EBh5GgNZR4l0eaFEV+fxVsydOQYo1RIyFMXtafFBqQl6DDxujlFeU3FZ+Bcp12t7dlM4E0/sS1XdL47CfGVj4Bp+/VbF862HmkAbd7shs7sDQkHbU="));
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 2));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false));

                    //字符比较结果,不一致时跳转到var17标签位置
                    var15.add(new JumpInsnNode(Opcodes.IFEQ, var17));

                    //以上两处字符串比较一致时都运行到此处
                    //标记var16标签
                    var15.add(var16);

                    //替换传入参数
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Base64", "getDecoder", "()Ljava/util/Base64$Decoder;", false));
                    var15.add(new LdcInsnNode("MIIDlzCCAn+gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDEw1KZXRQcm9maWxlIENBMCAXDTE4MTEwMTEyMjk0NloYDzIwOTkwODA5MDIyNjA3WjBoMQswCQYDVQQGEwJDWjEOMAwGA1UECBMFTnVzbGUxDzANBgNVBAcTBlByYWd1ZTEZMBcGA1UEChMQSmV0QnJhaW5zIHMuci5vLjEdMBsGA1UEAxMUcHJvZDN5LWZyb20tMjAxODExMDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdXyaNhhRySH1a8d7c8SlLLFdNcQP8M3gNnq7gudcpHC651qxRrN7Qks8gdXlIkA4u3/lp9ylp95GiIIDo4ydYje8vlTWDq02bkyWW/G7gZ3hkbBhRUK/WnNyr2vwWoOgwx5CfTRMjKkPkfD/+jffkfNfdGmGcg9yfnqPP9/AizKzWTsXSeS+0jZ8Nw5tiYFW+lpceqlzwzKdTHug7Vs0QomUPccRtZB/TBBEuiC7YzrvLg4Amu0I48ETAcch/ztt00nx/oj/fu1DTnz4Iz4ilrNY+WVIEfDz/n3mz+PKI9kM+ZeB0jAuyLsiC7skGpIVGX/2HqmZTtJKBZCoveAiVAgMBAAGjgZkwgZYwSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TAJBgNVHRMEAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGA1UdDwQEAwIFoDAdBgNVHQ4EFgQUYSkb2hkZx8swY0GRjtKAeIwaBNwwDQYJKoZIhvcNAQELBQADggEBAJZOakWgjfY359glviVffBQFxFS6C+4WjYDYzvzjWHUQoGBFKTHG4xUmTVW7y5GnPSvIlkaj49SzbD9KuiTc77GHyFCTwYMz+qITgbDg3/ao/x/be4DD/k/byWqW4Rb8OSYCshX/fNI4Xu+hxazh179taHX4NaH92ReLVyXNYsooq7mE5YhR9Qsiy35ORviQLrgFrMCGCxT9DWlFBuiPWIOqN544sL9OzFMz+bjqjCoAE/xfIJjI7H7SqGFNrx/8/IuF0hvZbO3bLIz+BOR1L2O+qT728wK6womnp2LLANTPbwu7nf39rpP182WW+xw2z9MKYwwMDwGR1iTYnD4/Sjw="));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Base64$Decoder", "decode", "(Ljava/lang/String;)[B", false));
                    var15.add(new VarInsnNode(Opcodes.ASTORE, 1));


                    //标记var17标签
                    var15.add(var17);

                    //buf赋值
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 1));
                    var15.add(new FieldInsnNode(Opcodes.PUTFIELD, "java/io/ByteArrayInputStream", "buf", "[B"));

                    //pos赋值0
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new InsnNode(Opcodes.ICONST_0));
                    var15.add(new FieldInsnNode(Opcodes.PUTFIELD, "java/io/ByteArrayInputStream", "pos", "I"));

                    //count赋值数组长度
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 1));
                    var15.add(new InsnNode(Opcodes.ARRAYLENGTH));
                    var15.add(new FieldInsnNode(Opcodes.PUTFIELD, "java/io/ByteArrayInputStream", "count", "I"));

                    //返回
                    var15.add(new InsnNode(Opcodes.RETURN));

                    var14.clear();
                    var14.add(var15);

                    var13.exceptions.clear();
                    var13.visitEnd();

                    ClassWriter var18 = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
                    var10.accept(var18);

                    return var18.toByteArray();
                }
            }
        }
        if (var2.equals("java/util/Arrays")) {
            ClassReader var9 = new ClassReader(var5);
            ClassNode var10 = new ClassNode();
            var9.accept(var10, 0);

            List var11 = var10.methods;
            Iterator var12 = var11.iterator();
            while (var12.hasNext()) {
                MethodNode var13 = var12.next();
                if (var13.name.equals("equals") && var13.desc.equals("([B[B)Z")) {
                    InsnList var14 = var13.instructions;
                    InsnList var15 = new InsnList();

                    LabelNode var16 = new LabelNode();
                    LabelNode var17 = new LabelNode();

                    //static方法,变量0为第一个参数,null跳到var16
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new JumpInsnNode(Opcodes.IFNULL, var16));

                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Base64", "getEncoder", "()Ljava/util/Base64$Encoder;", false));
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Base64$Encoder", "encodeToString", "([B)Ljava/lang/String;", false));
                    var15.add(new VarInsnNode(Opcodes.ASTORE, 2));


                    var15.add(new LdcInsnNode("dcc+F+1UvLoQW9oLY67mo3ImO2dEDv6t0aMRLmu3bUMZJ5c5c8EAWOGZ75ek809JiWLd1k5IcgZaXccSIKGaAQ=="));
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 2));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false));

                    //一致时跳转到var17
                    var15.add(new JumpInsnNode(Opcodes.IFNE, var17));

                    var15.add(new LdcInsnNode("AXilfPnlA2jsnBcIuPj+SOz4yBvnVKtbRcaw5aPMcGvIo+y1BrbiDlhVeLzpOOccp6goKo3j82bLrEBf5tcG7w=="));
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 2));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false));


                    //不一致时转到var16
                    var15.add(new JumpInsnNode(Opcodes.IFEQ, var16));

                    //以上两处字符串比较一致时都运行到此处
                    var15.add(var17);

                    //返回true
                    var15.add(new InsnNode(Opcodes.ICONST_1));
                    var15.add(new InsnNode(Opcodes.IRETURN));

                    var15.add(var16);

                    //以上代码插入到方法最前最前
                    var14.insertBefore(var14.getFirst(), var15);

                    var13.visitEnd();

                    ClassWriter var18 = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
                    var10.accept(var18);

                    return var18.toByteArray();
                }
            }
        }
        if (var2.equals("java/net/URL")) {
            ClassReader var9 = new ClassReader(var5);
            ClassNode var10 = new ClassNode();
            var9.accept(var10, 0);

            List var11 = var10.methods;
            Iterator var12 = var11.iterator();
            while (var12.hasNext()) {
                MethodNode var13 = var12.next();
                //public URL(URL context, String spec, URLStreamHandler handler)
                if (var13.name.equals("") && var13.desc.equals("(Ljava/net/URL;Ljava/lang/String;Ljava/net/URLStreamHandler;)V")) {
                    InsnList var14 = var13.instructions;
                    InsnList var15 = new InsnList();

                    LabelNode var16 = new LabelNode();

                    var15.add(new VarInsnNode(Opcodes.ALOAD, 2));
                    var15.add(new JumpInsnNode(Opcodes.IFNULL, var16));

                    var15.add(new VarInsnNode(Opcodes.ALOAD, 2));
                    var15.add(new LdcInsnNode("https://account.jetbrains.com/lservice/rpc/validateKey.action"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "startsWith", "(Ljava/lang/String;)Z", false));
                    var15.add(new JumpInsnNode(Opcodes.IFEQ, var16));

                    //替换网址
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 2));
                    var15.add(new LdcInsnNode("https://account.jetbrains.com/lservice/rpc/validateKey.action"));
                    var15.add(new LdcInsnNode("http://bs.studycoder.com/lservice/rpc/validateKey.action"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "replace", "(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;", false));
                    var15.add(new VarInsnNode(Opcodes.ASTORE, 2));

                    var15.add(var16);

                    var14.insertBefore(var14.getFirst(), var15);

                    var13.visitEnd();

                }

                if (var13.name.equals("getHost") && var13.desc.equals("()Ljava/lang/String;")) {
                    InsnList var14 = var13.instructions;
                    InsnList var15 = new InsnList();

                    LabelNode var16 = new LabelNode();

                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;", false));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Thread", "getStackTrace", "()[Ljava/lang/StackTraceElement;", false));
                    var15.add(new InsnNode(Opcodes.ICONST_2));
                    var15.add(new InsnNode(Opcodes.AALOAD));
                    //变量0为this,无参数,存储到变量1
                    var15.add(new VarInsnNode(Opcodes.ASTORE, 1));

                    //字符串和host比较
                    var15.add(new LdcInsnNode("bs.studycoder.com"));
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new FieldInsnNode(Opcodes.GETFIELD, "java/net/URL", "host", "Ljava/lang/String;"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false));

                    //不一致跳转
                    var15.add(new JumpInsnNode(Opcodes.IFEQ, var16));

                    //字符串和path比较
                    var15.add(new LdcInsnNode("/lservice/rpc/validateKey.action"));
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new FieldInsnNode(Opcodes.GETFIELD, "java/net/URL", "path", "Ljava/lang/String;"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false));

                    //不一致跳转
                    var15.add(new JumpInsnNode(Opcodes.IFEQ, var16));

                    //取上面保存变量
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 1));
                    //null跳转
                    var15.add(new JumpInsnNode(Opcodes.IFNULL, var16));

                    //比较调用堆栈的类所属包
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 1));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StackTraceElement", "getClassName", "()Ljava/lang/String;", false));
                    var15.add(new LdcInsnNode("com.jetbrains"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "startsWith", "(Ljava/lang/String;)Z", false));
                    //不一致跳转
                    var15.add(new JumpInsnNode(Opcodes.IFEQ, var16));

                    var15.add(new LdcInsnNode("account.jetbrains.com"));
                    var15.add(new InsnNode(Opcodes.ARETURN));

                    var15.add(var16);

                    var14.insertBefore(var14.getFirst(), var15);

                    var13.visitEnd();
                }
            }
            ClassWriter var18 = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
            var10.accept(var18);
            return var18.toByteArray();
        }
        return var5;
    }
}


最后于 2021-4-26 15:17 被guduzhe编辑 ,原因:
2021-4-26 14:01
2
雪    币: 5182
活跃值: (9697)
能力值: ( LV9,RANK:181 )
在线值:
发帖
回帖
粉丝
25
guduzhe nevinhappy 同步更新一个: 现在的破解失效,原来就是密钥被取消了,/etc/hosts屏蔽掉这个地址就可以了127.0.0.1& ...
你这个是还原的,还是自己写的?
2021-4-26 16:08
0
游客
登录 | 注册 方可回帖
返回
//