下面代码mingw编译通过,用windows的cl编译器须略作改动。
#include <iostream>
#include <string>
using namespace std;
void test(int i) {
cout << i;
}
#pragma pack(push, 1)
struct Thunk {
unsigned char mov[4];
int num;
unsigned char jmp;
unsigned long proc;
void init(int i) {
mov[0] = 0xC7;
mov[1] = 0x44;
mov[2] = 0x24;
mov[3] = 0x04;
num = i;
jmp = 0xE9;
proc = (unsigned long)test - (unsigned long)this - sizeof(Thunk);
};
} *thunk;
#pragma pack(pop)
int main() {
thunk = new Thunk;
//for vc
//thunk = (Thunk*)VirtualAlloc(nullptr, sizeof(Thunk), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//FlushInstructionCache(GetCurrentProcess(), thunk, sizeof(Thunk));
thunk->init(5);
typedef void (*Func)(int);
Func func = (Func)thunk;
func(7);
//输出5,而不是7
return 0;
}
x64
模式适用
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
typedef void (*Func)();
class A {
public:
void echo() {
cout << "ok";
}
};
#pragma pack(push, 1)
struct Thunk {
unsigned char mov;
A* num;
unsigned char rov[2];
ULONGLONG proc;
unsigned char jmp[2];
void init(ULONGLONG addr, A *i) {
mov = 0xb9;
num = i;
rov[0] = 0x48;
rov[1] = 0xb8;
proc = addr;
jmp[0] = 0xff;
jmp[1] = 0xe0;
FlushInstructionCache(GetCurrentProcess(), this, sizeof(Thunk));
};
} *thunk;
#pragma pack(pop)
void test(void *i) {
((A*)i)->echo();
}
int main() {
A *pa = new A;
thunk = (Thunk*)VirtualAlloc(nullptr, sizeof(Thunk), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
thunk->init((ULONGLONG)test, pa);
Func func = (Func)thunk;
func();
return 0;
}
网友评论