这个周末我和好友聊天时,他向我求助修改一个他正在编写Python脚本。他试图通过解混淆一个APK,来理解该APK的混淆基址和防篡改保护机制。同我以往的APK逆向过程(dex2jar->jd-gui->done)相比,这是一个很有挑战性同时充满趣味的工作。同时,这个逆向过程我编写了一个我认为比较酷比较独特的工具。
怪异的字符串
同其他有过APK反编译工作经验的逆向工作者一样,我已经很习惯程序中的类和名字被ProGuard混淆(或者被DexGuard混淆字符串等),这对我来说不是什么困难。但是当我使用apktool打开这个应用的时候还是大吃一惊:
大部分的类和方法名都是很怪异的字符串,这几乎没法让我使用一个单独的工具或者编辑器来查看这些文件。所以目前最首要的步骤就是修复(坦诚的说应该是从头开始写)Matteo写的python脚本,这个脚本试图重新命名所有的混淆入口,脚本本身工作流程比较简单:
遍历所有名称为不能打印字符的smali文件
使用ClassXXX替代混淆的类名字(XXX是一个自增的数字)
重命名文件
查找所有引用这些类的地方并使用新的名称替代(正则匹配)
在.field文件夹(类变量,方法等)中重复这个操作
这个过程结束之后,最终获得了一个可以浏览的文件夹和可读的smali文件:
但是这离完成还有很远的距离。
反篡改
在我继续进行之前,我先需要指出两点,以便你能够理解我这么做背后的理由:
1. 这个应用使用了很奇怪的反篡改(很大可能是反调试之类的措施)保护,因此,使用注入代码的方式将smali代码重新打包成APK是不可行的,同样调试也是不行的
2. 这样的保护措施不仅阻止了代码注入/修改,同时也会在检测到这种篡改后卸载软件
所以代码注入(XPosed也不行)、调试都无法使用,基本我通常的标准逆向方式都无法使用。
加密字符串
作为一个懒惰(或者说是聪明)的逆向者,我不想先去理解其中的逻辑,相反,我试图发现那些能够给我一些提示的、有意义的字符串,帮助我发现这个app在做些什么,但是我再次被震惊到了。
所有的字符串都进过了传统的加密算法加密,基本上所有引用字符串的地方都被如下的方式进行了替换:
Stringdecrypted = Class623 :: method5 (new int []{-12, 44,-35,…}, 52);
函数的参数仅仅是一个整形数组和其他的一些数字作为第二个参数(或许是某种形式的密钥?)
通常我遇到这种情况的做法是:
1. 反编译APK到Java(使用dex2jar+jd-gui或者仅仅是jadx)
2. 获取到解密的java代码,并将其粘贴到一个独立的java控制台
3. 对加密的东西执行解密例程从而获得明文结果
然而。。。任何工具都无法正确的将Class623::method5 的smali代码转换成
java代码,这些工具获得的输出都是无意义的东西,不起作用。但是目前我并不是很擅长阅读smali代码(这个解密程序本身也十分复杂,至少对我来说很复杂)…但是我不能就这么放弃。
所有的都让Smali模拟器来搞定吧
我当然可以利用Class623::method5的smali代码,创建一个新的安卓APP,然后使用apktool反编译,在这个方法的输出中注入代码,插入一个调用该函数代码的调用到app中,重新构建这个app并且运行它。但是:
1. 同样,我是一个懒惰的人
2. 这个实现方式并不优雅
3. 我头脑里闪现出一个很酷的想法,我必须尝试一下!
长话短说,我要做的是:“写一个smali解析器和模拟器,然后加载这个函数例程,最终它将输出所有我需要的明文!”。
于是我开始阅读Dalvik操作码说明,整合了一些代码,经过几个小时,我完成了这个简单的pyhon 脚本用于测试:
from smali . emulator import Emulator
emu = Emulator ()
# The smali file to emulate.
filename ='decryptor.smali'
# Arguments for the method.
args ={
'p0':(-62,-99,-106,-125,-123,-105,-98,-37,-105,-97,-103,-41,-118,-97,-113,-103,-109,-104,-115,111,98,103,35,52),
'p1':19
}
ret = emu . run ( filename , args )
print emu . stats
print"RESULT:/n"
print"'%s'"% ret
而且,运行结果如下:
成功了!
我对所有的加密字符串执行该脚本,模拟器也能正确的解析和执行解密例程的smali代码,并解密所有我从反编译程序中抽取的每一个条目。从现在开始,所有的工作就是使用明文替换所有的加密条目,从而这个逆向过程易如反掌。