卸载riched20导致崩溃

0x00

在公司的crash平台上发现每天都存在调用ClipBoard函数时发生崩溃。
函数最终崩溃在 ole32! RemoveClipboardDataObject 中。简易流程如下:
pData = (IDataObject *)GetPropW(hClipWnd, L"ClipboardDataObjectInterface");
__guard_check_icall_fptr(pData->vfptr->Release);
由此可见 pData对应的对象应该是已经被释放到,导致调用 Release 函数出错。

0x01

我们知道,对于虚函数表来说,当image被编译出来以后,它的内容就存在于image的某处。当image被加载到进程地址空间以后,new出的对象会动态更新其虚函数表的指针,指向这些虚表。
由此我们可以根据访问的地址(pData->vfptr 的地址)定位到对应的image与对应的虚表内容。
1、 假设pData->vfptr地址为 x;
2、 Windbg中执行 lm 命令,查看x落在哪个module地址空间内(这里最好不要直接使用ln命令,以为module可能已经被卸载了);
3、 找到对应的module后,假设起base addr为y;
4、 通过 x – y可以得到虚表在Image内的偏移;
5、 打开IDA,分析对应的image,找到实际的虚表内容,确定当前pData指向的对象的实际类型。

0x02

在本例中,问题的原因是当我们使用richedit并且编辑复制时,ole32可能会将riched20.dll中的对象通过 SetPropW 保存到 ClipWnd 中。当外部调用EmptyClipBoard或者其他函数导致ole32的RemoveClipboardDataObject被调用时,ole32会取出当前ClipWnd中保存着的riched20.dll的对象,并调用其Release函数。如果riched20.dll被提前卸载,则客户端崩溃。
检查了下代码,发现某个模块会在特定情况下加载卸载 riched20.dll,试了几把,可以重现问题。

0x03

系统模块间的关系看起来比我们想象的复杂的多,对待系统模块的加载卸载还是要谨慎一点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值