本文转载自: https://www.zybuluo.com/oro-oro/note/143651
0. 序Jeb 本身是支持变量重命名的,所以,混淆了的变量名、类名可以修改。
实际上,它还可以做到这种效果 Decompiled Java Code Manipulation using JEB API – Part 2: Decrypting Strings。
例子中的脚本在这:ASTDecryptStrings.py。
整体的逻辑:
1. 破解解密算法。
2. 遍历类里面的所有方法
3. 如果方法为解密方法,则提取所有的参数出来,给解密方法。
4. 计算出解密的字符串,最终用replaceSubElement替换掉整个函数调用。
而这些都需要去了解 jeb.api.ast。
1. AST 整体结构简介
AST是Abstract Syntax Tree的简称,也就是抽象语法树,这是用来解析源码的。
源代码有各种各样的结构和语句,譬如类、方法、变量、表达式、常量、For语句、Break语句等等。
这些东西AST都会有对应的类一一对应。
整个jeb.api.ast整体结构如下:
所有的类都直接或间接实现了 IElement。
它有2个重要的方法:
getSubElements() 获取该元素的子元素列表。
replaceSubElement(IElement old_elt, IElement new_elt) 用另外一个元素替换一个元素。
2. NonStateMent 部分
2.1 Class, Method, Field
Class:表示一个Java类。类则包含了内部类、方法(Method)、变量(Field)等。
Method:表示一个Java方法。可以用JebInstance.getDecompiledMethodTree来获得一个方法,可以通过Method.Builder创建方法。
Field:表示一个Java变量。可以通过Field.Builder创建变量。
这3类元素都是只读元素,而不是表达式(Expression),跟其他类是有区别的。
import jeb.api.IScript; import jeb.api.JebInstance; import jeb.api.ast.Field; import jeb.api.ast.Method; import jeb.api.dex.Dex; import java.util.List; public class TestASTClass implements IScript { @Override public void run(JebInstance jebInstance) { Dex dex = jebInstance.getDex(); List<String> classSignatures = dex.getClassSignatures(true); for (String classSignature : classSignatures) { if (!classSignature.contains("MainActivity")) { continue; } jebInstance.print(classSignature); jeb.api.ast.Class decompiledClassTree = jebInstance.getDecompiledClassTree(classSignature); if (decompiledClassTree == null) { continue; } jebInstance.print("\nField : "); List<Field> fields = decompiledClassTree.getFields(); for (Field field : fields) { jebInstance.print(field.getSignature()); } jebInstance.print("\nMethod : "); List<Method> methods = decompiledClassTree.getMethods(); for (Method method : methods) { jebInstance.print(method.getSignature()); } jebInstance.print("\nInnerClass : "); List<jeb.api.ast.Class> innerClasses = decompiledClassTree.getInnerClasses(); for (jeb.api.ast.Class cls : innerClasses) { jebInstance.print(cls.getType()); } String type = decompiledClassTree.getType(); jebInstance.print("\nType : " + type); } } }
2.2 ArrayElt, Identifier, InstanceField, StaticFieldArrayElt : 表示一个数组的元素,如array[index]。
Identifier:表示一个Java标识符或变量。
InstanceField:表示非静态变量,这是一个左值表达式,不要跟jeb.api.ast.Field混淆。
StaticField:表示静态变量,不要跟jeb.api.ast.Field混淆。
这3个都实现了ILeftExpression。
下面代码是有问题的,Field不是表达式,因为变量可能用在任何地方,而具体使用的地方,才是表达式。
if (field instanceof InstanceField) { }
2.3 ConditionalExpression, Constant, Expression, TypeReferenceConditionalExpression:表示条件表达式,如a ? b : c。
Constant:表示一个常量值,类型支持8个主要类型 (boolean, byte, char, short, int, long, float, double) 和字符串。
通过Constant.Builder.可创建一个Constant。