这是X64的代码(我对汇编不太了解,这个代码可以用visual studio编译,不知道是什么格式):
.code
extern mProcs:QWORD
myfunc proc
jmp mProcs[1*8]
myfunc endp
mProcs 是用 C 代码定义的数组,函数 myfunc 只是简单地跳转到数组中的第二个元素。如果从 C 语言来看,它会跳转到 *(mProcs+1)(1*8 因为在 x64 中指针是 8 个字节)。
在 GCC ARM 版本中,我尝试这样做:
.extern mProcs
.global myfunc
myfunc:
b mProcs+4
(这里是 mProcs+4 因为指针是 4 个字节)
但是这段代码似乎不起作用。在 C 中是跳转到 *(mProcs+1) 还是跳转到 mProcs+1?我怎样才能使它*(mProcs + 1)?
==================================================== ===========================
在和 Michael 的评论中讨论后,我明白我需要对寄存器进行计算,然后使用 bx 指令跳转到目标函数。
然而,问题来了。由于我正在实现一个 thunk(我正在拦截函数调用并在中间做一些事情),我不知道目标例程如何使用寄存器。
1.在我跳转到目标之前,我需要保留被调用者保存寄存器,否则目标函数将保留错误的值。
2.在执行跳转之前,我需要保持参数寄存器不变,以便目标函数具有正确的参数。3.以上两点意味着我只能使用调用者保存但非参数寄存器。
r0-r3 是参数寄存器,r4-r12 是被调用者保存寄存器,r13 以后是特殊寄存器。
这意味着在不恢复值的情况下不能使用任何寄存器。
如果 bx 指令只能对一个寄存器进行操作,那么即使该寄存器暂时保存在堆栈中,我也没有机会恢复该寄存器。
有什么解决办法吗?或者只是手臂二进制文件不能被钩住。