Threadtear:一款多功能Java代码反混淆工具套件

栏目: IT技术 · 发布时间: 4年前

内容简介:Threadtear是一款针对Java代码的多功能反混淆工具,该工具即将添加针对Android应用程序的支持。在该工具的帮助下,广大研究人员无需过多担心代码混淆方面的问题,因为Threadtear可以为你的代码分析过程添砖加瓦。即使是ZKM和Stringer之类的混淆工具,对于Threadtear来说也不在话下。为了方便进行代码调试,Threadtear还集成了很多其他的功能,并且还提供了代码行标注以及其他的代码栈追踪功能。值得一提的是,Threadtear还支持逆向分析功能。一次“任务执行”指的是对所有已

Threadtear

Threadtear是一款针对 Java 代码的多功能反混淆工具,该 工具 即将添加针对Android应用程序的支持。在该工具的帮助下,广大研究人员无需过多担心代码混淆方面的问题,因为Threadtear可以为你的代码分析过程添砖加瓦。即使是ZKM和Stringer之类的混淆工具,对于Threadtear来说也不在话下。为了方便进行代码调试,Threadtear还集成了很多其他的功能,并且还提供了代码行标注以及其他的代码栈追踪功能。值得一提的是,Threadtear还支持逆向分析功能。

任务执行

一次“任务执行”指的是对所有已加载的类文件进行执行和修改操作,执行任务有很多种类型,从字节码清理到字符串反混淆,但所有的任务都需要确保文件以正确的顺序加载和执行。一切准备就绪之后,点击“Run”按钮即可按顺序对目标文件进行操作。

安全

Threadtear会使用自己的SecurityManager类来尽可能地帮助研究人员免受恶意调用(任意代码执行)的影响,但无法100%保证安全。尤其是在处理类似ZKM或Stringer这样的混淆目标时,反射是经常会出现的。

如何编译

首先,运行下列命令,然后在builds/libs中会创建一个可运行的jar文件。

gradle build
gradle fatJar

如果你不想下载项目源码的话,你还可以直接使用该项目Release页面提供的最新版本:【 点我获取 】。

工具使用

我们可以直接通过扩展me.nov.threadtear.execution.Execution方法来创建自己的执行任务:

public class MyExecution extends Execution {

public MyExecution() {

super(ExecutionCategory.CLEANING /* category */, "My execution" /* name */,

"Executes something" /* description, can use html */);

}

/**

* This method is invoked when the user clicks on the Run button

* @return true if success, false if failure

*/

@Override

public boolean execute(Map<String, Clazz> classes, boolean verbose) {

classes.values().stream().map(c -> c.node).forEach(c -> {

//transform the classes here using the tree-API of ASM

});

return false;

}

}

在运行时加载 ClassNodes 类,可以直接使用 me.nov.threadtear.asm.vm.VM 类并实现 me.nov.threadtear.asm.vm.IVMReferenceHandler 方法:

public class MyExecution extends Execution implements IVMReferenceHandler {

public MyExecution() {

super(ExecutionCategory.GENERIC, "My execution", "Loads ClassNodes at runtime");

}

@Override

public boolean execute(Map<String, Clazz> classes, boolean verbose) {

classes.values().stream().map(c -> c.node).forEach(c -> {

VM vm = VM.constructVM(this);

//transform bytecode to java.lang.Class

Class<?> loadedClass = vm.loadClass(c.name.replace('/', '.'), true);

//do stuff with your class here

loadedClass.getMethods[0].invoke(...);

return true;

});

}

/**

* Will get invoked by VM, when VM.loadClass is called

*/

@Override

public ClassNode tryClassLoad(String name) {

//try to find the class to be loaded in open jar archive

return classes.containsKey(name) ? classes.get(name).node : null;

}

}

通过使用 me.nov.threadtear.analysis.stack.ConstantTracker 方法,你可以分析目标代码中的方法并追踪非变量栈值:

public class MyExecution extends Execution implements IConstantReferenceHandler {

public MyExecution() {

super(ExecutionCategory.GENERIC, "My execution", "Performs stack analysis and replaces code.");

}

@Override

public boolean execute(Map<String, Clazz> classes, boolean verbose) {

classes.values().stream().map(c -> c.node).forEach(this::analyzeAndRewrite);

return true;

}

public void analyzeAndRewrite(ClassNode cn) {

cn.methods.forEach(m -> {

// this analyzer keeps known stack values, e.g. can be useful for jump prediction

Analyzer<ConstantValue> a = new Analyzer<ConstantValue>(new ConstantTracker(this, Access.isStatic(m.access), m.maxLocals, m.desc, new Object[0]));

try {

a.analyze(cn.name, m);

} catch (AnalyzerException e) {

logger.severe("Failed stack analysis in " + cn.name + "." + m.name + ":" + e.getMessage());

return;

}

Frame<ConstantValue>[] frames = a.getFrames();

InsnList rewrittenCode = new InsnList();

Map<LabelNode, LabelNode> labels = Instructions.cloneLabels(m.instructions);

 

// rewrite method instructions

for (int i = 0; i < m.instructions.size(); i++) {

AbstractInsnNode ain = m.instructions.get(i);

Frame<ConstantValue> frame = frames[i];

// replace / modify instructions, etc...

if (frame.getStackSize() > 0) {

ConstantValue top = frame.getStack(frame.getStackSize() - 1);

if (top.isKnown() && top.isInteger()) {

int knownTopStackValue = top.getInteger();

// use the known stack to remove jumps, simplify code, etc...

// if(...) { rewrittenCode.add(...); }

continue;

}

}

rewrittenCode.add(ain.clone(labels));

}

// update instructions and fix try catch blocks, local variables, etc...

Instructions.updateInstructions(m, labels, rewrittenCode);

});

}

/**

 * Use this method to predict stack values if fields are loaded

 */

@Override

public Object getFieldValueOrNull(BasicValue v, String owner, String name, String desc) {

return null;

}

/**

 * Use this method to predict stack values if methods are invoked on known objects

 */

@Override

public Object getMethodReturnOrNull(BasicValue v, String owner, String name, String desc, List<? extends ConstantValue> values) {

if (name.equals("toCharArray") && owner.equals("java/lang/String")) {

if (!values.get(0).isKnown()) {

// invocation target is not known, we can't compute the return

return null;

}

return ((String) values.get(0).getValue()).toCharArray();

}

return null;

}

}

反混淆顺序

最佳的反混淆处理顺序如下:

通用执行->访问反混淆代码->字符串反混淆->清理执行痕迹

工具运行截图

Threadtear:一款多功能Java代码反混淆工具套件

Threadtear:一款多功能Java代码反混淆工具套件

Threadtear:一款多功能Java代码反混淆工具套件

Threadtear:一款多功能Java代码反混淆工具套件

Threadtear:一款多功能Java代码反混淆工具套件


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

嵌入式Linux应用开发完全手册

嵌入式Linux应用开发完全手册

韦东山 主编 / 人民邮电出版社 / 2008-8 / 69.00元

本书全部实例代码及相关工具。 基于ARM 9+Linux 206平台,从基础讲起,引导读者快速入门,实例丰富,可直接应用于工程实践。 本书全面介绍了嵌入式Linux系统开发过程中,从底层系统支持到上层GUI应用的方方面面,内容涵盖Linux操作系统的安装及相关工具的使用、配置,嵌入式编程所需要的基础知识(交叉编译工具的选项设置、Makefile语法、ARM汇编指令等),硬件部件的使用及......一起来看看 《嵌入式Linux应用开发完全手册》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具