吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 10240|回复: 6
收起左侧

[调试逆向] winDBG调试跨模块释放Bug

  [复制链接]
goodboy_wkx 发表于 2017-12-4 13:36
本帖最后由 goodboy_wkx 于 2017-12-4 13:47 编辑

1      概述
打开windbg附加待调试程序再F5运行。之后程序发生异常而中断。Windbg捕捉到了主进程的的异常信息。异常信息格式为:
image1.jpg
  图1
1中第1行的调试信息表明堆管理器检测到了DLL_Test.exe进程在调用RtlfreeaHeap从堆0x00240000上释放堆块0x001A3480(用户指针)时指定的地址参数非法。第2行信息表明应用程序是因为断点异常而中断到了调试器,其中(8e8.540)DLL_Test.exe的进程ID和线程ID。事实上,这是堆管理器检测到错误情况并判断当前进程是被调试后故意触发了断点异常。


2      Bug重现
在分析bug的过程一般会有下面4步:定位bug类型、定位bug位置、分析bug成因、解决bug方案。


2.1  定位bug类型
步骤1打开windbgctr+E选择一个要调试的程序。(注意使用!heap命令需要加载ntdll的符号)
步骤2WINdbg命令输入窗口中输入g命令运行起来。WINdbg将会捕捉到异常如图2
image2.jpg
2
通过图2,从提示信息中可知,程序在从堆区(00c50000)中释放用户指针(00ca3480)时发生异常。
注:堆块的释放过程。堆管理器在指定的堆区(如00c50000)寻找要释放的堆块(如00ca3480所在的堆块),如果找到则将该堆区的堆块的状态改成空闲状态然后将该堆块添加到堆区的空闲链表中;如果没有找到则触发异常。
步骤3执行!heap –x 00ca3480命令。可以看到00ca3480指针位于00ca0000堆区的00ca3478堆块上。
注:00ca3478是堆块的入口地址;00ca3480用户使用的指针如newmalloc函数返回的地址;00ca0000是所属堆区的地址。到这里可以确定该bug属于内存释放异常中的跨模块释放bug

2.2  定位bug位置
步骤4执行k命令。查看函数调用栈,通过栈回溯的方法来找到触发异常的指针是从哪里来的。
image3.jpg
3
用户模式下在最近的一个函数是DLL_Test!free。而DLL_Test!free要释放的指针是由DLL_Test!MyTestFunction函数给他传递的。所以导致异常的函数在DLL_Test!MyTestFunction函数中且位于0118188e的上一条指令及call DLL_Test!free
步骤5执行ub 0118188eL20.如图4.

   image4.png
4
结合图3,可知函数DLL_Test!operatordelete就是DLL_Test!free函数。且释放的函数指针是从ESP+34h中取出来的。而ESP+34h是在0118183a的位置处赋值的,该位置为一个函数调用即ESP+34h是在DLL_Test!_imp_?getMemberNamesValueJson函数中赋值的。
步骤6 重新调试即重复步骤1. 当程序加载完毕后,执行Bp DLL_Test!MyTestFunction+0xa7DLL_Test!MyTestFunction+0xa7下断点。如图5.
image5.png
5
注:没有使用绝对地址是因为在下次运行时基地址会发生变化。
步骤7到断点位置后执行u012d1817 L20命令查看代码。并在012d183a处下断点。当走到012d183aF8跟进去看一下给ESP+34h赋值的过程。
image6.png
图6
步骤8 直接运行到断点处,并用0:000>dd 002af688查看002af688的内容。
image7.png
图7
跟进getMemberNames函数。getMemberNames中的70dd4f7e位置处是一条all lib_json!std::vector指令。lib_json!std::vector函数会在lib_json模块所属堆中申请一块堆块,并将该堆块的用户指针赋值给ESP+34h
image8.png
图8
到这里就可以清楚的认识到问题的原因了即,ESP+34h的指针指向的位置是json模块申请的堆块,而且这个堆块属于json模块的堆,但在释放的时候是DLL_Test.exe中的free函数释放的,而DLL_Test.exe中的free函数只能释放属于DLL_Test.exe模块的堆中的堆块。


2.3  解决bug方案
json!getMemberNames函数中申请,并且在json模块再提供一个释放接口。DLL_Test.exe使用一个指针去接受json!getMemberNames返回的数据,使用完后调用json模块提供的释放接口进行释放。这样申请和释放都在json模块中了,就不会出现跨模块释放的问题了。
时间有限后续再补充MT与跨模块之间的关系。

免费评分

参与人数 4威望 +2 吾爱币 +13 热心值 +4 收起 理由
贝优妮塔 + 1 + 1 呜呜呜 看懂了一点点
sunnylds7 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Three_fish + 1 + 1 谢谢@Thanks!
Hmily + 2 + 10 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

yssun 发表于 2017-12-5 09:33
不觉明历啊
gongyong728125 发表于 2017-12-5 09:41
学写了楼主,我最近系统spoolsvc.exe老是一打印就报错,不知道为什么,你遇到类似的情况没有?有没有好的解决办法
 楼主| goodboy_wkx 发表于 2017-12-5 09:52
gongyong728125 发表于 2017-12-5 09:41
学写了楼主,我最近系统spoolsvc.exe老是一打印就报错,不知道为什么,你遇到类似的情况没有?有没有好的解 ...

首先,您说描述的信息有限不能有针对性的做出回答。
下面是我找到的一些解决方法。
https://jingyan.baidu.com/article/c843ea0b64fc4a77931e4a11.html

有可能是电脑中毒了(不确定)。您可以将spoolsv.exe上传到www.virustotal.com看一下。
寒尘丶Coldust 发表于 2017-12-5 22:21
仰望大牛
任国富 发表于 2017-12-6 08:07
感谢大神分享,谢谢!
greenmor 发表于 2018-10-13 23:46
学习调试中~windbg好强大,楼主神剖解~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 13:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表