【问题标题】:Question about CALL statement关于 CALL 语句的问题
【发布时间】:2011-01-04 04:19:22
【问题描述】:

我在 VC++ 中有以下代码

Func5(){ StackWalk(); }
Func4{ Func5();}

我是 x86 汇编语言的初学者。我试图找出 Func5() 的起始地址。我从它的堆栈帧中得到 Func5() 的返回地址。现在在这个返回地址之前应该有一个 CALL 语句。所以我提取了返回地址之前的字节。

有时就像E8 ff ff ff d8 这样的近距离通话。所以对于这个语句,我从函数的返回地址中减去偏移量 0x28 得到 Func5() 的基地址(它驻留在内存中的位置)。

问题是我不知道如何为间接 NEAR 调用计算此值。一段时间以来,我一直在尝试找出如何做到这一点。所以我提取了返回地址前的前 5 个字节,它们是 ff 75 08 ff d2 我认为这代表 CALL ECX (ff d2) 但我不确定。

如果有人能告诉我这是什么类型的 CALL 语句以及我如何从这种调用中计算函数的基地址,我将不胜感激。

【问题讨论】:

    标签: assembly


    【解决方案1】:

    要反汇编,最简单的方法是使用反汇编器。

    假设 32 位 80x86,NDISASM 说“ff 75 08 ff d2”是:

    00000000  FF7508            push dword [ebp+0x8]
    00000003  FFD2              call edx
    

    在这种情况下,函数的地址将在 EDX 寄存器中。

    【讨论】:

    • 能否推荐一个适用于 Windows 的调试器。
    • 我已经有 8 年没有使用 Windows 进行软件开发了,所以我认为我不是询问 Windows 调试器的最佳人选。当我以前使用 Windows98 时,我使用的是 NASM/NDISASM。现在我在 Linux 上完成所有开发工作,我仍在使用 NASM/NDISASM(但我的大部分工作是原始二进制文件,而不是 Windows/PE 文件)。
    • 只是一个快速的额外说明 - 出于学习汇编的目的,我可能会推荐某种交互式调试器(可以让您在“单- step”或一次执行一条指令)。
    • 我发现了另一个CALL指令FF 15 34 73 58 00。这是否意味着跳转到地址0x00587334?
    • 这将是“在 [dword 0x00587334] 附近调用 dword”,其中地址 0x00587334 处的内存包含要调用的例程的地址。
    【解决方案2】:

    告诉编译器和链接器生成详细的映​​射文件。我不知道最近的版本,但以前可以请求链接的汇编语言转储,包括操作码。

    【讨论】:

      猜你喜欢
      • 2010-12-09
      • 1970-01-01
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-18
      相关资源
      最近更新 更多