Android中的垃圾字节注入

Android中的垃圾字节注入,android,obfuscation,bytecode,dalvik,Android,Obfuscation,Bytecode,Dalvik,在读了一篇关于Android中代码混淆的有趣文章之后,我试图做这件事是为了研究目的,但是在将这项技术应用到classes.dex文件中之后,我遇到了崩溃 接下来是我在应用该技术后尝试运行的代码: 0006e8: |[0006e8] com.example.root.bji.MainActivity.paintGUI:()V 0006f8: 1202 |

在读了一篇关于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
...
为了给您提供一些上下文,我想清除一些赋值,例如0x6f8处v2寄存器中的0值(“const/4 v2,0”=>12 02),这将在该方法末尾的GUI中显示(0x746及更高);并使用这种模糊处理技术,在0x716(“const/4 v2,1”=>12”)处将v2寄存器的值设置为1的修改“隐藏”到v2寄存器中。 如果遵循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”跳转,因为偏移量是指向的(我尝试过其他分支指令,但结果是相同的)。代码工作的唯一方式是,如果我指向fill数组数据有效负载之外的偏移量,但是没有应用模糊处理技术:P

有人尝试过类似于此技术的方法,或者反对此分支验证拒绝吗?

由于dalvik中的一个问题,此“模糊”技术起了作用。这个问题在4.3时间框架内的某个地方得到了修复,尽管我不确定包含该修复的第一个发布版本。棒棒糖使用的是艺术,从来没有这个问题


以下是修复此问题的更改:

这是不可能的。字节码验证器检查所有分支的有效性。地址是否是指令或数据的问题由通过该方法的方法确定。数据块本质上是非常大的指令,因此它们会被跨过


如果您修改.odex输出,并在类上设置“pre-verified”标志,这样验证器就不会再次检查它,那么您就可以做到这一点——但您不能以这种方式分发APK。

您所指的提交似乎是关于无效访问标志的,这与问题中描述的技术无关。请确保它确实如此。dalvik验证器将拒绝任何试图使用此技术的类。如果你看一下他们的示例应用程序,为了避免这个问题,dexlabs的家伙在应用程序的dex文件中修改的类上设置了CLASS_isprevided标志,这可以防止dalvik验证器验证和拒绝该类。我提交的更改是专门为了防止这种混淆技术。@JesusFreke那么它现在已经修复了吗?或者垃圾字节(或者像DIVILAR这样的其他保护方法)今天仍然可以使用吗?例如,我知道谷歌并没有使用ART在较新的Android版本(参见2014年的谷歌IO视频)上编译所有代码。如果还有任何可能性,那将很有趣。谢谢fadden和JesusFreke。在类中更改pre-verify标志后,它就像4.1虚拟设备上的符咒一样工作!。