吾爱破解教程链接《教我兄弟学Android逆向08 IDA爆破签名验证》

前言

IDA pro我之前接触过,但用它修改指令和数据还是第一次。通过上一篇教程,我知道了用ida修改so文件,实际上就是修改数据对应的HEX值。比如将hello 52pojie修改为hello world,就是将其对应的16进制修改。而在这篇爆破签名验证的教程中,需要我去修改CPU指令。原理和修改数据相同,也是修改指令对应的hex值,但不是字符串转换那么简单了。

对ARM架构的CPU简单介绍

在开始之前有必要了解一下ARM架构CPU的知识。我们都知道pc领域cpu的老大是Intel,而移动设备cpu老大就是ARM。不同的cpu架构对应不同的指令集。Intel和ARM两大阵营还可以再细分。Intel的架构中x86代表32位cpu,x86_64代表64位的cpu,x86汇编语言学习最为普遍。ARM架构也有32位和64位之分。

image-20210203100254429

在此例中,我们使用apktool对app进行反编译,lib下得到三个包含so的文件夹。

1
2
3
armeabi     : 32位 arm cpu 库,几乎所有手机都支持
armeabi-v7a : 64位 arm cpu 库,现在我们买的手机基本上都是64位的cpu了
x86 : 在电脑上运行的模拟器或者基于Intel x86的平板电脑上用的

这三个版本的库在指令上有多差别。作为初学者,我们选择 armeabi 下的 libJniTest.so 库作为研究对象,便于在网上查找资料。

Google一开始就没把筹码都压在ARM上,Android1.6开始Dalvik虚拟机提供对x86的支持。Android4.1加入了对MIPS的支持。

修改指令:将 BNE 改为 BEQ

根据教程一步步操作,来到了最关键的地方

image-20210203103710704

1
2
3
4
cmp 是比较两个数是否相等
loc_F62 代表的函数是 “签名不一致,退出程序”
BNE 指不相等的时候跳转(branch not equal)
BEQ 指相等的时候跳转(branch equal)

搞清楚了逻辑,那么爆破这个apk的签名其实就是把 BNE loc_F62 改为 BEQ loc_F62,即签名一致则跳转到 loc_F62退出程序,我们的签名和作者签名一定不同,所以程序不会直接退出,爆破成功。

选中BNE指令来到hex dump视图,对应的16进制为10D1

image-20210203104320113

查看下方的BEQ指令来到hex dump视图,对应的16进制为09D0

image-20210203104437676

原教程中说将10D1改为10D0即完成了BNE到BEQ的修改,但是为什么这样修改呢?

深入问题

在《计算机组成原理》和《汇编语言》中,我们知道了计算机指令的组成

1
一条指令(32位) = 操作码(前16位):操作数(后16位)

操作码代表做哪些运算,例如:ADD、MOV、B 等等
操作数就代表被操作的数据,即可以是数据也可以是地址。

回到此例中

1
2
BNE loc_F62  对应机器码 10 D1 对应二进制 0001 0000 1101  0001
BEQ loc_F74 对应机器码 09 D0 对应二进制 0000 1001 1101 0000

哪几位对应指令,哪几位对应数据呢?我们再往下看。

查询arm的官方指令手册可以知道B(跳转指令的用法)

image-20210203110514898

1
2
3
4
5
6
7
B指令
格式:`B{条件} 目标地址`
解释:B指令是最简单的跳转指令。一旦遇到一个B指令,ARM处理器将立即跳转到给定的目标地址,从那里继续执行。注意存储在`跳转指令中的实际值是相对当前PC 值的一个偏移量,而不是一个绝对地址`,它的值由汇编器来计算(参考寻址方式中的相对寻址)。它是24位有符号数,左移两位后有符号扩展为32 位,表示的有效偏移为26 位(前后32MB的地址空间)。以下指令:
示例:
B Label //程序无条件跳转到标号Label处执行
CMP R1,#0 //当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label处执行
BEQ Label

再对照条件码表

image-20210203110701674

我们可以得到指令对应的机器码

1
2
BNE 1101 0001
BEQ 1101 0000

这样一看就清晰明了了,此例中对应的二进制居然是数据在前,指令在后的。故修改时应将1101 0001改为1101 0000即为D1改为D0

cpu指令必然是操作码在前,数据在后。只不过是ida hex视图显示下,16进制高位在右,低位在左。所以看起来是反过来了,但实际上书写的时候操作码是在高位的。所有的16进制编辑器都是这样显示的。

结论

ida pro 反汇编 Android SO库(armeabi版本) ,一条汇编指令如果由4个十六进制数组成的,so库的指令格式如下:

1
一条SO的汇编指令(16位) = 操作码(前8位) :操作数(后8位)

image-20210203113643245

修改后即可绕过签名验证

后续作业绕过登录验证的代码也在so中,修改思路大致相同,同样是更改判断语句的条件。

总结

对arm的原生逆向比对smali的逆向要困难的多。理解各种指令的使用方法才能更好的理解程序并做出修改。

Arm指令转16进制速查可使用Arm汇编指令转机器码网站:http://armconverter.com/但是ida pro反编译SO库用的是 Thumb-2 指令集,这个指令集是 arm 指令集的子集。转码网站似乎不在支持Thumb-2指令集,只有一个Thumb选项,和ida pro反编译的内容略有差别。

参考资料
https://www.52pojie.cn/thread-732955-1-1.html
《Android软件安全与逆向分析》
https://blog.csdn.net/fuchaosz/article/details/104804026
感谢CSDN博主“梧桐那时雨”的文章,我十分敬佩他对问题钻研的态度