DLLエントリポイント - 実験4

またまた実験

00000000  55                push ebp
00000001  89E5              mov ebp,esp
00000003  B878563412        mov eax,0x12345678
00000008  FFD0              call eax
0000000A  C9                leave
0000000B  C3                ret

ということはきっとこんなことが出来るはず

void hello()
{
    printf("hello\n");
}

int main(int argc, char *argv[])
{
    unsigned char code[] = {0x55, 0x89, 0xE5, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xC9, 0xC3};
    *(unsigned int*)(&code[4]) = (unsigned int)hello;
    void (*call_func)(void) = (void (*)(void))code;
    (*call_func)();
    return 0;
}

動きました。

nobita% ./dynamic_code4
hello

最初いろいろ間違えてセグフォまくったので、0xEBFEをはさみまくって原因を追求した。


1個呼べれば2個呼べるはず。
ちょっと汚いけど。

void hello()
{
    printf("%s\n", __func__);
}

void goodbye()
{
    printf("%s\n", __func__);
}

int main(int argc, char *argv[])
{
    unsigned char code[128];
    code[0] = 0x55;
    code[1] = 0x89;
    code[2] = 0xE5;
    code[3] = 0xB8;
    *(unsigned int*)(&code[4]) = (unsigned int)hello;
    code[8] = 0xFF;
    code[9] = 0xD0;
    code[10] = 0xB8;
    *(unsigned int*)(&code[11]) = (unsigned int)goodbye;
    code[15] = 0xC9;
    code[16] = 0xFF;
    code[17] = 0xD0;
    code[18] = 0xC3;
    void (*call_func)(void) = (void (*)(void))code;
    (*call_func)();
    return 0;
}

結果

nobita% ./dynamic_code5 
hello
goodbye