如何在汇编中创建一个 dumpRegisters PROC?

How to create a dumpRegisters PROC in assembly?

我正在创建一个程序来显示名为 dumpRegisters 的寄存器。寄存器需要与调试器中寄存器 window 中显示的内容相匹配(使用 Visual Studio)。调试器window中的寄存器有:EAX、EBX、ECX、EDX、ESI、EDI、EBP、ESP、EIP、EFL。总共 10 个寄存器。

我知道欧文图书馆已经有了这个程序,但我是从头开始创建的。

我可以显示大部分寄存器。但是,我正在为如何显示 ESP(扩展堆栈指针)寄存器而苦恼?

我在整个程序中使用push和pop,所以当我调用一个showRegister过程时,它输出了那个点的ESP,但是ESP不断变化,所以当程序退出时,我显示的ESP不是相同的。我试过 push 和 pop esp,但是,它仍然不匹配,这取决于我 push 和 pop esp 的位置,有时它也只显示前 4 个寄存器。

如何让 ESP 寄存器与调试器中的寄存器 window 相匹配?

dumpRegisters PROC
    push eax
    push edx
    mov edx, OFFSET essp
    mov eax, esp
    INVOKE showRegister, OFFSET essp, esp
    pop edx
    pop eax
dumpRegisters ENDP
showRegister PROC,
                regName:PTR BYTE , regValue:DWORD

    ;push esp

    call writeString
    call writeHex
    Tab
    
    ;pop esp 

    ret
showRegister ENDP

打印或保存其他传入参数后,计算推入 4 字节 return 的 call dumpRegsiters(打字错误?)之前 必须是什么 ESP ] 地址,加上您所做的任何其他推送。

lea eax, [esp+12]按2次后应该是正确的。

您可能应该从 pushf 开始以先保存 EFLAGS,这样您就可以使用修改 FLAGS 的指令,例如 addsub。然后当然相应地调整你的偏移量。除非事实证明 Irvine32 的功能类似于 WriteHex save/restore EFLAGS 本身,否则您可能只是在处理传入数据。

您甚至可以从 pusha 开始并循环弹出和打印,如果您不需要打印带有值的寄存器名称。该指令为数不多的 use-cases 之一,尽管您可能仍想计算 ESP 而不是使用它推送的内容。

(我猜想从你的 return 地址获取 EIP,如果你不介意在 电话之后有地址 。如果你想要之前的地址,你必须弄清楚它是一个 5 字节 call rel32,还是通过像 2 字节 call eax 这样的函数指针调用。)