関数の乗っ取り

hoge() を piyo() で乗っ取る例。(WindowsVC++にて)

#include <stdio.h>
#include <windows.h>

void hoge(void)
{
    printf("hogehoge\n");
}

unsigned int original_hoge;

void piyo(void)
{
    printf("piyopiyo\n");

    // 本来のhogeを呼び出す
    ((void(*)())original_hoge)();
}

int main(void)
{
    // hogeのスタブのアドレス
    unsigned int stub_hoge = (unsigned int)(void*)hoge;
    // ジャンプ先へのオフセット値
    unsigned int* offset = (unsigned int*)((unsigned char*)stub_hoge+1);
    // 本来のhogeのアドレス
    original_hoge = stub_hoge + *offset + 5;

    // piyoのスタブのアドレス
    unsigned int stub_piyo = (unsigned int)(void*)piyo;


    // 仮想アドレスのアクセス保護解除
    DWORD dwOldProtect;
    VirtualProtect(offset, sizeof(offset), PAGE_EXECUTE_READWRITE, &dwOldProtect);
    // hogeのスタブの値をpiyoのスタブへジャンプするように書き換え
    *offset = stub_piyo - (stub_hoge+5);
    // 仮想アドレスのアクセス保護を元に戻す
    VirtualProtect(offset, sizeof(offset), dwOldProtect,&dwOldProtect);

    // hogeを呼んでみる
    hoge();

    getchar();
    return 0;
}