我正在尝试为 x86 和 amd64 编写蹦床,以便将给定的函数调用立即向量化到存储在已知内存位置的地址(目的是确保第一个目标地址位于给定的 DLL(窗口)中)。
以下代码试图_fn
用作内存位置(或其中一组)来启动实际目标地址:
(*_fn[IDX])(); // rough equivalent in C
.globl _asmfn
_asmfn:
jmp *_fn+8*IDX(%rip)
旨在使用一些 CPP 宏来构建,IDX
以提供一系列嵌入式 DLL 向量,每个向量都唯一地映射到_fn
函数指针数组中的一个槽。这适用于一个简单的测试程序,但是当我实际将它放入共享库时(目前在 OSX 上进行测试),在尝试引导到 _asmfn 代码时出现总线错误:
Invalid memory access of location 0x10aa1f320 rip=0x10aa1f320
这段代码的最终目标是 Windows,虽然我还没有在那里尝试过(我想我至少可以先在 OSX/intel 上的测试用例中证明程序集)。amd64 跳转至少在名义上是正确的,还是我错过了什么?
amd64 上关于蹦床的一个很好的参考。
编辑
跳转在 Windows 7 上确实可以正常工作(终于有机会测试了)。但是,我仍然很想知道为什么它在 OSX 上失败了。总线错误是由 KERN_PROTECTION_FAILURE 引起的,这似乎表明操作系统保护正在阻止执行该代码。目标地址是分配的内存(它是由 libffi 生成的蹦床),但我相信它被正确标记为可执行内存。如果这是一个可执行内存问题,那就可以解释为什么我的独立测试代码可以工作(回调蹦床是编译的,而不是分配的)。