Log.i53

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

デバッガ検出技術:DebugObject:NtQueryObject()

 プロセスがデバッグされているかどうかを特定する代わりに、デバッガがシステムで実行されているかどうかのチェックに関与するその他の技術があります。

 リバースエンジニアリングのフォーラムで議論されていた1つの興味深い方法が、DebugObject型のカーネルオブジェクトの数をチェックするものです。この手法は、アプリケーションがデバッグされている全ての時間において、カーネル内でデバッグセッションにおいてDebugObject型のオブジェクトが生成されるために動作します。

 DebugObjectの数はntdll!NtQueryObject()を使用して全てのオブジェクト型についての情報を列挙することによって取得することができます。NtQueryObjectは5つの引数を持ち、全てのオブジェクト型を列挙する目的では、ObjectHandleパラメータをNULLに設定して、ObjectInformationClassパラメータはObjectAllTypeInformation(3)に設定します:
f:id:i53:20150609040411p:plain

 上記のAPIは、ObjectTypeInformation配列とオブジェクト型の総数であるNumberOfObjectsTypesフィールドを含むOBJECT_ALL_INFORMATION構造体を返します:
f:id:i53:20150609040451p:plain

 検出ルーチンでは、以下の構造体を有するObjectTypeInformation配列を走査します:
f:id:i53:20150609040532p:plain

 TypeNameフィールドがUNICODE文字列"DebugPort"と比較され、その後でTotalNumberOfHandlesかTotalNumberOfObjectsの値が非ゼロ値であればデバッグされていると判定します。

解決策

 NtQueryInformationProcess()における対応策と同様に、NtQueryObject()のリターンに対してブレークポイントを設定します。その後で、リターンされるOBJECT_ALL_INFORMATION構造体にパッチを施します。特に、パッカーによるObjectTypeInformation配列の走査から逃れるために、NumberOfObjectsTypesフィールドの値を0に設定します。NtQueryInformationProcess()における対応策で作成したollyscriptと同様に、スクリプトを介して上記のパッチを適用することも可能です。
 また、OllyAdvancedプラグインでは、ObjectAllTypeInformation型のクエリ時に返されるバッファ全体を0に設定するためのコードをNtQueryObject()に対してコードインジェクションします。