安卓逆向学习笔记(8)- 破解NDK层的签名校验

        在上篇文章中,我记录了破解Java层的签名校验。本文介绍的则是破解NDK层的签名校验,与Java层的签名校验相比,NDK层的签名校验破解的难度更大一些。但是NDK层签名校验破解的思路与Java层签名校验破解的思路相似:
       (1) 通过输入“signature”关键字定位获取本Apk签名信息的函数(在下文中,我们用getApkSign来标记该函数);
       (2) 找出调用的getApkSign函数的函数列表,然后在得到的函数列表中筛选出签名校验函数(在下文中,我们用verifyApkSign来标记该函数);
       (3) 梳理verifyApkSign函数的流程,找到判断签名合法性的关键代码,然后修改关键代码以绕过签名校验。

       本文只是介绍破解NDK层签名校验的过程,至于破解Apk签名校验的整个流程以及破解思路,请看博客:去除小黄人快跑ver2.6.5签名校验的过程  我就是参考这篇博客学习破解NDK层的签名校验。下面以手游小黄人快跑(版本为2.6.5)为例,从已经确定该Apk采用的是NDK层签名校验的步骤开始,简单介绍一下破解NDK层签名校验的流程:

0x00 反编译小黄人快跑Apk

       将小黄人快跑Apk放入某个文件夹中,在该文件夹中打开命令提示符,
       输入命令:apktool d xiaohuanrenkuaipaos_33lc.apk
       如图1所示:

安卓逆向学习笔记(8)- 破解NDK层的签名校验_第1张图片

图1  反编译小黄人快跑客户端


0x01 定位获取当前Apk签名的函数

       使用Notepad++的“在文件中查找”功能定位到反编译apk所得到的\lib\armeabi-v7a文件夹,然后搜索签名信息对应的关键字:
” [Landroid/content/pm/Signature”。具体如图2和图3 所示:

安卓逆向学习笔记(8)- 破解NDK层的签名校验_第2张图片

图2  使用Notepad++在文件中查找字符串的功能


安卓逆向学习笔记(8)- 破解NDK层的签名校验_第3张图片

图3  在反编译得到的lib文件夹中查找签名字符串


       搜索完毕后,我们会发现有两个so文件用到了签名信息,分别是libcipher.so和libdespicablemefree.so。具体如图4所示:

   

 图4  查找签名关键字所命中的目标


(1)我们先用IDA Pro加载libcipher.so进行静态分析,
我们输入关键字” [Landroid/content/pm/Signature”查找签名信息,可以发现libcipher.so中的Java_com_wandoujia_base_utils_CipherUtil_getAESKeyNative函数使用了签名信息,具体如图5所示:

图5  查找libcipher.so中使用签名信息的函数


所以我们要重点分析Java_com_wandoujia_base_utils_CipherUtil_getAESKeyNative 这个函数,通过分析我们可以发现该函数只是获取了Apk的签名信息,但是并没有被其他函数调用,所以我们可以断定Apk签名校验函数并不在libcipher.so中。而且该函数名字中出现了wandoujia这样的关键字,因此我们可以判定这个函数可能与豌豆荚有关,并不是我们所要寻找的获取当前Apk签名的函数。
(2)我们接着用IDA Pro加载libdespicablemefree.so进行静态分析,与分析libcipher.so的过程类似,我们输入关键字” [Landroid/content/pm/Signature”查找签名信息,可以发现libdespicablemefree.so中的nativeGetApkSignature函数使用了签名信息,具体如图6所示:

图6  查找libdespicablemefree.so中使用签名信息的函数


通过分析nativeGetApkSignature函数的内部实现,还有nativeGetApkSignature这个函数名字,我们可以断定该函数应该是获取当前Apk签名的函数。


0x02 定位和分析Apk签名校验函数

通过分析nativeGetApkSignature函数,我们发现该函数的右边出现了
; CODE XREF: sub_50DF64+58 p 这样的关键字,如图7所示:

安卓逆向学习笔记(8)- 破解NDK层的签名校验_第4张图片

图7  nativeGetApkSignature函数


双击字符串 ; CODE XREF: sub_50DF64+58 p,我们就能找到调用nativeGetApkSignature函数的代码,该代码在libdespicablemefree.so中的偏移地址是0x0050DFBC,具体如图8 所示:

安卓逆向学习笔记(8)- 破解NDK层的签名校验_第5张图片

图8 调用nativeGetApkSignature函数的代码


该代码位于函数sub_50DF64中,所以我们需要重点分析sub_50DF64这个函数。我们将鼠标定位到函数sub_50DF64处,然后再按键盘上的F5键就可以得到函数sub_50DF64对应的C代码(这样做的前提是,你的IDA Pro必须支持F5功能),具体的C代码如图9所示:

安卓逆向学习笔记(8)- 破解NDK层的签名校验_第6张图片

图9 函数sub_50DF64对应的C代码


       通过分析C代码,我们能发现函数sub_50DF64的设计流程:先调用函数nativeGetApkSignature获取系统的签名信息;然后调用strcmp函数将该签名信息与某个字符串(我想这个字符串应该就是正版Apk的签名信息)进行比较,如果二者不相同,则调用kill函数终止当前进程的运行。函数sub_50DF64应该就是Apk签名校验函数。


0x03 修改Apk签名校验函数

找到Apk签名校验函数后,我想到了两个破解办法:
(1)找到调用函数sub_50DF64的语句 BL sub_50DF64,将其nop掉,即将BL sub_50DF64改为空操作;
(2) 更改函数sub_50DF64的执行流程,让其在执行过程中避开nativeExit, kill, __stack_chk_fail这些函数,直接跳转到函数的末尾处。
显然办法(1)更简单,所以接下来我使用的是办法(1)。
/*办法(2)也是可以破解成功的,感兴趣的童鞋可以自己尝试一下*/
先按下快捷键Alt + t,然后输入查找关键字”sub_50DF64”,我们可以找到语句”BL sub_50DF64”,该语句在libdespicablemefree.so中的偏移地址是0x005046B8,如图10所示:

安卓逆向学习笔记(8)- 破解NDK层的签名校验_第7张图片
图10  BL sub_50DF64 语句


BL sub_50DF64对应的机器码为” 29 26 00 EB”,如图11所示:

安卓逆向学习笔记(8)- 破解NDK层的签名校验_第8张图片

图11  BL sub_50DF64语句对应的机器码


我们可以使用二进制编辑软件UltraEdit将该机器码改为”00 00 00 00”,如图12所示:

图12  nop掉BL sub_50DF64指令


为了和原版App进行区分,我将values\strings.xml中icon_label的值改成了”小黄人快跑签名破解版”,如图13所示:


图13  修改APP的名字


0x04 二次打包apk并进行签名
打开命令提示符,
输入命令:apktool b xiaohuanrenkuaipaos_33lc
对小黄人快跑进行二次打包,具体如图14所示:

安卓逆向学习笔记(8)- 破解NDK层的签名校验_第9张图片

图14  重新打包apk


然后再用签名工具对二次打包生成的Apk进行签名即可。
因为我提早就知道了该版本的小黄人快跑采用的是基于NDK层的签名校验,所以整个破解过程才会显得一气呵成。其实一般的逆向过程不可能像博客中这么顺利,需要仔细阅读逆向得到的代码,耐心地去挖掘线索,根据线索来寻找破解的突破点。

本文资源下载地址:安卓逆向学习笔记(8)
本文只做技术交流之用,请勿用于其他用途。


你可能感兴趣的:(安卓,安全,软件)