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

Log.i53

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

デバッガ検出技術:PEB.NtGlobalFlag, Heap Flags

PEB.NtGlobalFlag

 PEBは、プログラムがデバッガによってロードされているかどうかを検出するためにパッカーが使用するNtGlobalFlag (オフセット0x68)と呼ばれるフィールドを持っています。通常、プロセスがデバッグされていない場合NtGlobalFlagの値は0x0となっていますが、プロセスがデバッグされていると以下のフラグがセットされることによりNtGlobalFlagの値はたいてい0x70を含みます:

  • FLG_HEAP_ENABLE_TAIL_CHECK (0x10)
  • FLG_HEAP_ENABLE_FREE_CHECK (0x20)
  • FLG_HEAP_VALIDATE_PARAMETERS (0x40)

 これらのフラグはntdll!LdrpInitializeExecutionOptionsの内部でセットされます。PEB.NtGlobalFlagのデフォルトの値はgflags.exeツールの使用、または以下のレジストリキーにエントリにエントリを設定することによって上書き可能であることに注意してください:
f:id:i53:20150609033557p:plain

HeapFlags

 NtGlobalFlagにフラグがセットされる要因としてヒープの生成が挙げられます。ヒープ生成時にいくつかのフラグがセットされることになり、その挙動はntdll!RtlCreateHeap内部で観察することができます。一般的にプロセス用に生成される初期ヒープ(PEB.ProcessHeap)のフラグは0x02(HEAP_GROWABLE)、ForceFlagsフィールドは0x0にそれぞれ設定されることになります。ただし、プロセスがデバッグされている場合には、これらのフラグはたいてい(NtGlobalFlagに応じて)0x50000062と0x40000060(Flags AND 0x6001007D)にそれぞれ設定されます。デフォルトでは、デバッグされたプロセス上でヒープが生成された時に、以下の追加のヒープフラグが設定されます:

  • HEAP_TAIL_CHECKING_ENABLED (0x20)
  • HEAP_FREE_CHECKING_ENABLED (0x40)

 以下のサンプルコードでPEB.NtGlobalFlagが0でないか、追加のフラグがPEB.ProcessHeapに設定されているかどうかをチェックすることができます:
f:id:i53:20150609033750p:plain

解決策

 プロセスがデバッグされていないよう見せかけるために、PEB.NtGlobalFlagとPEB.HeapProcessフラグに対してパッチを適用します。以下は、上記のフラグにパッチを適用するollyscriptの例です:
f:id:i53:20150609033848p:plain

 また、OllyAdvancedプラグインはPEB.NtGlobalFlagsとPEB.ProcessHeapフラグを設定するオプションを持っています。