メモリダンプを読み解く-2

参考書籍 : たのしいバイナリの歩き方


・メモリダンプを取得するには
vista以降ならば、タスクマネージャーからプロセスを指定し、メモリダンプを作成できる。
f:id:kamishiroHW:20200613141524p:plain


・Just-In-Timeデバッグを有効にするには
Just-In-Timeデバッグを有効にすることで、プロセスが継続不能なエラーによって終了した場合に自動的にデバッガが立ち上がり、そのプロセスにアタッチするよう設定できる。
Just-In-Timeデバッグは以下のレジストリで設定できる
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\DbgManagedDebugger
(x64) HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
(x64) HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\DbgManagedDebugger


・ダンプファイルから原因の手がかりを見つける
WinDbgを利用し、メモリダンプからクラッシュの原因を見つける。
WinDbgWindows 10 SDKに含まれている。
Debugging Tools for Windows のダウンロード - WinDbg - Windows drivers | Microsoft Docs
例として書籍サンプルのダンプファイルを解析する
binarybook/chap02/guitest2 at master · kenjiaiko/binarybook · GitHub
WinDbgを起動し、File→Open Crash Dumpからダンプファイルを開く
②Alt+6, Alt+7でCall StackウィンドウとDisassemblyウィンドウを開く
f:id:kamishiroHW:20200613144843p:plain
③EIP(実行する命令を指すレジスタ)が00000000のため、Disassemblyウィンドウが??になっている。
④Call Stackウィンドウのguitest2+0x12d0(クラッシュしたプロセス)をダブルクリックすると、停止箇所が表示される。
f:id:kamishiroHW:20200613145306p:plain
⑤Alt+4でレジスタの内容を表示すると、eaxが0であり、call eaxでアドレス00000000を呼び出そうとしている事がわかる
f:id:kamishiroHW:20200613145553p:plain
⑥call eaxの前にcall dword ptr [guitest2+0x2004 (00402004)]が行われているため、この戻り値が0としてeaxに格納されている。
⑦00402004を辿ると、呼び出された関数がGetProcAddressだとわかる
⑧同様にpushされた引数を調べていくと、00402144でkernell31.dllという引数がpushされていることがわかる。
⑨これにより、LoadLibralyW, GetProcAddressが失敗し、戻り地00000000がeaxに格納され呼び出されることでクラッシュしたとわかる