[转载] 3. JebAPI 之 jeb.api.ast

时间:2021-11-19 01:38:19

本文转载自: 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, StaticField

ArrayElt : 表示一个数组的元素,如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, TypeReference

ConditionalExpression:表示条件表达式,如a ? b : c。

Constant:表示一个常量值,类型支持8个主要类型 (boolean, byte, char, short, int, long, float, double) 和字符串。 
通过Constant.Builder.可创建一个Constant。