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代码反混淆工具套件


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

查看所有标签

猜你喜欢:

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

构建之法(第三版)

构建之法(第三版)

邹欣 / 人民邮电出版社 / 2017-6 / 69.00元

软件工程牵涉的范围很广, 同时也是一般院校的同学反映比较空洞乏味的课程。 但是,软件工程 的技术对于投身 IT 产业的学生来说是非常重要的。作者有在世界一流软件企业 20 年的一线软件开 发经验,他在数所高校进行了多年的软件工程教学实践,总结出了在 16 周的时间内让同学们通过 “做 中学 (Learning By Doing)” 掌握实用的软件工程技术的教学计划,并得到高校师生的积极反馈。在此 ......一起来看看 《构建之法(第三版)》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器