【发布时间】:2016-01-11 16:02:32
【问题描述】:
在阅读了this关于 Android 中代码混淆的有趣文章后,我试图将其用于研究目的,但在将该技术应用到 classes.dex 文件后,我遇到了崩溃。
接下来是我在应用该技术后尝试运行的代码:
0006e8: |[0006e8] com.example.root.bji.MainActivity.paintGUI:()V
0006f8: 1202 |0000: const/4 v2, #int 0 // #0
0006fa: 1a01 0000 |0001: const-string v1, "" // string@0000
0006fe: 1200 |0003: const/4 v0, #int 0 // #0
000700: 1303 1400 |0004: const/16 v3, #int 20 // #14
000704: 3244 0900 |0006: if-eq v4, v4, 000f // +0009
000708: 2600 0300 0000 |0008: fill-array-data v0, 0000000b // +00000003
00070e: 0003 0100 1600 0000 1212 0000 0000 ... |000b: array-data (15 units)
00072c: 0000 |001a: nop // spacer
00072e: 0000 |001b: nop // spacer
... more NOPs ...
000742: 0000 |0025: nop // spacer
000744: 0000 |0026: nop // spacer
000746: 1503 087f |0027: const/high16 v3, #int 2131230720 // #7f08
...
为了给你一些背景信息,我想清楚一些赋值,比如 0 值到 v2 寄存器的 0x6f8 ("const/4 v2, 0" => 12 02),这将在 GUI 中显示此方法结束(在 0x746 及以后);并使用这种混淆技术,“隐藏”对 v2 寄存器的修改,将值 1 设置为 0x716 处的 v2 寄存器(“const/4 v2, 1” => 12 12)。 如果您遵循 0x704 处的代码,则分支完成到 0x716,“const/4 v2, 1”位于填充数据阵列有效负载内。
而我面临的问题是我在运行代码时发生了崩溃(我从 4.3 到 5.1 都试过了),而当崩溃发生时 logcat 告诉我的是:
W/dalvikvm(13874): VFY: invalid branch target 9 (-> 0xf) at 0x6
W/dalvikvm(13874): VFY: rejected Lcom/example/root/bji/MainActivity;.paintGUI ()V
W/dalvikvm(13874): VFY: rejecting opcode 0x32 at 0x0006
W/dalvikvm(13874): VFY: rejected Lcom/example/root/bji/MainActivity;.paintGUI ()V
W/dalvikvm(13874): Verifier rejected class Lcom/example/root/bji/MainActivity;
W/dalvikvm(13874): Class init failed in newInstance call (Lcom/example/root/bji/MainActivity;)
D/AndroidRuntime(13874): Shutting down VM
根据我在日志中的理解,操作系统拒绝“if-eq”跳转,因为偏移量指向(我尝试了其他分支指令,但结果相同)。代码工作的唯一方法是如果我指向填充数组数据有效负载之外的偏移量,但是没有应用混淆技术:P.
有没有人尝试过类似这种技术的东西或者反对这种分支验证拒绝?
【问题讨论】:
标签: android obfuscation bytecode dalvik