原文作者:Simone Margaritelli
Published on April 18, 2016
原文地址:https://www.evilsocket.net/2016/04/18/how-i-defeated-an-obfuscated-and-anti-tamper-apk-with-some-python-and-a-home-made-smali-emulator/
写在前面
某个周六午后,我和基友Matteo聊天,他向我求助工作中要修复的一些Python脚本的问题。他想给一个apk文件加代码混淆,为了理解混淆和防篡改(稍后详述)的保护,所以我也开始研究这个apk。
这绝对比我平时的APK逆向工程(dex2jar -> jd-gui ->完成)更具挑战性,just so much fun,为了这个需求我写了一个新的工具,我觉得非常酷,独一无二(这不是废话吗?哈哈哈),所以就有了这篇文章。
我在本文故意隐藏了一些细节,因为我不想给写这些应用程序的人造成任何伤害,所有涉及的保护机制目的是为了避免盗版。
混淆代码之混淆
就像其他经常APK反编译的人一样,我习惯了用Proguard来混淆class和method 等(或用Dexguard来混淆字符串等),这个对我来说轻车熟路,但在看到执行完apktool的结果时,我还是吃了一惊(作者内心os:WTF 这都特那么是什么鬼)
大多数的class和methods的属性都是诡异的二进制字符串,所以我之前常用反编译工具完全不能用了,于是第一步就是修改原有的Python脚本(说实话,重构代码从无到有,好心累),Matteo已经在apk里加了重命名以及代码混淆等代码保护,尽管这个脚本本身很简单:
1.循环所有非打印/不可输出名字的smali文件
2.用class xxx 代替混淆的类名称(其中xxx是一个渐进的int)
3.重命名这些文件
4.搜索所有目录的这些类,以他们新的名字作为补丁(俗话说就是FTW!)
5.重复以上的过程,字段指示(class members, methods等)
等上述流程走完后,我终于有了一个可浏览的文件夹以及可读的smali文件
但我肯定远远没有成功……
防篡改
在继续之前,为了让我的缘由更充分,我需要指出两件事的是:
Matteo告诉我一些有特殊的用来保护apk防篡改的技巧以及最有可能反编译的切入点,因此使用一些特殊代码注入到正在重构smali文件得到一个新的apk文件是不可能的,即使不调试也是可以的。
这样做的目的不仅有效的防止代码注入/修改,而且当检测到被篡改时可以卸载应用。
所以在没有代码注入(即使利用Xposed框架也不行)以及在不调试的情况下,是没有机会使用我的方法来逆向它的
字符串加密
像我这样懒得(或者你认为的小聪明的)人,肯定会首先寻找有意义的字符串,尤其是能给我一些关于这个APP的用途,而不是去理解这其中逻辑,但我又讨厌那种突然的惊喜。
每一个字符串都用了一个自定义算法来加密,基本上每一个字符串的引用被替换:
只是一个长数型的整数和另一个整数来作为二次参数(这可能是某种关键点?)
我通常在这种情况下是怎么做的:
用Java的一下反编译工具(dex2jar 与 jd-gui 结合或者单独用jadx),
把反编译好的java源码,并将其粘贴到一个可以 debug java应用程序,
运行反编译之后程序,并最终得到清晰的结果。
你猜怎么着?没有一个工具可以将 Class623::method5的smali代码变换成Java代码,并且输出的全是废代码,一点作用都没有。。。也从侧面反映我不擅长smali代码(程序本身还是相当复杂的,至少对于我这样的smali水平来说)
但是我并不会放弃,一条道走到黑吧
Smali 模拟器
事实上,我可以理所当然用smali代码Class623::method5,创建一个新的Android app,并用apktool工具反编译,构造一个注入的非常规的smali代码,并且插入到新的app中,然后重建并启动app……但是呢:
1、再次声明,我很懒的;
2、这个解决方法并不优雅;
3、还有就是一个新的想法涌上头顶,妈的,太酷了,So,我得弄出来。
那就让我长话短说吧:
妈的,我准备写一个smali的解析器和模拟器,并用代码完善它,最终它将会明文输出我想要的结果
于是我开始阅读Dalvik官方文档(这个还要谢谢另一个好基友Gabor Paller!)几个小时后,我写了这个简单的脚本准备测试:
Aaaaaaand:
BINGO!!!
我对每一个加密的字符串执行该脚本,它工作起来魅力四射,该模拟器能够正确解析并执行反编译的smali代码,以及解密我从反编译后的应用中提取的每一个函数……从这一点上它只是用明文替换密钥,转换过程变得易如反掌。
Conclusions
我像往常一样把本文中的代码发到 github (https://github.com/evilsocket/smali_emulator)上,尽管仍然缺乏大量的Dalvik代码的支持,我仅仅执行了我需要的那部分代码,当然者在本文中显而易见,但这个还是很容易容易改进的,我应该会在未来几天完成吧。
本文始发于微信公众号(inn0team):如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论