我需要在WinDBG 中获取.fnret
命令所需函数的地址。
例如,我想获取有关 apphelp!ApphelpCheckRunApp 函数返回值的信息。
首先,我在这个函数上设置了一个断点:
bp apphelp!ApphelpCheckRunApp
然后我继续执行,直到它在该函数上中断。
中断后,我正在执行 .fnret [Address]
命令。
我已经尝试使用断点上显示的 77b345d5
地址:
Breakpoint 0 hit
eax=77b345d5 ebx=7ed320f5 ecx=7ffac000 edx=7c886920 esi=7ffac000 edi=00000018
eip=77b345d5 esp=0378ce90 ebp=0378d108 iopl=0 nv up ei pl nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000213
appHelp!ApphelpCheckRunApp:
77b345d5 8bff mov edi,edi
但这似乎不是我需要的,因为我收到以下错误:
^ Unknown or unsupported return type in '.fnret 77b345d5'
我还使用了调用堆栈中该函数的返回地址 7c818cdf
(通过 kb
命令获得):
ChildEBP RetAddr Args to Child
0283ce8c 7c818cdf 00000474 046bb7d0 00000000 appHelp!ApphelpCheckRunApp
但这让我犯了同样的错误。
我应该为此使用哪个 WinDBG 命令以及它将显示哪个返回地址(以防它尚未在断点上显示)?那么它是否可以正常用于 .fnret
或 .fnret /s
命令?不幸的是,MSDN 上没有任何使用它们的示例,只有文档。
希望得到您的帮助。提前致谢。
答案 0 :(得分:0)
.fnret 仅在您拥有私有 pdb 时才有用
如果您有公共 pdb 则没有用,因为它需要检索类型信息
这里是使用私有 pdb 编译代码的示例用法
0:000> x /t /v /f myst!towlower
prv func 00007ff6`74ba5f84 7 <function> myst!towlower (unsigned short)
0:000> x /t /v /f myst!toupper
prv func 00007ff6`74b91b10 2a <function> myst!toupper (int)
0:000> .fnret myst!towlower
myst!towlower (00007ff6`74ba5f84) = unsigned short 1
0:000> .fnret myst!toupper
myst!toupper (00007ff6`74b91b10) = int 0n1
使用公共剥离的 pdb 返回 HANDLE 的已知函数出错
0:000> .fnret KERNELBASE!CreateFileA
^ Unknown or unsupported return type in '.fnret KERNELBASE!CreateFileA'
使用私有 pdb 在系统文件上成功 它将 @rax 中转储的强制返回值转换为带有类型信息的函数值的类型化返回
带有私有 pdb 的系统文件
0:000> .printf "%y\n" , 0x00000001`800bace0 ; an arbitrary function
ole32!ToUnicode (00000001`800bace0)
0:000> .printf "%mu\n" , 00000001`8014c17a ; an arbitrary wide string
guageErrorPointerംА
0:000> r rax = 00000001`8014c17a the $retreg is populated with an address of wide string
0:000> .fnret 0x00000001`800bace0 << fnret casts the $retreg as wide string and prints the resulting widestring
ole32!ToUnicode (00000001`800bace0) = wchar_t * 0x00000001`8014c17a
"guageErrorPointer???"
答案 1 :(得分:0)
好的,该命令在使用公共 PDB 时确实没有任何帮助。 我在这里找到了更好的解决方案:How to get return value from a function in windbg?。
可以通过使用 r
命令适当地查看 x86/x64 上的 eax/rax 寄存器来获取返回值的内存地址(因为它总是存储在那里)。断点后,我只是在 x86 上键入 r eax
或在 x64 上键入 r rax
。输出将如下所示:
eax=[Address]
然后,我通过 d*(dd、du 等显示数据类型命令)显示接收到的内存地址的值,如下所示:
du [Address]
查看输出后,就可以理解返回了哪些数据,以及它的数据类型(至少在大多数情况下)。 但首先要了解使用的是哪种数据类型,我正在尝试 display memory commands 和 display referenced memory commands 的不同组合。