如何在WinDBG中获取.fnret命令所需的函数地址?
解决WinDBG中
.fnret命令的地址获取问题 我来帮你梳理下.fnret命令的正确用法和地址获取方式——你遇到的错误本质是用错了地址类型,.fnret需要的是函数的入口地址,而不是函数内部的指令地址或者调用栈里的返回地址。
一、获取正确地址的命令
要获取apphelp!ApphelpCheckRunApp的正确入口地址,你可以用以下任意一个命令:
x apphelp!ApphelpCheckRunApp:直接列出该符号对应的内存地址,输出会类似77b34000 apphelp!ApphelpCheckRunApp,这里的77b34000就是函数入口。u apphelp!ApphelpCheckRunApp L1:反汇编函数的第一行指令,输出开头的地址就是入口(比如77b34000 push ebp,77b34000就是入口)。ln @eip:当断点触发在函数内部时,执行这个命令可以查看当前指令所属的函数信息,输出里的begin对应的地址就是函数入口(比如(77b34000))。
二、断点处未显示目标地址时的处理
如果断点触发后,WinDBG没有直接显示目标函数的入口地址(比如符号加载不完整,或者断在函数深处),你可以:
- 用
kb命令查看调用栈,找到apphelp!ApphelpCheckRunApp对应的栈帧,帧首的地址就是函数入口; - 执行
!ip2md @eip,这个命令会输出当前指令所属模块的函数信息,其中FunctionStart字段就是入口地址。
三、地址的可用性验证
用上述方法获取的函数入口地址,完全可以正常用于.fnret或.fnret /s命令。举个实际操作的例子:
- 先获取入口地址:
x apphelp!ApphelpCheckRunApp→ 得到77b34000 - 执行
.fnret 77b34000,此时WinDBG会正确解析该函数的返回类型和返回值相关信息,不会再报错。
为什么之前的地址会报错?
你之前用的两个地址都不符合要求:
- 断点触发后的
77b345d5是函数内部的某条指令地址,不是函数起始点,.fnret无法从这个位置识别函数的返回类型定义; - 调用栈里的返回地址
7c818cdf是调用者的指令地址,和当前函数的返回类型完全无关,自然报错。
内容的提问来源于stack exchange,提问作者odin23
相关产品推荐
相关产品推荐

