我正在尝试使用 C++ 和 Win32 API 创建一个 thunk,将这个指针绑定到静态成员函数,所以我可以将该函数用作回调。
现在,我有一个适用于 x64 的工作 thunk,它通过将 r9 寄存器的值(对应于函数的第 4 个参数)设置为此指针的地址来工作。
但是我遇到了 x86 的 thunk 问题,我尝试设置 [esp+10h] 的值(也对应于第 4 个参数)。
这是thunk:
#pragma pack(push, 1)
struct THUNK {
DWORD mov; // mov dword ptr[esp+10h], pThis
DWORD pThis;
BYTE jmp; // jmp relproc
DWORD relproc;
}
#pragma pack(pop)
这是使用 thunk 的类:
class foo {
void callback_impl(int a, int b, int c) {
...
}
static void __stdcall callback(int a, int b, int c, foo *This) {
This->callback_impl(a, b, c);
}
public:
THUNK *thunk;
foo() {
thunk = (THUNK*)VirtualAlloc(NULL, sizeof(THUNK), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
thunk->mov = 0x102444C7;
thunk->pThis = (DWORD)this;
thunk->jmp = 0xe9;
thunk->relproc = DWORD((INT_PTR)&foo::callback - ((INT_PTR)thunk + sizeof(THUNK)));
FlushInstructionCache(GetCurrentProcess(), this, sizeof(THUNK));
}
~foo() {
VirtualFree(thunk, sizeof(THUNK), MEM_DECOMMIT);
}
};
这是回调用户:
void callback_user(void(__stdcall *callback)(int, int, int)) {
...
}
// foo f;
// callback_user((void(__stdcall*)(int, int, int))f.thunk);
但是,当我运行程序时,它给了我失败:
运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是调用使用一种调用约定声明的函数和使用另一种调用约定声明的函数指针的结果。
我怎么解决这个问题?
谢谢。