我想转换/检测 Dex 文件。转换的目标包括测量代码覆盖率。请注意,源文件不可用。所以检测 Dex 是唯一的选择。
我想知道是否有任何现有的代码库可以作为示例来编写工具来实现我的目标。
我知道 Smali 项目和许多其他基于 Smali 的项目。但是,这些项目都不是我的目的的好例子。
我正在寻找自动转换 smali 代码或 dexlib 表示的代码,从中生成 smali。出于我的目的,后一个选项是首选,因为可以避免生成 smali 的开销。
代码很多,但是 dx 的DexMerger是一个转换 dex 文件的示例程序。由于它需要猜测输出的大小才能使前向引用起作用,这使得它变得相当复杂。
您还需要创建基础架构来重写 dalvik 指令。DexMerger 的InstructionTransformer进行了浅层重写:它调整从一个映射到另一个映射的偏移量。要衡量代码覆盖率,您的指令重写可能需要更加复杂。
最近可用的另一个选项是Dexpler。它是 Soot 的扩展,Soot 是一个用于分析和检测 Java 程序的框架。Dexpler 读取 .apk 文件并转换为 Jimple 中间格式。然后可以任意检测 Jimple 代码,并最终将其转储到新的 apk 中。
(为了记录,我在这里回答我自己的问题)
最终我没有找到任何适合我要求的工具。所以我最终基于 DexLib构建了自己的工具,称为Ella 。开箱即用,它做了一些事情,例如测量代码覆盖率、记录方法跟踪等。但它可以很容易地扩展来进行其他类型的转换。
在某些情况下,smali 本身在重新组装 dex 文件时会进行少量的指令重写。如果目标超出范围,则用 const-string/jumbo 替换 const-string 或用“更大”指令替换 goto 指令之类的事情。这涉及用可能更大的指令替换指令列表中的指令,并相应地修复偏移量。
CodeItem.fixInstructions是负责此的方法。
此外,还有asmdex 库。我对它不是很熟悉,但听起来它可能与你想做的事情有关。
我知道这有点晚了,但以防万一您仍然感兴趣,或者可能对其他一些读者感兴趣。ASMDEX 已经提到过。我认为这是你目前最好的选择,因为你正在努力实现。
至于添加新寄存器,请查看 org.ow2.asmdex.util.RegisterShiftMethodAdapter 类。这并不完美!事实上,在添加寄存器时更改现有的 4 位指令是很可怕的,这意味着某些寄存器最终会变成 0xF 并且不适合 4 位。
但这应该是一个好的开始。