|
文件: |
windbg.rar |
大小: |
0KB |
下载: |
下载 | |
1. 高地址到物理地址的转化
a>> 随便找一个cr3都ok,且转到为的物理地址都一致.
2. 共享内存是什么?
a>> 一个进程的地址空间中的页面,分为free,reserved,commit。
另外commit的页面分为share,private,或者mapped(该内存区可能被其他进程映射了,或者没有).
内存管理器中用以实现共享内存的是内存区对象也成为file mapping object。
共享内存的原理就是,多个进程可以共享同一块物理内存,而它们在各自进程内的地址依然是私有的。
据个例子来说,多个进程同时加载一个dll,那么实际上此dll的代码页面将被自动共享,即加载到物理内存后,被各个不同的进程映射访问。
内存区对象并不==共享内存,当内存区对象连接到一个磁盘文件时候成为映射文件;连接到内存时候便可提供共享内存。
从实现来说,CreateFileMapping 如果传入INVALID_HANDLE_VALUE 则表示将创建一个连接到内存的内存区对象,而其他进程就可以通过OpenFileMapping 来打开此内存区对象,同时将其map到本身的地址空间中。
至于这个mapviewoffilemapping的过程,大致可以推断:
1) 保留一个连续的地址空间
2) 将进程的页表修改或者添加,使得刚保留的虚拟地址解释指向此特定的物理地址
3. m_spUACMgr->Init crash,显示访问违规来说说vtable的调试。
这个问题是玉堂反映给我的,即玉堂在某些时候第二次运行release编译, 偶尔出现如题所示的crash,从msvc报告的call stack来看,uac.dll符号没有匹配,初步判断就已经知道这个dll应该有问题。
不过为了说明vtable的调试技巧,还是说明一下一个正常的vtable如何debug。
第一种方式:
1. 先以debug模式用windbg运行aliim.exe ,然后在 uacclient!cuacagent::start设置断点,可以用bu设置unresolved bp,即bu uacclient!cuacagent::start 。
也可以如下设置源码行断点如果有条件
0 eu 0001 (0001) (@@masm(`UACAgent.cpp:406+`))
1 eu 0001 (0001) (uacclient!cuacagent::start)
2. windbg中g运行
3. 断点命中。
4. 单步到通过pr , 注意到了init这行之后关闭source code模式,进入汇编调试模式。
具体可参见windbg.rar 文件中的记录,大体来说通过观察vtable的,本文中的init方法是
IUACMgr的一个方法,由于此接口集成字idispatch,后者集成自iunknown,所以它实际是第7个方法。
offset vtalbe + 1ch.
第二种方式
1. 在release模式下调试,同上
参见windbg_release.rar
|
文件: |
windbg_release.rar |
大小: |
1KB |
下载: |
下载 | |
因此这儿有个总结,即这类vtable的问题debug的时候,不妨先定位vtable,如果无法定位则可参考一份你认为比较好debug的release来参考,即通过正确的代码来观察正确的执行途径。
那么当你debug本问题中开始的那个old uac.dll时候你很快就发现vtable是错误的。因此offset vtalbe+1ch也不似IUACMgr::Init的方法的地址
阅读(507) | 评论(0) | 转发(0) |