Tencent / tinker

Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstall apk.
Other
17.15k stars 3.34k forks source link

使用DexPatchGenerator将2个dex做diff算法,然后将pacth与oldDex做合成时,发现合成后的dex和原来新dex的md5不一样,请问下是什么原因呢 #1573

Open super-h-c opened 3 years ago

super-h-c commented 3 years ago

异常类型:patch合成后的dex与源newDex的md5不一样,

手机型号:无,电脑端测试

tinker版本:1.7.7

堆栈/日志: File oldDex = new File("Hello.dex");

    File newDex = new File("Hello1.dex");

    File patch =  new File("Hello.patch");

    File newpatchDex = new File("newHello.dex");

    try {
        DexPatchGenerator dexPatchGenerator = new DexPatchGenerator(oldDex, newDex);
        dexPatchGenerator.executeAndSaveTo(patch);
        System.out.println("diff success " + patch.getPath() + "," + patch.length());
    } catch (IOException e) {
        e.printStackTrace();
    }

    DexPatchApplier dexPatchApplier = new DexPatchApplier(oldDex, patch);
    dexPatchApplier.executeAndSaveTo(newpatchDex);
    System.out.println("apply success " + newpatchDex.getPath() + "," + md5(newpatchDex).equals(md5(newDex)));

对比2个dex,发现部分差异,2个dex的map_list偏移量不一样 image image

MapListOffset赋值的地方,为什么不直接是newDex的mapOffset呢? this.patchedMapListOffset = this.patchedEncodedArrayItemsOffset

tys282000 commented 3 years ago

这是预期之内的。因为 dexdiff 为了减小 patch 信息的大小,同时节省在手机上还原新dex的内存开销,在diff的时候是没有按二进制一致来做差分的。按 dexdiff 的差分信息合成出来的新 dex 只在逻辑上和原 dex 保持一致,二进制内容大概率是不同的。

比方说两个 Codes 信息在新旧两个 Dex 里分别位于 offset 100 和 200 的位置,那旧 Dex 里用 offset 100 引用它和新 Dex 里用 offset 200 引用它在逻辑上就是一样的,但两个dex的二进制内容就会因为 100 变成 200 而产生变化。

super-h-c commented 3 years ago

这是预期之内的。因为 dexdiff 为了减小 patch 信息的大小,同时节省在手机上还原新dex的内存开销,在diff的时候是没有按二进制一致来做差分的。按 dexdiff 的差分信息合成出来的新 dex 只在逻辑上和原 dex 保持一致,二进制内容大概率是不同的。

比方说两个 Codes 信息在新旧两个 Dex 里分别位于 offset 100 和 200 的位置,那旧 Dex 里用 offset 100 引用它和新 Dex 里用 offset 200 引用它在逻辑上就是一样的,但两个dex的二进制内容就会因为 100 变成 200 而产生变化。

好的,感谢感谢,那如果需要保证二进制一致的话,在这个差分算法的基础上 有办法吗?