c++ - WinDbg 在堆上查找所有不使用继承的 X 类型的 C++ 对象(无 vftable)
问题描述
我有一个带有调试符号的 C++ 应用程序,并创建了一个启用了所有相关 gflags 的此类应用程序的转储文件:
gflags /i xxx.exe +hpa
gflags /i xxx.exe +ust
现在,我从其他问题(见这里)中发现,首先寻找一个类型的 vftable 地址:
x module!SomeClass*table*
然后在堆中搜索该地址:
!heap -srch 'address_of_vtable'
我可以找到该类型的所有实例。这是真的,如果 vftable 存在这种类型。
根据我的阅读,vftable 只为使用继承的类型创建,但如果一个类型根本不使用继承,那么它就不会被创建。
如果未创建 vftable,则上述方法似乎不起作用。我可以使用(无 vftable)找到该类型的地址:
x module!SomeClass::SomeClass
但是,如果我在堆中搜索返回的地址,则没有匹配项,尽管我知道我有几个这种类型的实例。
其他人所做的是强制创建 vftable,但是为了调试而以这种方式修改代码库对于现有的大型代码库来说似乎不是一个好的或实用的方法。
有没有一种方法,结合 windbg 命令,在转储文件中查找(非继承)类型的实例而无需修改源代码?
注意:我知道还有其他用于堆分析的工具,例如 umdh 和带有 WPR 的堆快照,但我假设我只有一个常规的、完整的、好的老式转储。所有堆信息都在那个转储中,有符号和来源,所以一定有办法,对吧?
解决方案
鉴于可以从随机字节创建对象(只要满足对齐要求),不可能说某些随机字节集合是否属于任何特定类型。即使在存在与 vtable 指针匹配的值的情况下,这只是一个非常强的提示而不是确凿的证据。毕竟,无论出于何种原因,都有可能拥有一个恰好具有与 vtable 的地址匹配的值的整数成员。
鉴于这一现实,我想说甚至无法猜测没有 vtable 匹配值的字节集合的类型。
推荐阅读
- intellij-idea - IntelliJ Ktor 和 Docker 有没有更好的方法?
- terraform - 在通用数据过滤器上使用 terraform_remote_state
- c# - CustomAttribute:如何设置 DateTime.Now
- sql - 将数据类型为 NUMBER 的单个列的值连接或连接为 Oracle 中的单个字符串
- angular - 在 NGRX 8 和 Angular 中定期调度操作
- php - 多维PHP数组数组到HTML表格问题
- javascript - 当光标聚焦时如何停止我的滑块
- python - 仅当特定时间在 Python 中以 x 开头时如何打印
- javascript - 在 .forEach() 循环中调用唯一的随机值
- postgresql - 如果我在 PostgreSQL 中使用非 ASCII 字符作为 ENUM 值会有所不同吗?