????优质资源分享????
???? Python实战微信订餐小程序 ???? | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
????Python量化交易实战???? | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
讲故事
最近遇到一位朋友的程序崩溃,发现崩溃点在富编辑器msftedit上,这个不是重点,重点在于发现他已经开启了页堆,看样子是做了最后的挣扎。
0:000> !analyze -v
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 82779a9e (msftedit!CCallMgrCenter::SendAllNotifications+0x00000123)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000001
Parameter[1]: 8351af28
Attempt to write to address 8351af28
...
STACK_TEXT:
00ffe0dc 827bda2a 8351ae88 00000000 00ffe174 msftedit!CCallMgrCenter::SendAllNotifications+0x123
00ffe110 827bd731 00ffe324 00ffe174 00ffe300 msftedit!CCallMgrCenter::ExitContext+0xda
00ffe120 827bde71 8351ae88 827232dc 28112f80 msftedit!CCallMgr::~CCallMgr+0x17
00ffe300 8290281f 00000102 00000067 00220001 msftedit!CTxtEdit::TxSendMessage+0x201
00ffe374 7576110b 00f20268 00000102 00000067 msftedit!RichEditWndProc+0x9cf
00ffe3a0 757580ca 82901e50 00f20268 00000102 user32!_InternalCallWinProc+0x2b
...
SYMBOL_NAME: system_windows_forms+1c45e7
MODULE_NAME: System_Windows_Forms
IMAGE_NAME: System.Windows.Forms.dll
0:000> !heap -p
Active GlobalFlag bits:
vrf - Enable application verifier
hpa - Place heap allocations at ends of pages
StackTraceDataBase @ 04c20000 of size 01000000 with 00001b18 traces
PageHeap enabled with options:
ENABLE_PAGE_HEAP
COLLECT_STACK_TRACES
active heaps:
+ 5c20000
ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
NormalHeap - 5d90000
HEAP_GROWABLE
+ 5e90000
ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
NormalHeap - 4960000
HEAP_GROWABLE HEAP_CLASS_1
...
对页堆的研究
案例演示
为了方便讲述,先上一段测试代码。
int main()
{
HANDLE h = HeapCreate(NULL, 0, 100);
int* ptr = (int*)HeapAlloc(h, 0, 9);
printf("ptr= %x", ptr);
DebugBreak();
}
接下来用gflags开启下页堆。
PS C:UsersAdministratorDesktop> gflags -i ConsoleApplication1.exe +hpa
Current Registry Settings for ConsoleApplication1.exe executable are: 02000000
hpa - Enable page heap
然后将程序跑起来,可以看到返回的handle句柄。
页堆布局研究
接下来用windbg的!heap-p命令观察页堆。
0:000> !heap -p
Active GlobalFlag bits:
hpa - Place heap allocations at ends of pages
StackTraceDataBase @ 042e0000 of size 01000000 with 0000000e traces
PageHeap enabled with options:
ENABLE_PAGE_HEAP
COLLECT_STACK_TRACES
active heaps:
+ 5b0000
ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
NormalHeap - 710000
HEAP_GROWABLE
+ 810000
ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
NormalHeap - 510000
HEAP_GROWABLE HEAP_CLASS_1
+ 56e0000
ENABLE_PAGE_HEAP COLLECT_STACK_TRACES
NormalHeap - 5aa0000
HEAP_CLASS_1
稍微解读下上面的输出。
+56e0000**
表示页堆的堆句柄。
NormalHeap-5aa0000
表示页堆关联的NT堆,可能有朋友要问了,既然都开启页堆了,还要弄一个ntheap干嘛?大家不要忘了,windows的一些系统api会用到这个堆。
接下来有一个问题,如何观察这两个heap之间的关联关系呢?要回答这个问题,需要了解页堆的布局结构,画个简如下:
从中可以看到,离句柄偏移4k的位置有一个DPH_HEAP_ROOT结构,它相当于NTHEAP的_HEAP,我们拿56e0000举个例子。
0:000> dt nt!_DPH_HEAP_ROOT 56e0000+0x1000
ntdll!_DPH_HEAP_ROOT
...
+0x0b4 NormalHeap : 0x05aa0000 Void
+0x0b8 CreateStackTrace : 0x042f4d94 _RTL_TRACE_BLOCK
+0x0bc FirstThread : (null)
上面输出的NormalHeap:0x05aa0000就是它关联的ntheap句柄。
堆块布局研究
对页堆有了一个整体认识,接下来继续研究堆块句柄,我们发现ptr=0x56e5ff0是落在56e0000这个页堆上,接下来我们导出这个页堆的详细信息。
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点