이 포인터를 정적 멤버 함수에 바인딩하는 C++ 및 Win32 API를 사용하여 썽크를 만들려고합니다. 콜백 함수로 사용할 수 있습니다.C++에서 썽크를 사용하여 정적 멤버 함수에이 포인터를 바인딩하는 방법
이제는 x64에서 작동하는 썽크가 있습니다.이 포인터의 주소에 r9 레지스터 (함수의 4 번째 매개 변수에 해당) 값을 설정하면 작동합니다.
하지만 x86 용 썽크에 문제가 있습니다. [esp + 10h] (또한 4 번째 매개 변수에 해당) 값을 설정하려고했습니다. 여기
썽크입니다 :#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)
그리고 여기 썽크 사용하는 클래스의 :
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 값이 함수 호출을 통해 제대로 저장되지 않았습니다. 이것은 대개 다른 호출 규칙으로 선언 된 함수 포인터로 하나의 호출 규칙으로 선언 된 함수를 호출 한 결과입니다.
이 문제를 어떻게 해결할 수 있습니까?
감사합니다.
[mcve]를 입력하십시오. – IInspectable