https://blog.csdn.net/Kaitiren/article/details/83182108
主要思路来自于这里,这里会利用ASM提供一种更为简单的逆向方法,
对于大佬们那些爆破,对我来说就太难了,静态破解是最简单的方法了。
我们找到那篇文章找到的一个入口点,然后根据他的思路进行修改。
(没想到这种商业软件能会出现如此简单的验证)
修改后:
之后我们编译导出:
替换运行测试:
成功了,这个方法是可行的。
接下来我们开始实现自动化破解,使用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());
}
});
由此可知,目标类拥有26个方法,70个Field,Access为49
由此写出匹配:
[Java] 纯文本查看 复制代码 private static boolean isTargetClass(ClassWrapper cw){
return cw.getMethods().size() == 26 && cw.getFields().size() == 70 && cw.getAccessFlags() == 49;
}
接下来我们需要定位那两个目标方法,并进行修改。
首先我们需要把boolean类型的那个方法进行匹配+修改:
到整个类找了一下发现就只有这一个是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.");
}
菜鸡一个,有错误请指出,勿喷
|