Charles 4.5.1 静态逆向 自动化Patch

https://blog.csdn.net/Kaitiren/article/details/83182108

主要思路来自于这里,这里会利用ASM提供一种更为简单的逆向方法,
对于大佬们那些爆破,对我来说就太难了,静态破解是最简单的方法了。

我们找到那篇文章找到的一个入口点,然后根据他的思路进行修改。
(没想到这种商业软件能会出现如此简单的验证)

image.png

修改后:

image.png

之后我们编译导出:

image.png

替换运行测试:

image.png

成功了,这个方法是可行的。

接下来我们开始实现自动化破解,使用ObjectWeb ASM框架
使用了我自己整合的框架(Radon混淆器ClassWrapper),并添加了一些东西,让他能够更容易使用。

[Java] 纯文本查看 复制代码

        // 加载根目录下以 input.jar 为名称的文件,输出为 output.jar 的文件。
        File input = new File("input.jar");
        File output = new File("output.jar");

        // 检查文件是否存在

        if(!input.exists()){
            logger.info("目标 input.jar 文件不存在. ");
            System.exit(0);
        }

        ClassEditor classEditor = new ClassEditor(logger, input, output);
        classEditor.init(); // 初始化加载 class 文件

对于静态破解,我们还需要对目标类进行条件匹配,所以先以我手中的样本为例
目标类的名称为YQUd,我们直接写死并输出类信息

[Java] 纯文本查看 复制代码

         classEditor.getClasses().values().forEach(classWrapper -> {
            if(classWrapper.getName().equals("com/xk72/charles/YQUd")){
                System.out.println(classWrapper.getName() + ": " + classWrapper.getMethods().size() + "-" + classWrapper.getFields().size() + "-" + classWrapper.getAccessFlags());
            }
        });

image.png

由此可知,目标类拥有26个方法,70个Field,Access为49

image.png

由此写出匹配:
[Java] 纯文本查看 复制代码

    private static boolean isTargetClass(ClassWrapper cw){
        return cw.getMethods().size() == 26 && cw.getFields().size() == 70 && cw.getAccessFlags() == 49;
    }

接下来我们需要定位那两个目标方法,并进行修改。

首先我们需要把boolean类型的那个方法进行匹配+修改:

image.png

到整个类找了一下发现就只有这一个是boolean类型且访问权限为9,所以匹配写起来也就轻松多了。

[Java] 纯文本查看 复制代码

    private static boolean isTargetBooleanMethod(MethodWrapper mw){
        return mw.getAccessFlags() == 9 && mw.getDescription().equals("()Z");
    }

之后我们就可以直接patch掉这个方法:
[Java] 纯文本查看 复制代码

                    if(isTargetBooleanMethod(methodWrapper)) {
                        // 对 instruction 进行清理 并返回true
                        methodWrapper.getMethodNode().instructions.clear();

                        methodWrapper.getMethodNode().instructions.add(new InsnNode(ICONST_1)); // 返回 TRUE
                        methodWrapper.getMethodNode().instructions.add(new InsnNode(IRETURN));

                        methodWrapper.getMethodNode().tryCatchBlocks.clear();
                        methodWrapper.getMethodNode().localVariables.clear();
                        methodWrapper.getMethodNode().exceptions.clear();
                        methodWrapper.getMethodNode().maxStack = 1;
                        methodWrapper.getMethodNode().maxLocals = 1;
                    }

对那个静态字符串的方法 处理方法甚是相同:
[Asm] 纯文本查看 复制代码

                    if(isTargetStringMethod(methodWrapper)){
                        // 对 instruction 进行清理 并返回水印
                        methodWrapper.getMethodNode().instructions.clear();

                        methodWrapper.getMethodNode().instructions.add(new LdcInsnNode("Cracked by UltraPanda")); // 返回 TRUE
                        methodWrapper.getMethodNode().instructions.add(new InsnNode(ARETURN));

                        methodWrapper.getMethodNode().tryCatchBlocks.clear();
                        methodWrapper.getMethodNode().localVariables.clear();
                        methodWrapper.getMethodNode().exceptions.clear();
                        methodWrapper.getMethodNode().maxStack = 1;
                        methodWrapper.getMethodNode().maxLocals = 1;

                        System.out.println("String Method Patched.");
                    }

菜鸡一个,有错误请指出,勿喷

image.png

THE END
喜欢就支持以下吧
点赞0
分享
评论 抢沙发
  • 管埋员

    昵称

  • 取消
    昵称