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

Log.i53

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

AntiDebug技術:Unhandled Exception Filter

 MSDNドキュメントには、例外が未処理例外フィルタ(kernel32!UnhandledExceptionFilter)
に達してかつ、そのアプリケーションがデバッグされていなかった場合、その未処理例外フィルタはkernel32!SetUnhandledExceptionFilter() APIのパラメータとして指定されたトップレベルの例外フィルタを呼び出します。パッカーは、例外フィルタを設定した後で例外を投げることによって、それがデバッグされていた場合とそれ以外とで、例外フィルタへ制御を移して実行を継続できるというアドバンテージを得ることができます。

 以下に、SetUnhandledExceptionFilter()を使用してトップレベルの例外フィルタを設定し、その後でアクセスバイオレーション例外を投げるサンプルを示します。プロセスがデバッグされている場合、そのデバッガは2回例外を受けとる機会を得ます。その他の場合、例外フィルタはCONTEXT.EIPを設定して実行を継続します。
f:id:i53:20150609050431p:plain
 
 パッカーによっては、分析者がSetUnhandledExceptionFilter()にブレークポイントがしかけられるであろうことを見越して、これを呼び出す代わりにkernel32!_BasepCurrentTopLevelFilterディレクトリを設定することで、例外フィルタをマニュアルで設定するものもあります。

解決策

 興味深いことに、kernel32!UnhandledExceptionFilter()内部のコードは、プロセスがデバッグされているかを判断するためにntdll!NtQueryInformationProcess (ProcessDebugPort)を呼び出しており、これはその後で登録された例外フィルタを呼び出すかどうかを決定するために利用されます。したがって、DebugPortによるデバッガ検出技術と同様の解決策をとればよいことが分かります。