如何在 WinDBG 中显示 .fnret 命令的函数地址?

How to display the address of the function in WinDBG for .fnret command?

我需要获取WinDBG中.fnret命令所需函数的地址。 例如,我想获取有关 apphelp!ApphelpCheckRunApp 函数的 return 值的信息。 首先,我在这个函数上设置了一个断点:

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'

我还使用了来自调用堆栈的此函数的 return 地址 7c818cdf(通过 kb 命令获得):

ChildEBP RetAddr  Args to Child
0283ce8c 7c818cdf 00000474 046bb7d0 00000000 appHelp!ApphelpCheckRunApp

但它导致我犯同样的错误。

我应该为此使用哪个 WinDBG 命令以及它将显示哪个 return 地址(以防断点处尚未显示)?然后它会正确地用于 .fnret.fnret /s 命令吗?不幸的是,MSDN 上没有任何使用它们的示例,只有文档。

希望得到您的帮助。提前致谢。

.fnret 仅在您拥有私有 pdb
时才有用 如果你有 public 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

使用 public 剥离的 pdbreturns 句柄的已知函数出错

0:000> .fnret KERNELBASE!CreateFileA
                                   ^ Unknown or unsupported return type in '.fnret KERNELBASE!CreateFileA'

使用私有 pdb 在系统文件上成功 它将在@rax 中转储的强制 return 值转换为类型化 return,其值是具有类型信息

的函数

带有私有 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???"

好的,在使用 public PDB 时,该命令确实一点用处也没有。 我在这里找到了更好的解决方案:How to get return value from a function in windbg?.

可以通过使用r命令适当地查看x86/x64上的eax/rax寄存器来获取return值的内存地址(因为它总是存储在那里).在断点之后,我只是在 x86 上键入 r eax 或在 x64 上键入 r rax。输出将如下所示:

eax=[Address]

然后,我通过 d*(dd、du 等显示数据类型命令)显示接收到的内存地址的值,如下所示:

du [Address]

查看输出后,return编辑了哪些数据及其数据类型(至少在大多数情况下是这样)就可以理解了。 但首先要了解使用了哪种数据类型,我正在尝试 display memory commands and display referenced memory commands.

的不同组合