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

时间:2021-07-09 15:48:27

标签: windbg

我需要在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 上没有任何使用它们的示例,只有文档。

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

2 个答案:

答案 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 commandsdisplay referenced memory commands 的不同组合。

相关问题