Thunk技术

下面代码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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容