[转载] 4. JebAPI 之 jeb.api.ui

时间:2023-12-15 19:34:50

本文转载自: https://www.zybuluo.com/oro-oro/note/145250

JebInstance可以通过getUI()方法来获得jeb.api.ui.JebUI

JebUI 下面有很多View,如AssemblyView, JavaView等等。

JebUI可以通过getView(View.Type viewtype)方法获得对应的View。 
具体类型在jeb.api.ui.View.Type中:

类型 说明
ASSEMBLY 反汇编界面
CLASS_HIERARCHY 类层级界面(左)
CONSOLE 控制台(下)
JAVA Java代码界面
MANIFEST 清单界面
NOTES 全局评论界面

在第3章解密的基础上,让JavaView界面自动刷新,显示解密字符串:

import jeb.api.IScript;
import jeb.api.JebInstance;
import jeb.api.ast.*;
import jeb.api.dex.Dex;
import jeb.api.dex.DexMethod;
import jeb.api.ui.JavaView;
import jeb.api.ui.JebUI;
import jeb.api.ui.View;
import java.util.ArrayList;
import java.util.List;
public class TestASTDecode implements IScript {
    public static final byte[] bytes = new byte[]{'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!'};
    @Override
    public void run(JebInstance jebInstance) {
        JebUI ui = jebInstance.getUI();
        JavaView javaView = (JavaView) ui.getView(View.Type.JAVA);
        Dex dex = jebInstance.getDex();
        List<String> classSignatures = dex.getClassSignatures(true);
        Constant.Builder cstBuilder = new Constant.Builder(jebInstance);
        // 获得decode方法的sig
        int methodCount = dex.getMethodCount();
        String decodeMtdSig;
        for (int i = 0; i < methodCount; i++) {
            DexMethod dexMethod = dex.getMethod(i);
            int index = dexMethod.getIndex();
            decodeMtdSig = dex.getMethod(i).getSignature(true);
            if (decodeMtdSig.contains("Lcom/test/helloworld/MainActivity;->decode")) {
                // 找出所有使用了该方法的地方
                List<Integer> methodReferences = dex.getMethodReferences(index);
                for (Integer refIdx : methodReferences) {
                    DexMethod refDexMethod = dex.getMethod(refIdx);
                    // 找到AST中对应的Method
                    Method decompiledMethodTree = jebInstance.getDecompiledMethodTree(refDexMethod.getSignature(true));
                    // 拿到语句块,遍历所有语句
                    Block block = decompiledMethodTree.getBody();
                    int size = block.size();
                    for (int j = 0; j < size; j++) {
                        Statement statement = block.get(j);
                        jebInstance.print(statement.toString());
                        if (statement instanceof Call) {
                            Call call = (Call) statement;
                            Method method = call.getMethod();
                            jebInstance.print("Call : " + method.getSignature());
                            List<IElement> subElements = call.getSubElements();
                            for (IElement element : subElements) {
                                jebInstance.print("Sub Element : " + element.toString());
                                if (element instanceof Call) {
                                    Call c = (Call) element;
                                    Method m = c.getMethod();
                                    if (m.getSignature().equals(decodeMtdSig)) {
                                        jebInstance.print(">>> " + decodeMtdSig);
                                        List<IExpression> arguments = c.getArguments();
                                        ArrayList<Integer> arrayList = new ArrayList<Integer>();
                                        for (IExpression expression : arguments) {
                                            if (expression instanceof Constant) {
                                                arrayList.add(((Constant) expression).getInt());
                                            }
                                        }
                                        String str = decode(arrayList.get(0), arrayList.get(1));
                                        jebInstance.print("解密后的字符串 : " + str);
                                        // 将当前语句Call的子元素,替换为解密后的字符串
                                        call.replaceSubElement(element, cstBuilder.buildString(str));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        javaView.refresh();
    }
    String decode(int a, int b) {
        byte[] ab = new byte[]{bytes[a], bytes[b]};
        return new String(ab);
    }
}