たまにはハックっぽいことをしたいなと思って。
簡単なデバッガ(のコアだけ)を作ってみた。
デバッガを作るために必要なものは2つ。
- アタッチする
- デバッグイベントを処理する
デバッガとしてアタッチする
まずデバッガからプログラムを起動する場合は
PROCESS_INFORMATION pcInfo; STARTUPINFO supInfo = { sizeof(STARTUPINFO) }; BOOL bResult = CreateProcess( NULL, lpCmdLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_SUSPENDED | DEBUG_PROCESS, NULL, NULL, &supInfo, &pcInfo ); if( !bResult ) throw std::runtime_error( "CreateProcess" );
こんな感じで CreateProcess API を呼ぶときに DEBUG_PROCESS フラグを立てるだけ。
他はオプション。お好みで。
も1つ、既に動いてるプロセスにアタッチしたい場合。
DebugActiveProcess( hProcess );
簡単ですね。
デバッグイベントの処理
デバッガとしてアタッチしている状態で WaitForDebugEvent API を呼ぶと、
次のデバッグイベントが発生するまで待機します。
返されたイベントを処理後、ContinueDebugEvent で継続できます。
for(;;) { DEBUG_EVENT evDebug; WaitForDebugEvent( &evDebug, INFINITE ); switch( evDebug.dwDebugEventCode ) { case CREATE_PROCESS_DEBUG_EVENT: printf("CREATE_PROCESS_DEBUG_EVENT\n"); break; case CREATE_THREAD_DEBUG_EVENT: printf("CREATE_THREAD_DEBUG_EVENT\n"); break; case EXCEPTION_DEBUG_EVENT: printf("EXCEPTION_DEBUG_EVENT\n"); break; case EXIT_PROCESS_DEBUG_EVENT: printf("EXIT_PROCESS_DEBUG_EVENT\n"); return; case EXIT_THREAD_DEBUG_EVENT: printf("EXIT_THREAD_DEBUG_EVENT\n"); break; case LOAD_DLL_DEBUG_EVENT: printf("LOAD_DLL_DEBUG_EVENT\n"); break; case OUTPUT_DEBUG_STRING_EVENT: printf("OUTPUT_DEBUG_STRING_EVENT\n"); break; case RIP_EVENT: printf("RIP_EVENT\n"); break; case UNLOAD_DLL_DEBUG_EVENT: printf("UNLOAD_DLL_DEBUG_EVENT\n"); break; } ContinueDebugEvent( evDebug.dwProcessId, evDebug.dwThreadId, DBG_CONTINUE ); }
基本はこんな感じ。
簡単すぎてビックリですね。