C 可移植可执行文件中虚拟地址的计算

C 可移植可执行文件中虚拟地址的计算,c,assembly,memory-address,virtual-address-space,C,Assembly,Memory Address,Virtual Address Space,我试图理解PE文件中寻址的基础知识,我制作了一个简单的应用程序,其中包含两个函数,这些函数调用针对msvcr110库静态链接的malloc。因此,我将生成的可执行文件在ida pro中打开,找到了未导入的malloc函数的偏移量,添加了基址,并尝试这样调用它: HMODULE hCurrentModule = GetModuleHandle(NULL); // get current module base addres DWORD_PTR hMallocAddr = (0x0048A

我试图理解PE文件中寻址的基础知识,我制作了一个简单的应用程序,其中包含两个函数,这些函数调用针对msvcr110库静态链接的
malloc
。因此,我将生成的可执行文件在ida pro中打开,找到了未导入的
malloc
函数的偏移量,添加了基址,并尝试这样调用它:

 HMODULE hCurrentModule = GetModuleHandle(NULL); // get current module base addres
    DWORD_PTR hMallocAddr = (0x0048AD60 + (DWORD_PTR)hCurrentModule); 
    char *pointer;
    __asm  //calling malloc
    {
        push 80
        mov eax,dword ptr[static_addr]
        call eax
        add esp,2
        mov [pointer],eax
    } 

然后我检查了IDA pro中重建的程序,以确保malloc偏移量保持不变,并且仍然是
0x0048AD60
。所以问题是offset+hCurrentModule给了我不正确的地址,在我调用这个地址后崩溃了。例如,我的
hmallocadr
结果是
0x0186AD60
,但在反汇编窗口的MSVC调试会话中,malloc地址位于
0x0146AD60
。这里怎么了?

0x0048AD60
不是malloc的偏移量,而是在默认加载地址0x00400000加载EXE时函数的实际地址。减去该值以获得从图像开始的偏移量。

我看到一件我不理解的事情,第一条指令;您推送一个值,但从不弹出它。当您将2添加到
esp
时,是否正在尝试修复堆栈?编译器是否可以“帮助”您将其优化为8位值

没有保证,但这些是我第一眼看到的东西;但是,我不在那里,无法看到调试屏幕

{
    push 80                           ;Where do you pop this ?
    mov eax,dword ptr[static_addr]
    call eax
    add esp,2                         ;Is this the "pop" ? Possible bug, is "80" a 16 bit value ?
    mov [pointer],eax
} 

同样,我也不完全确定你的应用程序是如何构造的,但是你是否可以安全地使用
Eax
,而不必在前推后弹出?没有任何线索如果这有什么不同,那只是粗略地看一下代码。

您是否一次一条地跟踪汇编语言指令?更重要的是,您能否在使用调试器调用eax之前停止执行?如果是这样,在调用eax之后执行的下一条指令是什么?我的直接问题是:在崩溃发生之前,要执行的指令是什么?@User.1在我计算的地址上,调试器中没有反汇编指令,就像,整个窗口的问题都在
0186AD60???
等。因此我假设地址不正确。在应用程序崩溃之前执行的指令是什么?@User.1我真的看不出来,但如果我进入,我会得到错误
无法进入,操作不受支持。未知错误0x92330010
,位于地址
0x0146AD60
“…但如果我进入…”
进入什么?当您尝试单步执行调试器时,调试器在哪里?哪条指令?about
eax
它只是从代码段所在的函数返回指针,所以没问题。关于
推送
你是对的,实际上推送将esp减少到4个字节,因此我应该在那里添加4个字节,而不是2个字节。我会更好地使用寄存器,推送适当的值,啊,等等。我对asm有点陌生。谢谢!我在IDA pro中没有注意到这一点。