Android中的垃圾字节注入

时间:2015-10-13 18:57:48

标签: android obfuscation bytecode dalvik

在阅读有关Android中代码混淆的this有趣文章后,我正在尝试将其用于研究目的,但在将该技术应用到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
...

为了给你一些上下文,我想在0x6f8(“const / 4 v2,0”=> 12 02)的v2寄存器中清除一些像0值这样的赋值,这将在GUI中显示这个方法的结尾(在0x746及以上);并使用这种混淆技术,“隐藏”v2寄存器的修改,将值1设置到0x716的v2寄存器中(“const / 4 v2,1”=> 12 12)。 如果你遵循0x704处的代码,那么分支就完成了0x716,其中“const / 4 v2,1”是在fill-data-array-payload内部。

我遇到的问题是当我运行代码时崩溃(我已经尝试过从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”跳转,因为偏移指向(我尝试过其他分支指令,但结果是相同的)。代码工作的唯一方法是,如果我指向fill-array-data-payload之外的偏移量,但是没有应用混淆技术:P。

任何人都尝试过类似这种技术的东西,或者反对这种分支验证拒绝?

2 个答案:

答案 0 :(得分:1)

由于dalvik存在问题,这种“混淆”技术起作用。这个问题在4.3时间框架附近被修复了,虽然我不确定包含该修复程序的第一个发布版本。棒棒糖使用ART,从来没有这个问题。

以下是解决此问题的更改:https://android-review.googlesource.com/#/c/57985/

答案 1 :(得分:1)

这不会起作用。字节码验证器explicitly checks所有分支都是有效的。地址是指令还是数据的问题由linear walk通过该方法确定。数据块本质上是非常大的指令,因此它们可以逐步完成。

如果您修改.odex输出,并设置"预先验证的"您可以使其工作。在课程上标记,以便验证者不会再次检查它 - 但你不能以这种方式分发APK。