dex2jar源码解析----dex转smail

本文以BaksmaliTest为例,详细解析Dex转Smali的流程。首先通过DexFileReader读取dex文件,接着调用Baksmali的to方法,不经过IR格式转换和优化步骤。在解析完成后,使用BaksmaliDumpOut将dex转换为smali文件。在处理过程中,涉及DexCodeNode的accept方法,处理特殊跳转和标签指令,计算参数占用的寄存器数,并通过BaksmaliCodeDumper输出Smali代码。
摘要由CSDN通过智能技术生成

我们以BaksmaliTest为例,查看一下Dex转smail的流程

public class BaksmaliTest {


    @Test
    public void t() throws Exception {
        File dir = new File("../dex-translator/src/test/resources/dexes");
        File[] fs = dir.listFiles();
        if (fs != null) {
            for (File f : fs) {
                if (f.getName().endsWith(".dex") || f.getName().endsWith(".apk")) {
                    dotest(f.toPath());
                }
            }
        }
    }

    private void dotest(Path f) throws Exception {
        Path smali0 = new File("target/" + f.getFileName() + "-smali0.zip").toPath();
        try (FileSystem fs0 = BaseCmd.createZip(smali0)) {
            Baksmali.from(f).to(fs0.getPath("/"));
        }
        Path smali1 = new File("target/" + f.getFileName() + "-smali1.zip").toPath();
        try (FileSystem fs0 = BaseCmd.openZip(smali0); FileSystem fs1 = BaseCmd.createZip(smali1)) {
            BaksmaliDumper baksmaliDumper = new BaksmaliDumper();
            BaksmaliDexFileVisitor v = new BaksmaliDexFileVisitor(fs1.getPath("/"), baksmaliDumper);
            Smali.smali(fs0.getPath("/"), v);
        }
    }

测试函数t调用doTest进行dex到smail的转换

t函数查找/dex-translator/src/test/resources/dexes目录下的dex文件,调用dotest方法,这里我们在这个目录下面放了前面生成的dex文件

首先调用

Baksmali.from(f).to(fs0.getPath("/"));
    public static Baksmali from(Path in) throws IOException {
        return from(ZipUtil.readDex(in));
    }
  public static byte[] readDex(Path file) throws IOException {
        return readDex(Files.readAllBytes(file));
    }
  public static Baksmali from(byte[] in) throws IOException {
        return from(new DexFileReader(in));
    }
  public static Baksmali from(DexFileReader reader) {
        return new Baksmali(reader);
    }

from这里构建了一个DexFileReader并以它为参数构建了一个Baksmali

然后调用Baksmail的to函数

   public void to(final Path base) {
        final BaksmaliDumper bs = new BaksmaliDumper(parameterRegisters, useLocals);
        reader.accept(new BaksmaliDexFileVisitor(base, bs), this.noDebug ? DexFileReader.SKIP_CODE : 0);
    }
新建一个BaksmaliDumper,以它为参数构建一个BaksmaliDexFileVisitor,在以它为参数调用reader.accept

这里就到了前面的DexFileReader的accept,跟我们前面分析的一样,只是传给他的DexFileVisitor不一样

   public void accept(DexFileVisitor dv, int config) {//使用指定的访问者访问dex文件
        for (int cid = 0; cid < class_defs_size; cid++) {//总共有多少个类
            accept(dv, cid, config);
        }
        dv.visitEnd();
    }

accept里面主要调用DexFileVisitor的visitor,它会返回一个DexClassVisitor,然后调用acceptClass,并使用前面的DexClassVisitor为参数

public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {
        return new DexClassNode(access_flags, className, superClass, interfaceNames) {

            @Override
            public void visitEnd() {
                super.visitEnd();

                Path smaliFile = dir
                        .resolve(rebuildFileName(className.subst
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值