Android绕签名
Android开发基于Java语言,比较容易被反编译,因此在开发过程中对APK的保护是必不可少。特别是金融类,涉及用户隐私、钱财的APP对安全要求极高,以防被恶意篡改。目前比较普遍做法是apk的加固和签名保护。这篇主要基于签名的绕过作些简单介绍,提供思路以及本人的实践流程。 水平有限,不当之处非常欢迎大家指正批评! 对App的反编译修改,只用作学习交流。如果有一定的Smali语法基础,那便能更好的去理解这篇文章。
需要的工具
010Editor 用于修改so库 IDA 用于反编译so库 另外,还要反编译工具。这里我用apktool
思路
apk的签名验证一般在Java层,Native层或是服务器验证三种形式。如果在Java层时就非常简单破解,这种签名验证如同虚设,因此一般APP开发不建议这种做法。在Native层也就是在so库中,因为C语言特征,因此反编译难度会骤然增加,但也是可以尝试绕过。最后一种则是服务器验证,网络的验证如果仅仅是字符串,可以通过抓包正常apk和异常Apk,一般服务器会传输一个key值与客户端比对。因此抓包分析出两个apk的key值差异,通过修改原有的字符串来绕过验证
实践
首先反编译
我这里用的是某款证券类APP(如果APK已经加固就需要脱壳处理!) 首先反编译执行命令:
apktool d yourApk.apk
此时便会看到这样的目录:

这里的smali文件存放的便是源代码,只不过是.smali结尾的smali文件。JVM执行的是class文件,dalvik执行的smali文件。
执行回编命令:
apktool b yourApk
(不带.apk后缀)
(如果回编失败,可能是apk为防止反编译做了特殊处理。常见的做法是在res放一张以常见图片格式结尾的文件,如fangzhihuibian.png,但这张图片并不是真正的图片,在打包apk的时候并不会报错,但apktool在回编时会报错,只要随便找张图片以相同的命名替换即可。根据apktool的报错堆栈来处理,当然这只是举例一种手法,可以根据apktool的报错堆栈具体问题,具体处理)
这时,便会在目录下多生成build和dist两个文件夹。build目录里有个class.dex文件,这便是类似windows的EXE文件的Dalvik的EXE文件。
dex–smali–jar,这三种文件可以互相转换。(具体方法网上有很多资料可以参考)
为了方便,我们将dex文件装换成jar文件,可以用JD-GUI工具打开。
在dist的目录中,便是回编成的apk包,签上自己名。
OK!!装在手机上,便弹出一条Toast,”APP已被篡改”,进不去应用。此时便是签名验证生效,此时该怎么处理???
Java层绕过签名
这里的Toast是关键突破点。肯定是在验证失败弹出这条吐司,因此可以从这段代码着手。开始查找“APP已被篡改”这段文字在smali文件夹的哪里出现过。注意:由于文件编码格式,中文已被替换成Unicode码
执行命令:
grep -rns "\u7be1" yourPath/smali
(方便起见就查找一个“篡”)
结果为:

因此很明显,第一条记录很符合条件,在BufferActivity中。根据路径代开相应的smali文件中可以看到这段关键代码:

解读发现: 调用Application中的AuthKey之后得到的字符串,与”true”进行比较,如果通过,则跳转到cond_4,如果不通过则弹出我们刚刚看到的吐司。
如果仅仅只在java层做签名认证,修改便很简单,只要让代码跳转到cond_4即可。这里“if-eqz”,意思是相等就跳转到cond_4。把if-eqz改成if-nez便可以,意思是不相等跳转。事实上,在我测试中,确实走到这一步,就完成了。再回编打包签名,apk便可以用。=_=!!! 所以这个app的签名验证是非常不安全的。
那怎么在native层修改呢?那上面的说的工具不都没用到??
native绕过签名
在native中验证无非要拿字符串,一般会生成MD5放在so库中的函数中比较。 事实上还可以用这个作为例子

刚刚的AuthKey方法是在native层实现。因此用这个例子,可以来改native的验证。
在lib文件夹中,libVerify.so的文件,猜测这个便是用来做验证的核心so库,放入IDA打开,注意选择合适的CPU架构。

找到.rodata:

相信这里代码大家会眼睛一亮,查看调用规则。

箭头指向代码的流向,上面的代码最后流向,true或false。条件便是最后的判断语句,BNE loc_f20–这是汇编中的跳转语句,条件对应最近的一条CMP语句。意思是不相等就跳转到loc_f20处。相同的,查看BNE对应的16进制HEX.

用010Editor打开文件,找到对应行数00000F10将其中的03D1修改为03D0即可,即对应BEQ。
到这里,便破坏了在Native的签名认证。