【问题标题】:Calculation of the Virtual Adresses in Portable Executable便携式可执行文件中虚拟地址的计算
【发布时间】:2025-12-25 23:55:11
【问题描述】:

我正在尝试了解 PE 文件中寻址的基础知识,并且我制作了一个简单的应用程序,其中包含几个调用 malloc 的函数,这些函数静态链接到 msvcr110 库。所以我把我生成的可执行文件在 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 给了我不正确的地址,并且在我调用这个地址后崩溃。例如我的hMallocAddr 的结果是0x0186AD60,但在MSVC 调试会话中,反汇编窗口中的malloc 地址是0x0146AD60。这里有什么问题?

【问题讨论】:

  • 您是在逐个跟踪汇编语言指令吗?更重要的是,您可以使用调试器在call eax 之前停止执行吗?如果是这样,在你 call eax 之后执行的下一个 instruction 是什么?我的直接问题是:就在崩溃发生之前要执行的指令是什么?
  • @User.1 在我计算的地址上,调试器中没有反汇编指令,就像,问题遍布窗口0186AD60 ?? 等,所以我认为地址不正确.
  • 应用崩溃前执行的指令是什么?
  • @User.1 我真的看不到这一点,但如果我进入,我会在地址0x0146AD60 的第一行收到错误Unable to step, Operation not supported. Unknown error 0x92330010
  • "...but if i do step into..." 变成什么?当您尝试介入时,您的调试器在哪里?哪条指令?

标签: c assembly memory-address virtual-address-space


【解决方案1】:

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

【讨论】:

  • 谢谢!我在 IDA pro 中没有注意到这一点。
【解决方案2】:

我看到一个我不明白的东西,第一条指令;你推送一个值,但永远不要弹出它。当您将 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,它只是从代码sn-p所在的函数返回指针,所以没问题。关于push,你是对的,实际上 push 将 esp 减少到 4 个字节,所以我应该添加 4 个字节而不是 2 个。我会更好地使用寄存器,推送适当的值,啊,等等。我对 asm 有点陌生。
最近更新 更多