Thunk技术

下面代码mingw编译通过,用windows的cl编译器须略作改动。

#include 
#include 
 
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 
#include 
#include 

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;
}
  • 相关链接:
    • GUI之窗口过程thunk
    • WTL学习之旅
    • 利用thunk技术封装窗口类

你可能感兴趣的:(Thunk技术)