手臂组装中的代码漏洞

逆向工程 拆卸 手臂 小精灵 部分
2021-06-26 01:56:30

在一个反汇编的 elf 二进制文件中,我发现了这些手臂拇指指令:

function0
0x002cc3a8  8079       ldrb r0, [r0, #6]
0x002cc3aa  7047       bx      lr

在 codecave 中,这些是初始的十六进制字节:

0x00033fd8 00 00 00 00 00 00 00 00 
0x00033fe0 00 00 00 00 00 00 00 00

然后我只是分支到代码洞穴(将指令转换为拇指十六进制):

function0
0x002cc3a8  33F0EABF        b 0x33fd8

然后将相同的十六进制字节插入到代码洞中(我没有改变任何东西):

0x00033fd8 80 79 70 47 00 00 00 00
0x00033fe0 00 00 00 00 00 00 00 00

Function0 和 codecave 位于不同的部分,但两个部分具有相同的可读和可执行标志。在调用该函数时运行应用程序后出现错误。该应用程序刚刚退出。问题似乎来自分支到 codecave。我做错了什么吗?函数和 codecave 应该在同一部分吗?

1个回答

是的,终于自己弄明白了。经过进一步测试,事实证明问题确实出在分支上。与其在拇指状态下分支,我应该在手臂状态下分支。

指令

0x2cc3a8  33F0EABF      b 0x33fd8 

应该

0x2cc3a8  4C3A0CEA      b 0x33fd8

我不完全理解这背后的原因,因为原始指令是在拇指状态下执行的,我不明白为什么处理器不识别该指令。在获得更多信息后,我将编辑答案。顺便说一下,由于处理器架构是 ARM-7,所以 arm 状态是 ARM-7 状态。

编辑: 根据我从 arm 和 keil 网站获得的有关 branch(b) 指令的信息,分支时存在限制。在拇指模式下分支时,程序计数器和您要分支到的地址的距离应该是 2KB,在我的情况下,代码洞大约是 111KB。由于限制为 32 MB,因此在 arm 状态下分支有效,但以某种方式导致错误,例如增加寄存器中的值。

解决方案:用psedo指令将代码洞起始地址的寄存器加载到pc中,例如ldr pc, =0x30e93c如果函数少于 8 个字节,这可能不起作用。在拇指模式加载到程序计数器(PC)不起作用。因此,您需要加载到通用寄存器,然后将值移动到 pc 。例如

ldr r0, =0x30e93c
mov pc, r0