好友
阅读权限20
听众
最后登录1970-1-1
|
本帖最后由 goodboy_wkx 于 2017-12-4 13:47 编辑
1 概述
打开windbg附加待调试程序再F5运行。之后程序发生异常而中断。Windbg捕捉到了主进程的的异常信息。异常信息格式为:
图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:打开windbg,ctr+E选择一个要调试的程序。(注意使用!heap命令需要加载ntdll的符号)
步骤2:在WINdbg命令输入窗口中输入g命令运行起来。WINdbg将会捕捉到异常如图2。
图2
通过图2,从提示信息中可知,程序在从堆区(00c50000)中释放用户指针(00ca3480)时发生异常。
注:堆块的释放过程。堆管理器在指定的堆区(如00c50000)寻找要释放的堆块(如00ca3480所在的堆块),如果找到则将该堆区的堆块的状态改成空闲状态然后将该堆块添加到堆区的空闲链表中;如果没有找到则触发异常。
步骤3:执行!heap –x 00ca3480命令。可以看到00ca3480指针位于00ca0000堆区的00ca3478堆块上。
注:00ca3478是堆块的入口地址;00ca3480用户使用的指针如new、malloc函数返回的地址;00ca0000是所属堆区的地址。到这里可以确定该bug属于内存释放异常中的跨模块释放bug。
2.2 定位bug位置
步骤4:执行k命令。查看函数调用栈,通过栈回溯的方法来找到触发异常的指针是从哪里来的。
图3
用户模式下在最近的一个函数是DLL_Test!free。而DLL_Test!free要释放的指针是由DLL_Test!MyTestFunction函数给他传递的。所以导致异常的函数在DLL_Test!MyTestFunction函数中且位于0118188e的上一条指令及call DLL_Test!free。
步骤5:执行ub 0118188eL20.如图4.图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+0xa7在DLL_Test!MyTestFunction+0xa7下断点。如图5.
图5
注:没有使用绝对地址是因为在下次运行时基地址会发生变化。
步骤7:到断点位置后执行u012d1817 L20 命令查看代码。并在012d183a 处下断点。当走到012d183a 时F8 跟进去看一下给ESP+34h 赋值的过程。
图6
步骤8: 直接运行到断点处,并用0:000>dd 002af688 查看002af688 的内容。
图7
跟进getMemberNames 函数。在getMemberNames 中的70dd4f7e 位置处是一条all lib_json!std::vector 指令。lib_json!std::vector 函数会在lib_json 模块所属堆中申请一块堆块,并将该堆块的用户指针赋值给ESP+34h 。
图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与跨模块之间的关系。 |
免费评分
-
查看全部评分
本帖被以下淘专辑推荐:
- · 学习及教程|主题: 1126, 订阅: 1118
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|