Thunk技术

作者: JetLu | 来源:发表于2015-01-26 17:45 被阅读243次

    下面代码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;
    }
    

    相关文章

      网友评论

        本文标题:Thunk技术

        本文链接:https://www.haomeiwen.com/subject/dhmkxttx.html