简体   繁体   English

为什么ARM的此分支指令不起作用

[英]Why this branch instruction of ARM doesn't work

Now I am writing a library to mock the trivial function for C/C++. 现在,我正在编写一个库来模拟C / C ++的琐碎函数。 It is used like this: MOCK(mocked, substitute) If you call the mocked function, the substitute function will be called instead. 它的用法如下: MOCK(mocked, substitute)如果调用MOCK(mocked, substitute)函数,则会替代调用替代函数。

I modify the attribute of code page and inject the jump code into the function to implement it. 我修改了代码页的属性,并将跳转代码注入到函数中以实现它。 I have implemented it for x86 CPU and I want to port it to ARM CPU . 我已经为x86 CPU实现了它,我想将其移植到ARM CPU But I have a problem when I inject binary code. 但是当我注入二进制代码时,我遇到了一个问题。

For example, the address of substitute function is 0x91f1 , and the address of function to mock is 0x91d1 . 例如,替代函数的地址为0x91f1 ,要模拟的函数的地址为0x91d1 So I want to inject the ARM branch code into 0x91d1 to jump to the substitute function. 因此,我想将ARM分支代码注入0x91d1以跳转到替代函数。

According to the document online, the relative address is 根据在线文件,相对地址为

(0x91f1 - (0x91d1 + 8)) / 4 = 6

so the binary instruction is: 所以二进制指令是:

0xea000006

Because my arm emulator(I use Android arm v7 emulator) is little endian, so the binary code to inject is: 因为我的arm模拟器(我使用Android arm v7模拟器)是低端字节序的,所以要注入的二进制代码是:

0x060000ea

But when I executed the mocked function after injecting branch code, segment fault occurred. 但是当我在注入分支代码后执行了模拟功能时,发生了段错误。 I don't know why the branch instruction is wrong. 我不知道分支指令为什么出错。 I have not learned ARM architecture so I don't know whether the branch instruction of ARM has some limits. 我还没有学习过ARM体系结构,所以我不知道ARM的分支指令是否有一些限制。

Addresses you are branching to is odd numbered, meaning they are in Thumb mode. 分支到的地址为奇数,表示它们处于Thumb模式。

There is an obvious problem with your approach. 您的方法存在明显的问题。

If target is in Thumb mode, you either need to be in Thumb mode at the point you are branching from or you need to use a bx (Branch and Exchange) instruction. 如果目标是在Thumb模式下,则您需要从分支处进入Thumb模式,或者需要使用bx (分支和交换)指令。

Your functions are in Thumb mode (+1 at the target) but you are using ARM mode branch coding (B A1 coding?), so obviously either you are not in Thumb mode or you are using ARM mode instruction in Thumb mode. 您的函数处于Thumb模式(目标为+1),但是您使用的是ARM模式分支编码(BA 1编码?),因此很明显,您未处于Thumb模式或正在Thumb模式中使用ARM模式指令。

The ARM family allows loading of registers with values. ARM系列允许使用值加载寄存器。 One of those registers is the PC (Program Counter). 这些寄存器之一是PC(程序计数器)。

Some alternatives: 一些替代方案:

  1. You could use a function to load the PC register with the destination address (absolute). 您可以使用函数将目标地址(绝对值)加载到PC寄存器中。
  2. Add the PC register with an offset. 将PC寄存器加一个偏移量。
  3. Use a multiply-and-add instruction with the PC register. 在PC寄存器中使用乘加指令。
  4. Push the destination register onto the stack and pop into PC register. 将目标寄存器压入堆栈,然后弹出PC寄存器。

These choices plus modifying the destination of the branch instructions are all different options at are not "best". 这些选择加上修改分支指令的目标都是“最佳”的所有不同选项。 Pick one that suits you best and is easiest to maintain. 选择最适合您并且最容易维护的一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM