重复delete 对象指针后的 异常调用栈怪异 解析

科技资讯 投稿 5800 0 评论

重复delete 对象指针后的 异常调用栈怪异 解析

0:000> kb
 # ChildEBP RetAddr      Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
00 0019eb94 76124f2f     00c3afc8 0019ebdc 0019ebb8 0x8c73d01
01 0019ebdc 0079451a     00c3afc8 73d82ec0 00000001 USER32!IsZoomed+0xaf
02 0019ebe4 73d82ec0     00000001 73d35d1c 00c3afc8 JXC_MED!CMainFrame::`scalar deleting destructor'+0x8
03 0019ebec 73d35d1c     00c3afc8 00000000 73d35c0f MFC42!CControlFrameWnd::PostNcDestroy+0xb
04 0019ec2c 73d31e1d     00c3afc8 00c3afc8 00cae670 MFC42!CWnd::OnNcDestroy+0x10d
05 0019eca4 73d31b07     00000082 00000000 73dca448 MFC42!CWnd::OnWndMsg+0x2f4
06 0019ecc4 73d31a78     00000082 00000000 00000000 MFC42!CWnd::WindowProc+0x22
07 0019ed24 73d319d0     00c3afc8 00000000 00000082 MFC42!AfxCallWndProc+0x91
08 0019ed44 73dbe00c     00031002 00000082 00000000 MFC42!AfxWndProc+0x34
09 0019ed70 76135cab     00031002 00000082 00000000 MFC42!AfxWndProcBase+0x39
0a 0019ed9c 761267bc     73dbdfd3 00031002 00000082 USER32!_InternalCallWinProc+0x2b
0b 0019ee80 7612635a     73dbdfd3 00000000 00000082 USER32!UserCallWinProcCheckWow+0x3ac
0c 0019eee4 76133f87     01225f90 00000000 00000082 USER32!DispatchClientMessage+0xea
0d 0019ef28 77e62add     0019ef44 00000020 0019efac USER32!__fnNCDESTROY+0x37
0e 0019ef60 73d364c5     00031002 009a034c 009a1f14 ntdll!KiUserCallbackDispatcher+0x4d
0f 0019ef74 00794760     009a8968 00000000 00c3afc8 MFC42!CWnd::DestroyWindow+0x31
10 0019efb8 73d38fb4     00c3afc8 00c3afc8 00794965 JXC_MED!CMainFrame::DestroyWindow+0x13c [MainFrm.cpp @ 852] 
11 0019efd0 02b056f3     00000000 00794a45 00c3afc8 MFC42!CFrameWnd::OnClose+0xf5
12 0019efec 007949a3     00000000 73dca64c 00000001 ToolLib!CTFrameWnd::OnClose+0x13
13 0019f044 73d31e1d     00c3afc8 00c3afc8 00cae670 JXC_MED!CMainFrame::OnClose+0x3e [MainFrm.cpp @ 1133]

顶层两个函数调用帧都是错的,地址怪异,没有函数名子通过反汇编校验,根据帧返回地址是 0079451a 判断出具体函数源码位置, 不及格的程序员-八神

JXC_MED!CMainFrame::`scalar deleting destructor': 00794512 56 push esi 00794513 8bf1 mov esi, this (ecx 00794515 e814000000 call JXC_MED!CMainFrame::~CMainFrame (79452e //顶层栈实际上是在调用此析构函数中的代码 0079451a f644240801 test byte ptr [esp+8], 1 0079451f 7407 je JXC_MED!CMainFrame::`scalar deleting destructor'+0x16 (794528 00794521 56 push esi 00794522 e8338c0000 call JXC_MED!operator delete (79d15a 00794527 59 pop this (ecx 00794528 8bc6 mov eax, esi 0079452a 5e pop esi 0079452b c20400 ret 4 JXC_MED!CMainFrame::~CMainFrame: 0079452e b806828200 mov eax, 828206h 00794533 e8489b0000 call JXC_MED!__EH_prolog (79e080 00794538 51 push this (ecx 00794539 51 push this (ecx 0079453a 56 push esi 0079453b 8bf1 mov esi, this (ecx 0079453d 57 push edi 0079453e 8975f0 mov dword ptr [ebp-10h], esi 00794541 c70668a98800 mov dword ptr [esi], 88A968h 00794547 8b8e58040000 mov this (ecx, dword ptr [esi+458h] 0079454d c745fc06000000 mov dword ptr [ebp-4], 6 00794554 85c9 test this (ecx, this (ecx 00794556 7407 je JXC_MED!CMainFrame::~CMainFrame+0x31 (79455f 00794558 8b01 mov eax, dword ptr [this(?? (ecx] //通过指令飞越技术查出是这里出错,代码对应 delete loadWareWork; 0079455a 6a01 push 1 0079455c ff5004 call dword ptr [eax+4] 0079455f a150889a00 mov eax, dword ptr ds:[009A8850h] 00794564 83780400 cmp dword ptr [eax+4], 0 00794568 741f je JXC_MED!CMainFrame::~CMainFrame+0x5b (79458900794623 c3 ret

CMainFrame::~CMainFrame(
{
    if(loadWareWork delete loadWareWork; //这个被重复删了 导至出错
    if (gpDb->IsOpen(
    {
        WriteOpLog(gpDb, gstrOprCode, GSP_OPLOG_MODULEID, "2", "退出系统"; 
    }
}

图1:指针飞越技术重现@eip内存地址 0x8c73d01

创建时使用WS_CHILD类型创建,它会随着父窗体自动DESTORY,并且子类重载函数 PostNcDestroy 并 delete this了,不需要这里再次delete。

 

编程笔记 » 重复delete 对象指针后的 异常调用栈怪异 解析

赞同 (26) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽