Android逆向之旅--「最右」签名算法解析(ARM指令学习喜欢篇)

一、逆向分析

在之前已经介绍了最右这款App的签名算法解析第一篇工作,因为签名算法比较多,所以就分开处理,大家如果要看后续文章,一定要记得去详细看第一篇文章,不然我也不能保证你不懵逼!上一篇解析完了第一部分算法解析工作,这一篇继续操作,首先用IDA打开so查看第二部分代码,同时IDA动态调试so,具体步骤大家一定要去看第一篇内容,这里不再详细说了,我们动态调试到了第二部分加密算法:

640?wx_fmt=png

看到这段代码和之前的一段其实差不多,然后再看看静态的伪代码:

640?wx_fmt=png


看到arm指令的代码和伪代码位置不太一致,但是没关系,我们看关键点,比如arm指令的前几行是SUB和AND操作,而且看到是自减4然后和0xF进行与操作:

640?wx_fmt=png

640?wx_fmt=png

所以这时候看到伪代码的地方:

640?wx_fmt=png


所以有时候发现伪代码和动态调试的代码不一致没关系,只要看到特殊值找到对应代码即可,按照之前的规矩,把伪代码拷贝到之前的C代码中:

640?wx_fmt=png

首先依然是有个变量循环四次,每次递增4,然后是之前打印的四个常量值放在R0-R3寄存器中,

640?wx_fmt=png


我们把伪代码实现之后打印值发现和动态调试的值是一样的,所以这一块就过去了,继续往下看:

640?wx_fmt=png


这里发现了一个密钥库,还记得之前在第一篇中我们已经发现了一个密钥库长度是64个字节,我们在看到LDR指令的时候一定要留意这个一般都是加载内存中的数据,看到ADD.W R11, R4, #0x40 这个是在之前的密钥库B1E0基础上加上64,也就是说这个密钥库是和B1E0那个内存中挨着的:

640?wx_fmt=png


然后我们看看内存中的值:

640?wx_fmt=png

我们再把这个密钥库弄出来即可:

640?wx_fmt=png


继续往下走就是和之前一篇一样用四个常量值进行与或非操作了:

640?wx_fmt=png

不过这里需要介绍一个新指令:LDMIA.W

640?wx_fmt=png


这个指令是一次性从一个地址中连续取出多个值放到寄存器中,与之对应的还有存储指令,而且还有顺序直说,这个指令的详细说明如下(摘自网络):

LDM:(load  much)多数据加载,将地址上的值加载到寄存器上
STM:(store much)多数据存储,将寄存器的值存到地址上
主要用途:现场保护、数据复制、参数传送等,共有8种模式(前面4种用于数据块的传输,后面4种是堆栈操作)如下:
1> IA: 每次传送后地址加4,其中的寄存器从左到右执行,例如:STMIA R0,{R1,LR} 先存R1,再存LR
2> IB: 每次传送前地址加4,同上
3> DA: 每次传送后地址减4,其中的寄存器从右到左执行,例如:STMDA R0,{R1,LR} 先存LR,再存R1
4> DB: 每次传送前地址减4,同上
5> FD: 满递减堆栈 (每次传送前地址减4)

6> FA: 满递增堆栈 (每次传送后地址减4)
7> ED: 空递减堆栈 (每次传送前地址加4)
8> EA: 空递增堆栈 (每次传送后地址加4)
注意:其中在数据块的传输中是STMMDB和LDMIA对应,STMMIA和LDMDB对应,而在堆栈操作是STMFD和LDMFD对应,STMFA和LDMFA对应


比如这里就是从R11寄存器中的地址也就是第二个密钥库E220中连续取出三个四个字节的数据放到R9,R10,R11中,看到上面寄存器中的值在和密钥库比较:

640?wx_fmt=png


这个指令后面还会用到,需要记住它,让后往下就是与或非操作了:

640?wx_fmt=png


这里看到一波与或非操作,但是有点坑爹的是中间多了一条穿插指令,所谓穿插指令就是本来流程是正常的,但是中间无意中多了几行指令,发现这些指令的操作结果值不参与后面的指令执行,那么就是指令穿插,比如这里我们分析之前的文章知道一般在ROR操作之前都是BIC+AND+ORR,但是这里突然来了一个BIC,而且BIC的操作结果R4并没有参与ROR的操作,所以就认为他是个穿插指令,需要记住它因为后面肯定在哪个地方需要他。这里看到之前与或非之后的操作R2是B658E0EC,我们打印C代码看看结果是否正确:

640?wx_fmt=png


看到这里打印结果是正确的,说明我们的第二个密钥库是正确的,后面就是正常的ROR操作了,大部分内容和第一篇类似:

640?wx_fmt=png


我们打印了C代码的执行结果,而且这里找到了那条穿插指令的位置,再去动态调试查看寄存器值是否正确:

640?wx_fmt=png


640?wx_fmt=png


这样看到打印的值就没问题了,然后后面就和之前的一篇文章一样了,就不在多说了,我们最后直接看轮训后的值:

640?wx_fmt=png


640?wx_fmt=png


640?wx_fmt=png


640?wx_fmt=png


依然是轮训了四次,我们打印一下C代码结果:

640?wx_fmt=png


二、技术总结

看到了四次轮训结果和上面的一模一样,说明加密算法的第二部分分析完了,这里我们也学习到了一些新知识:

第一、新增LSL循环左移指令,LDMIA批量连续读取多个内存数据

第二、对于分析指令的时候如果发现有一些意外的多余指令可以认为是穿插指令,识别穿插指令的方法就是看到这条指令的操作返回值是否参与后续的流程


严重说明

本文的目的只有一个就是学习逆向分析技巧,如果有人利用本文技术进行非法操作带来的后果都是操作者自己承担,和本文以及本文作者没有任何关系,本文涉及到的代码项目可以去编码美丽小密圈自取,长按下方二维码加入小密圈一起学习探讨技术

640?wx_fmt=png


三、总结

我们在分析arm指令的时候,看到LDR指令需要留意,因为可能是在读取内存中的密钥库,见到LSL指令是乘法操作,而一般加密算法都会有密钥库,同时发现这个加密算法是分为四个循环部分,但是都是很类似,后面还会继续把第三和第四部分一起分析,敬请期待!


手机查看文章不方便,可以网页看

http://www.520monkey.com


《Android应用安全防护和逆向分析》 

 点击查看图书详情


长按下面??二维码,关注编码美丽


640


长按下面??二维码,加我好友吧!

640?wx_fmt=png


猛戳下方"阅读原文",开启安全逆向大门!

640

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值