1
我正在嘗試使用WinDbg調試一款名爲「Ballmaster」(其源代碼不具備)的非常古老的遊戲。當顯示對話框時,我將WinDbg附加到遊戲中,以便UI線程的調用堆棧不會更改。WinDbg沒有顯示整個調用堆棧?
這裏是正在運行的線程的列表:
當我點擊Ballmaster
線程,以下調用堆棧,提出:
ntdll!NtDelayExecution + 0xc
KERNELBASE!SleepEx + 0x99
KERNELBASE!Sleep + 0xf
USER31!HookedCreateWindowExA + 0x41
DlgBox!Ordinal49 + 0x35dd
DlgBox!Ordinal49 + 0x4d58
uxtheme!ThemePreDefDlgProc + 0x83
USER32!UserCallDlgProcCheckWow + 0x2a8
USER32!DefDlgProcWorker + 0xc7
USER32!DefDlgProcA + 0x25
USER32!_InternalCallWinProc + 0x2b
USER32!UserCallWinProcCheckWow + 0x2d3
USER32!SendMessageWorker + 0x26c
USER32!InternalCreateDialog + 0xb07
USER32!CreateDialogIndirectParamAorW + 0x35
USER32!CreateDialogIndirectParamA + 0x1b
DlgBox!Ordinal49 + 0x52bf
Ballmaster
是主UI線程,並在創建對話框時凍結它。但是,調用堆棧中記錄的最底層函數是DlgBox!Ordinal49
,該文件位於可執行文件加載的DlgBox.dll
中。
很明顯,這不是完整的調用堆棧,因爲這是主線程,因此可執行文件中的main()
方法不能退出/返回,否則進程將關閉。
那麼爲什麼調用堆棧以DLL中的函數結束而不是主可執行文件中的函數? 如何查看完整的調用堆棧?
!address DlgBox!Ordinal49+0x52bf
呈現以下:
Usage: Image
Base Address: 028e1000
End Address: 028f2000
Region Size: 00011000 ( 68.000 kB)
State: 00001000 MEM_COMMIT
Protect: 00000020 PAGE_EXECUTE_READ
Type: 01000000 MEM_IMAGE
Allocation Base: 028e0000
Allocation Protect: 00000080 PAGE_EXECUTE_WRITECOPY
Image Path: C:\Users\mathu\Desktop\Games\Ballmaster\CrtC0B.tmp\DlgBox.DLL
Module Name: DlgBox
Loaded Image Name: C:\Users\mathu\Desktop\Games\Ballmaster\CrtC0B.tmp\DlgBox.DLL
Mapped Image Name:
More info: lmv m DlgBox
More info: !lmi DlgBox
More info: ln 0x28e52bf
More info: !dh 0x28e0000
但是如果* pdb *文件(帶有幀信息)不適用於堆棧中的所有模塊 - 在x86中不可能總是得到完整的堆棧跟蹤。調試器假定該函數使用了* ebp * frame('push ebp; mov ebp,esp'開頭)並且通過這個* ebp *鏈走。但是如果一些函數沒有使用這個框架 - 這裏堆棧跟蹤可以停止。 – RbMm
啊,那麼有沒有辦法嘗試不同的幀類型? –