windbgのLogger Extensionと「bp」コマンドにおけるコマンド実行
windbg における 2 つの小ネタをメモしておきます。
- Logger Extension(logexts.dll)
- windbg の「bp」コマンドにおけるコマンド実行
この日記における windbg の実行環境は以下の通りです。User-Mode におけるデバックとなります。
コンポーネント | バージョン情報 |
---|---|
OS | Windows XP SP3*1 |
windbg | 6.12.0002.633 |
Logger Extension(logexts.dll)
windbg の拡張機能には、Logger Extension(logexts.dll)があります。この機能を使うと、windbg でデバッグするプログラムの Windows API 呼び出し(引数、戻り値を含む)を記録できます(すべての API 呼び出しを記録できるか分かりません)。以下に MSDN の文章を引用します。
Logger can monitor the actions of a user-mode target application and record all of its API calls. The resulting information can be displayed in the debugger, saved as a text file, or displayed in a powerful interactive format by the LogViewer tool.
Logger and LogViewer - Windows drivers | Microsoft Docs
試しに DLL Hijacking のブログ記事で使った Mozilla Firefox 3.5.8 を windbg で起動して、LoadLibrary 関数呼び出しを記録してみます。
LoadLibrary 関数呼び出しの記録
[File]メニューの[Open Executable]にて firefox.exe を起動します。
CommandLine: "C:\Program Files\Mozilla Firefox\firefox.exe" Symbol search path is: SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols Executable search path is: ModLoad: 00400000 004e0000 firefox.exe ModLoad: 7c940000 7c9df000 ntdll.dll ModLoad: 7c800000 7c933000 C:\WINDOWS\system32\kernel32.dll (略) ModLoad: 770d0000 7715b000 C:\WINDOWS\system32\OLEAUT32.dll ModLoad: 7c420000 7c4cf000 C:\Program Files\Mozilla Firefox\MOZCPP19.dll ModLoad: 003e0000 003e7000 C:\Program Files\Mozilla Firefox\xpcom.dll (874.864): Break instruction exception - code 80000003 (first chance) eax=00191eb4 ebx=7ffdf000 ecx=00000003 edx=00000008 esi=00191f48 edi=00191eb4 eip=7c94120e esp=0012fb20 ebp=0012fc94 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!DbgBreakPoint: 7c94120e cc int 3
Logger Extension で LoadLibrary関数呼び出し(LoadLibrary だけではないけど)を記録する手順は、以下の通りです。各コマンドの詳細は、「!logexts.help」で確認できます。この手順では、windbg の実行結果を適宜編集しています。文頭が // の文は僕のコメントとなります。
// Logger Extension のロード 0:000> !load logexts // テキストファイルへの出力の有効化 0:000> !logo e t Windows API Logging Extensions v3.01 Parsing the manifest files... Location: C:\Program Files\Debugging Tools for Windows (x86)\winext\manifest\main.h Parsing file "main.h" ... Parsing file "winerror.h" ... Parsing file "kernel32.h" ... (略) Parsing file "d3d8caps.h" ... Parsing file "dsound.h" ... Parsing completed. Debugger Disabled Text file Enabled Verbose log Enabled // LoadLibrary関数を含むカテゴリ「ProcessAndThreads」の記録のみ有効化 0:000> !logc d * All categories disabled. 0:000> !logc e 19 19 ProcessesAndThreads Enabled // Windows API 呼び出しの記録の開始(出力先:C:\windbg_logext_dir) 0:000> !loge C:\windbg_logext_dir Logexts injected. Output: "C:\windbg_logext_dir\LogExts\" Logging enabled. // ここで「g」コマンドを実行する。
windbg で Firefox を実行すると、「C:\windbg_logext_dir\LogExts」フォルダに firefox.exe.txt と firefox.exe.lgv が生成されます。firefox.exe.txt には、以下のようなログが記録されています。この記録から LoadLibrary関数のみ抽出すると、こうなります。
Thrd 864 00401C44 GetCurrentProcessId() -> 0x00000874 Thrd 864 00401C4C GetCurrentThreadId() -> 0x00000864 Thrd 864 78133B81 GetModuleFileNameW( NULL 0x00000104) -> 0x0000002C ( "C:\Program Files\Mozilla Firefox\firefox.exe") Thrd 864 7813E268 GetEnvironmentStringsW() -> "ALLUSERSPROFILE=C:\Documents and Settings\All Users" Thrd 864 7813E2F7 FreeEnvironmentStringsW( "ALLUSERSPROFILE=C:\Documents and Settings\All Users") -> TRUE Thrd 864 00401024 LoadLibraryExA( "ntdll.dll" NULL 0x00000000) -> 0x7C940000 (略)
ただ、Logger Extension ですべての Windows API 呼び出しを記録できるか疑問があります。Mozilla Firefox 3.6.8 には dwmapi.dll を呼び出すときに DLL Hijacking の問題がありますが、Logger Extension ではその LoadLibrary関数呼び出しを記録していませんでした。後述の「bp」コマンドにおけるコマンド実行、および「Process Monitor」のスタックトレース(下図)では LoadLibraryW 関数で dwmapi.dll を読み込んでいることを確認しています。
「bp」コマンドにおけるコマンド実行
windbg にはブレイクポイントを設定する「bp」コマンドがあります。この「bp」コマンドではブレイクすると同時に特定のコマンドを実行する使用方法があります。以下に MSDN の文章を引用します。
User-Mode
[~Thread] bp[ID] [Options] [Address [Passes]] ["CommandString"]
(略)
CommandString
Specifies a list of commands that are executed every time that the breakpoint is encountered the specified number of times. You must enclose the CommandString parameter in quotation marks. Use semicolons to separate multiple commands.
Debugger commands in CommandString can include parameters. You can use standard C-control characters (such as \n and \"). Semicolons that are contained in second-level quotation marks (\") are interpreted as part of the embedded quoted string.
The CommandString commands are executed only if the breakpoint is reached while the application is executing in response to a g (Go) command. The commands are not executed if you are stepping through the code or tracing past this point.
Any command that resumes program execution after a breakpoint (such as g or t) ends the execution of the command list.
bp, bu, bm (Set Breakpoint) - Windows drivers | Microsoft Docs
Logger Extension と同様に、「bp」コマンドを使って Mozilla Firefox 3.5.8 における LoadLibrary 関数呼び出しを記録してみます。
LoadLibrary 関数呼び出しの記録
Logger Extension の場合と同様に、windbg で firefox.exe を起動します。「bp」コマンドを設定して実行すると、以下のような結果が得られます。
0:000> bp kernel32!LoadLibraryA ".printf \"++++++++++ LoadLibraryA\\n+++ StackTrace\\n\"; kb; .printf \"\\n+++ First Argument(dump string)\\n\"; dW poi(esp+4); .printf \"\\n++++++++++\\n\";" // ここで「g」コマンドを実行する。 0:000> g ModLoad: 60740000 60749000 C:\WINDOWS\system32\LPK.DLL ModLoad: 5b5d0000 5b5d8000 C:\WINDOWS\system32\rdpsnd.dll ModLoad: 762b0000 762c0000 C:\WINDOWS\system32\WINSTA.dll ModLoad: 59250000 592a5000 C:\WINDOWS\system32\NETAPI32.dll ModLoad: 76ba0000 76bab000 C:\WINDOWS\system32\PSAPI.DLL ++++++++++ LoadLibraryA +++ StackTrace ChildEBP RetAddr Args to Child 0012f940 73f9e23f 73f81840 73f9e439 7c9657e5 kernel32!LoadLibraryA 0012f9e8 73f9e40d 0012fa10 7c94118a 73f80000 USP10!UspProcessAttach+0x1f 0012f9f0 7c94118a 73f80000 00000001 0012fd30 USP10!_DllMain+0x1d 0012fa10 7c95b5d2 73f9e439 73f80000 00000001 ntdll!LdrpCallInitRoutine+0x14 0012fb18 7c95fbdc 0012fd30 7ffde000 7ffdf000 ntdll!LdrpRunInitializeRoutines+0x344 0012fc94 7c95fad7 0012fd30 7c940000 0012fce0 ntdll!LdrpInitializeProcess+0x114b 0012fd1c 7c94e457 0012fd30 7c940000 00000000 ntdll!_LdrpInitialize+0x183 00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7 +++ First Argument(dump string) 73f81840 6467 3369 2e32 6c64 006c 0000 0000 0000 gdi32.dll....... 73f81850 6e69 7469 656d 6964 6966 616e 7369 6c6f initmedifinaisol 73f81860 696c 6167 736d 7465 0404 0404 0404 0404 ligamset........ 73f81870 0404 0404 0404 0404 0404 0404 0404 0404 ................ 73f81880 0404 0404 0404 0404 0404 0202 0202 0201 ................ 73f81890 0201 0101 0101 0201 0202 0102 0101 0101 ................ 73f818a0 0101 0401 0404 0404 0101 0101 0101 0101 ................ 73f818b0 0102 0801 0808 0808 0808 0808 0808 0404 ................ ++++++++++ eax=00005b9d ebx=73f9e439 ecx=0012f99c edx=7c94e514 esi=0012fa04 edi=00000001 eip=7c801d7b esp=0012f944 ebp=0012f9e8 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206 kernel32!LoadLibraryA: 7c801d7b 8bff mov edi,edi
この「bp」コマンドでは、CommandString として ".printf \"++++++++++ LoadLibraryA\\n+++ StackTrace\\n\"; kb; .printf \"\\n+++ First Argument(dump string)\\n\"; dW poi(esp+4); .printf \"\\n++++++++++\\n\";" を設定します。
この CommandString では、以下の 5 つのコマンドを連続で実行します。この CommandString ではコマンドを実行した後にブレイクしますが、「g」コマンドを連結することで CommandString 実行後すぐにデバッグを再開できます。
参考情報
- MSDN: Debugger Commands 一覧
- WinDbg にはまる - doldukeの日記
- On the (im)possibility of MS11-083 | Exploit Shop
- 「bp」コマンドと「j」コマンドの組み合わせたコマンド実行が紹介されている。