有过android应用反编译或者再打包的朋友都有使用过apktool的经验,apktool能将dex文件的
字节码转换为smali代码,这个工具是怎么做到对dex进行解析并生成smali代码的呢?这就需要对
dex文件的格式很熟悉、需要掌握dalvik指令的字节码格式,并能翻译成对应的smali代码。
我准备写一系列的文章来分析dex文件的格式、dalvik字节码的格式、以及dex to smali的方法,
基于此可以做很多的应用,比如安全扫描、应用加固等等!
Dalvik指令介绍请参考官方文档:General design 如果读者对X86或者ARM指令集有一定的了解,
学习Dalvik指令还是很容易的。如果您掌握了Dalvik指令集,就能将dex文件转换为smali代码,这也
是很多android安全研发人员的基本功。
下面以一个例子开始来讲解Dalvik指令集:
实例1:将如下davik字节码翻译为smali代码,从高字节到低字节为:00 02 2C 69 10 70
翻译步骤:(用程序语言描述)
step1: 将00 02 2C 69 10 70赋值给变量instr
step2: 低8bits为opcode,即OP = instr & 0xff 得到 0x70,对应的指令为invoke-direct,查询官方文档
可知0x70指令对应的指令格式为35c,即长度为6个字节,最多有5个寄存器,如下图:
70 | invoke-direct { parameters }, methodtocall | Invokes a method with parameters without the virtual method resolution. | 7010 0800 0100 - invoke-direct {v1}, java.lang.Object.<init>:()V // method@0008 Invokes the 8th method in the method table with just one parameter, v1 is the "this" instance5. |
format为35c的指令:长度为6bytes( 3*2) 5代表寄存器数量 c代表const pool index
35c格式的指令:
A|G|opBBBB F|E|D|C | 35c | [A=5 ] op {vC, vD, vE, vF, vG}, meth@BBBB[ A=5 ] op {vC, vD, vE, vF, vG}, type@BBBB[ A=4 ] op {vC, vD, vE, vF},kind @BBBB[ A=3 ] op {vC, vD, vE}, kind @BBBB[ A=2 ] op {vC, vD}, kind @BBBB[ A=1 ] op {vC}, kind @BBBB[ A=0 ] op {}, kind @BBBBThe unusual choice in lettering here reflects a desire to make the count and the reference index have the same label as in format 3rc. |
即op=70,op的高8位为A|G,所以左右12位就可以得到A的值,因为这是小端字节序,所以A|G|op被存放在低地址
A: argument word count,寄存器的个数(4bits)
B: method reference index (16bits)
C..G: argument registers (4bits each=20bits)
step3: 获取A G位的值,G = (instr >> 8) & 0xf = 0, A = (instr >> 12) & 0xf = 1,即A等于1,对应的指令格式为:
[A=1
] op
{vC}, kind
@BBBB
step4: 获取C和BBBB的值:C = (instr >> 32) & 0xf = 2,所以寄存器为v2,BBBB = (instr >> 16) & 0xffff = 0x2C69 = 11369
BBBB即为method index,以11369作为下标,查询method表获得该方法对应的描述如下:
struct method_id_item method_id[11369]
void java.lang.Object.<init>() 33A04h 8h Fg: Bg:0x008080 Method ID</span>
所以上述16进制代码对应的dalvik指令为:
invoke-direct v2, Ljava/lang/Object;-><init>()V</span>
小结: 35C格式的指令是dalvik指令集里比较复杂的一种指令,读者可以对照上述步骤,再仔细分一下转换过程,
如果能将35C格式的指令分析明白了,再分析别的指令也不是难事。
参考网址:
1. https://source.android.com/devices/tech/dalvik/dalvik-bytecode.html
2. https://source.android.com/devices/tech/dalvik/instruction-formats.html