代码之家  ›  专栏  ›  技术社区  ›  Lucas Martins

远程调用将错误的IP推送到堆栈

  •  0
  • Lucas Martins  · 技术社区  · 7 年前

    当我使用virtualbox以实模式运行以下代码时,我希望 call 0x9000:foo 将CS和IP寄存器推送到堆栈的指令。但是,当我在far调用之后查看调用堆栈(在virtualbox的调试器中)时,返回地址设置为 9000:000006c6 而不是 9000:0000078c ,显然是一个任意地址。

    如果使用近调用,则调用堆栈中的返回地址设置正确。

    我正在用NASM进行组装,并在virtualbox上以x86实模式运行代码。

    我知道在这个例子中我不需要一个远程调用,但是在代码的另一部分中我需要它。

    9000:00000787    call 0x9000:foo
    9000:........    ...
    9000:00003bac    push bp  ; foo:
    9000:........    ...
    9000:00003bf0    retf
    

    我的问题是:

    是否可以使用far调用调用当前段中的函数?

    在调用堆栈中是否存在错误返回地址的已知原因?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Michael Petch    7 年前

    我建议不要使用 kg k 要在virtualbox的调试器中遍历调用堆栈,除非您在设置函数的stackframe的函数序言之后跨到某个点:

    push bp 
    mov bp, sp
    

    在某些代码中,这是使用等价的 ENTER 指令。

    virtualbox的调用堆栈转储程序遍历堆栈,这要求将bp设置为当前堆栈帧。如果在输入函数后立即停止,则应考虑如下命令 dw ss:sp 这将把当前堆栈指针位置的数据原始转储为16位字。如果进行近调用,则打印的第一个字应该是要返回的偏移量,如果进行远调用,则偏移量将首先跟随要返回的段。


    注意:我的经验是,调用堆栈是被遍历的,假设已经执行了一个远调用来访问函数,那么一个近调用可能不会生成一个正确的调用堆栈跟踪。

    推荐文章