如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk

  • A+
所属分类:移动安全

原文作者:Simone Margaritelli

原文地址: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 这都特那么是什么鬼)

如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk
如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk

    大多数的class和methods的属性都是诡异的二进制字符串,所以我之前常用反编译工具完全不能用了,于是第一步就是修改原有的Python脚本(说实话,重构代码从无到有,好心累),Matteo已经在apk里加了重命名以及代码混淆等代码保护,尽管这个脚本本身很简单:

1.循环所有非打印/不可输出名字的smali文件

2.用class xxx 代替混淆的类名称(其中xxx是一个渐进的int)

3.重命名这些文件

4.搜索所有目录的这些类,以他们新的名字作为补丁(俗话说就是FTW!)

5.重复以上的过程,字段指示(class members, methods等)

等上述流程走完后,我终于有了一个可浏览的文件夹以及可读的smali文件

如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk

如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk
但我肯定远远没有成功……


防篡改


在继续之前,为了让我的缘由更充分,我需要指出两件事的是:

  1. Matteo告诉我一些有特殊的用来保护apk防篡改的技巧以及最有可能反编译的切入点,因此使用一些特殊代码注入到正在重构smali文件得到一个新的apk文件是不可能的,即使不调试也是可以的。

  2. 这样做的目的不仅有效的防止代码注入/修改,而且当检测到被篡改时可以卸载应用。

所以在没有代码注入(即使利用Xposed框架也不行)以及在不调试的情况下,是没有机会使用我的方法来逆向它的

如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk

字符串加密

   

   像我这样懒得(或者你认为的小聪明的)人,肯定会首先寻找有意义的字符串,尤其是能给我一些关于这个APP的用途,而不是去理解这其中逻辑,但我又讨厌那种突然的惊喜。

   每一个字符串都用了一个自定义算法来加密,基本上每一个字符串的引用被替换:

如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk
只是一个长数型的整数和另一个整数来作为二次参数(这可能是某种关键点?)

我通常在这种情况下是怎么做的:

  1. 用Java的一下反编译工具(dex2jar 与 jd-gui 结合或者单独用jadx),

  2. 把反编译好的java源码,并将其粘贴到一个可以 debug java应用程序,

  3. 运行反编译之后程序,并最终得到清晰的结果。

你猜怎么着?没有一个工具可以将 Class623::method5的smali代码变换成Java代码,并且输出的全是废代码,一点作用都没有。。。也从侧面反映我不擅长smali代码(程序本身还是相当复杂的,至少对于我这样的smali水平来说)

但是我并不会放弃,一条道走到黑吧

如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk


Smali 模拟器

    

    事实上,我可以理所当然用smali代码Class623::method5,创建一个新的Android app,并用apktool工具反编译,构造一个注入的非常规的smali代码,并且插入到新的app中,然后重建并启动app……但是呢:

1、再次声明,我很懒的;

2、这个解决方法并不优雅;

3、还有就是一个新的想法涌上头顶,妈的,太酷了,So,我得弄出来。


那就让我长话短说吧:

妈的,我准备写一个smali的解析器和模拟器,并用代码完善它,最终它将会明文输出我想要的结果

于是我开始阅读Dalvik官方文档(这个还要谢谢另一个好基友Gabor Paller!)几个小时后,我写了这个简单的脚本准备测试:

如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk

Aaaaaaand:

如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk

BINGO!!!

   

    我对每一个加密的字符串执行该脚本,它工作起来魅力四射,该模拟器能够正确解析并执行反编译的smali代码,以及解密我从反编译后的应用中提取的每一个函数……从这一点上它只是用明文替换密钥,转换过程变得易如反掌。

如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk
Conclusions

 我像往常一样把本文中的代码发到 github (https://github.com/evilsocket/smali_emulator)上,尽管仍然缺乏大量的Dalvik代码的支持,我仅仅执行了我需要的那部分代码,当然者在本文中显而易见,但这个还是很容易容易改进的,我应该会在未来几天完成吧。

如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk

inn0team只是一个正在成长的小的安全团队
微信号:inn0team
如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk
长按便可关注我们


如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk

点击下方“阅读原文”即可查看原文

本文始发于微信公众号(inn0team):如何利用Python和自制smali模拟器反编译了一个加混淆防篡改的apk

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: