読者です 読者をやめる 読者になる 読者になる

Log.i53

Themidaのアンパックを目指すブログ改め使い物になるえんじにゃを目指すブログ

デバッガ検出技術:DebugPort:CheckRemoteDebuggerPresent() / NtQueryInformationProcess()

CheckRemoteDebuggerPresent

 Kernel32!CheckRemoteDebuggerPresent()は、デバッガがプロセスに接続されているかどうかを返すAPIです。このAPIは、ntdll!NtQueryInformationProcess()内部で呼び出され、ProcessInformationClassパラメータがProcessDebugPort(7)に設定されます。さらに、カーネルの内部で、NtQueryInformationProcess()はEPROCESSカーネル構造体のDebugPortフィールドを照会します。DebugPortフィールド内のゼロ以外の値はプロセスがユーザモードデバッガによってデバッグされていることを示します。この場合、ProcessInformationの値は0xFFFFFFFFに設定され、そうでない場合はProcessInformationの値は0x0に設定されます。
 Kernel32!CheckRemoteDebuggerPresent()は2つの引数をもちます。1つ目の引数はプロセスハンドルであり、2つ目の引数はプロセスがデバッグされている場合TRUEとなるブール変数へのポインタです。
f:id:i53:20150609034307p:plain

NtQueryInformationProcess

 もう一方のNtdll!NtQueryInformationProcess()は、5つの引数を持っています。デバッガを検出が目的の場合、ProcessInformationClassがProcessDebugPort(7)に設定します:
f:id:i53:20150609034433p:plain

 以下の例は、現在のプロセスがデバッグされているかどうかを検出するためのCheckRemoteDebuggerPresent()とNtQueryInformationProcess()の一般的な呼び出しを示しています:
f:id:i53:20150609034544p:plain

解決策

 解決策の1つは、NtQueryInformationProcess()のリターンに対してブレークポイントを設定し、その後ブレークポイントがヒットした時にProcessInformationの値を0でパッチすることです。これを自動的に実行するためのollyscriptの例を以下に示します:
f:id:i53:20150609034730p:plain

 また、OllyAdvancedプラグインはNtQueryInformationProcess()をパッチするオプションを持っています。このパッチは、NtQueryInformationProcess()の戻り値を操作するコードインジェクションとなっています。