x86 系 CPU のフラグレジスタには、Trap Flag というフラグがあって、
これを立てると次の1命令を実行してトラップ例外を起こします。
void SetSingleStepMode( HANDLE hThread ) { CONTEXT ctx = { CONTEXT_CONTROL }; GetThreadContext( hThread, &ctx ); ctx.EFlags |= 0x00000100; // TrapFlag SetThreadContext( hThread, &ctx ); }
スレッドのコンテキストには、その時の CPU のレジスタなどの
情報が格納されています。EFlags がフラグレジスタ。
CONTEXT_INTEGER を付けるとおなじみ EAX〜EDX レジスタも見れます。
さて、TrapFlag を立てておくと1命令実行後、EXCEPTION_SINGLE_STEP 例外が発生するので
case EXCEPTION_DEBUG_EVENT: if( evDebug.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP ) { SetSingleStepMode( hThread ); } break;
こんな風に拿捕します。
一回発生するとフラグが落ちるので、毎回設定しなおします。
ほんとは Get/SetThreadContext する前に Suspend する必要がありますが、
WaitForDebugEvent ループ中は実行停止されているので問題なし。
CreateProcess 直後にするなら CREATE_SUSPENDED フラグを。