WinDbg查看函数参数

在使用Windbg给一个函数下断点后,函数被中断时,我们经常需要查看函数的参数是什么。通常函数被中断的时机发生在,参数已经被压栈了,执行 call指令(当前EIP被压栈,然后EIP被填充为被调用函数的地址)。此时函数参数已经被压栈了,因此为我们在函数中断时查看函数参数提供了可能。通 常有两种方法查看函数参数,下面以调试记事本打开文件使用的CreateFile函数为例说明。
首先给CreateFile函数下断点,然后使用记事本打开一个txt文件,会发现立即被中断了。
 
查看参数的最简单的方法就是使用kb命令。k系列命令是查看函数的栈帧,即调用堆栈的命令,其中kb命令查看Windbg帮助的解释是在栈回溯中显示传给函数的前三个参数(Displays the first three parameters that are passed to each function in the stack trace. )。因此使用kb命令列出当前函数的调用堆栈,如下图:
 
其中ChiledEbp是函数的基址指针,RetAddr是函数的返回地址,我们需要关注的就是后三列,即函数的前三个参数。在这里可以看出分别是0007fbb0、800000000、00000003。查看MSDN可知,第二个参数是dwDesiredAccess值是80000000即GENERIC_READ,第三个参数dwShareMode是FILE_SHARE_READ | FILE_SHARE_WRITE,现在我们重点来瞅瞅第一个参数,我们知道CreateFileW的第一个参数是LPCWSTR,是个指针,因此我们使用du查看内存上Unicode的值,如下图:
 
可以看出,第一个参数恰好是我们要打开的文件。
看到这里也许会问,那使用kb命令只能查看前三个参数,那如何查看更多的参数呢?前面我们有说过,断点断下来的时机发生在函数参数压栈后,call 指令已经执行,但还没有执行被调用函数的命令的时候,此时EIP已经指向了将要执行的下一条指令,即被调用函数的第一条指令。我们查看EIP的内容,并反 汇编这个地址,
 
下一条指令的地址是0x7c810800,指令是mov edi, edi。另外我们再想到,ESP寄存器是栈顶指针,总是指向栈顶,那么此时栈的结构是什么样的,可不可以通过ESP来访问栈中参数的内容,肯定可以,而且 此时的时机也是非常好的。我们之前说过call指令有一个隐含的动作就是把将要返回的地址也压入栈中,因此此时ESP恰好是指向这个地址的,而之前的动作 就是压栈,通常是反序压栈。因此ESP+4即是第一个参数的地址,ESP+8是第二个参数的地址,依次类推……说了这些,我们可以看看这时内存上的数据:
 
看图的确和我们刚才说的一样吧,这样就可以看到全部7个参数的内容了。