// Basically reworking what this guy already did:
// http://www.codeproject.com/KB/cpp/thunk32.aspx
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <cstdio>
using std::printf;
struct I {
virtual void print() = 0;
};
struct C : I {
C(int x)
: x(x)
{ }
void print() {
printf("My x is %i\n", x);
}
int x;
};
typedef void (__stdcall *Function0)();
void nothing() {
__asm {
mov ecx, 0x11223344 // B9 44 33 22 11
mov eax, 0x44332211 // B8 11 22 33 44
jmp eax // FF E0
}
}
template <typename D, typename S>
D really_reinterpret_cast(S s) {
char __static_assert_that_types_have_same_size[sizeof(S) == sizeof(D)];
union {
S s;
D d;
} u;
u.s = s;
return u.d;
}
void main() {
I* instance = new C(994);
char code[] = {
0xB9, 0, 0, 0, 0, // mov ecx, 0
0xB8, 0, 0, 0, 0, // mov eax, 0
0xFF, 0xE0 // jmp eax
};
// YEEHAW
*((I**)(code + 1)) = instance;
*((void**)(code + 6)) = really_reinterpret_cast<void*>(&I::print);
void* buffer = VirtualAlloc(0, sizeof(code), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(buffer, &code, sizeof(code));
FlushInstructionCache(GetCurrentProcess(), buffer, sizeof(code));
Function0 f0 = reinterpret_cast<Function0>(buffer);
for (int q = 0; q < 10; q++) {
f0();
}
VirtualFree(buffer, 0, MEM_RELEASE);
}