如何根据汇编中的地址调用printf函数

时间:2012-01-08 04:54:29

标签: c assembly

我想根据地址调用一个函数。但在我尝试这样做之后,一些麻烦来到了我的眼前。我无法解决这些麻烦。我不知道出了什么问题。 请有人帮我完成呼叫动作。 image link

#include <stdio.h>

void main()
{
    char* mat = "%s\n";
    char* str = "abc";
    //printf(mat,str);

    _asm
    {
        mov         eax,dword ptr [ebp-8]
        push        eax
        mov         ecx,dword ptr [ebp-4]
        push        ecx
        mov         eax,00401090h //function 'printf' address
        call        [eax]
        //call        printf //dont call like this, we shall call based on its address.
    }

    getchar();
}

2 个答案:

答案 0 :(得分:4)

您不能依赖printf处于硬编码地址。

替换:

mov    eax,00401090h
call   [eax]

使用:

call    printf

答案 1 :(得分:2)

包含printf的DLL的加载地址可以(并且确实!)有所不同。这意味着printf的地址会发生变化 - 甚至可能会在同一个应用程序的两次运行中发生变化!

你可以像Drew建议的那样做,并用文字printf替换它 - 链接器将用蹦床例程的正确地址替换它(反过来,它可以从一个编译移动到另一个编译,或者即使在运行时,如果你有一个可重定位的可执行文件),它将在运行时指向真实的printf

或者您可以使用特定于操作系统的例程在运行时自己查找printf的地址,然后使用该地址调用(详细信息留给读者练习 - 我建议先在C中进行原型设计) ,然后将它一次翻译成asm)。在Windows上,查找GetProcAddress;在Unixen上,查找dlsym