为什么ARM的这个分支指令不起作用
Why this branch instruction of ARM doesn't work
现在我正在编写一个库来模拟C/c++的平凡函数。它是这样使用的:MOCK(mocked, substitute)
如果调用模拟函数,则会调用替代函数。
我修改了代码页的属性,并将跳转代码注入到函数中实现。我已经为x86 CPU
实现了它,我想把它移植到ARM CPU
。但是我有一个问题,当我注入二进制代码。
例如,替代函数的地址为0x91f1
,要模拟的函数的地址为0x91d1
。所以我想注入ARM分支代码到0x91d1
跳转到替代函数。
根据网上的文件,相对地址是
(0x91f1 - (0x91d1 + 8)) / 4 = 6
所以二进制指令是:
0xea000006
因为我的手臂模拟器(我使用Android手臂v7模拟器)是小端序的,所以要注入的二进制代码是:
0x060000ea
但是当我在注入分支代码后执行模拟函数时,发生了段错误。我不知道为什么分支指令是错误的。我没有学过ARM架构,所以我不知道ARM的分支指令是否有一些限制
您要分支到的地址是奇数,这意味着它们处于拇指模式。
你的方法有一个明显的问题。
如果目标处于Thumb模式,您要么需要在您的分支点处于Thumb模式,要么需要使用bx
(分支和交换)指令。
您的函数处于拇指模式(目标+1),但您正在使用ARM模式分支编码(B A1编码?),因此显然您不是处于拇指模式,或者您在拇指模式下使用ARM模式指令。
ARM系列允许用值加载寄存器。其中一个寄存器是PC(程序计数器)。
其他选项:
- 你可以使用一个函数来加载PC寄存器目的地址(绝对).
- 添加带有偏移量的PC寄存器。
- 使用PC寄存器的乘法和加法指令。
- 将目标寄存器压入堆栈并弹出PC登记。
这些选择加上修改分支指令的目的地都是不同的选择,而不是"最佳"。选择一个最适合你,最容易维护的。
相关文章:
- 我的神经网络不起作用 [XOR 问题]
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- C++为什么尽管我调用了void函数,它却不起作用
- 为什么在保护模式下继承升级不起作用
- 循环在计数器中不起作用
- 在其他文件中创建类时在 c++ 项目中不起作用
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 为什么二进制搜索在我的测试中不起作用
- 我的代码中有错误吗?使用BGI图形的C++代码对我不起作用
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 带有指定长度字符* 参数的 std::regex_search 在 VS2017 中不起作用?
- Bjarne Stroustrup Book - std_lib_facilities.h - 不起作用(未知类型名称)
- 为什么简单的算术减法在"if"条件下不起作用?
- 为什么Stroustup书中的has_f不起作用
- 为什么使用"使用指令"时 ADL 不起作用?
- CUDA中的洗牌指令不起作用
- 我可以将 #define 指令与 :: 一起使用吗?为什么它不起作用?
- 为什么ARM的这个分支指令不起作用
- 预处理器指令在for循环中不起作用