概要
現在のプロセスがユーザーモードデバッガー(Ollydbg, x64dbgなど)にデバッグされているかどうかを判別するWin32 APIの関数です。デバッグされている場合、戻り値として0以外の値を返します。
C++
BOOL IsDebuggerPresent();
IsDebuggerPresentはPEB(Process Environment Block)という構造体の中にあるBeingDebuggedの値を参照してデバッガーの有無を判別しています。デバッガーが存在する場合、BeingDebuggedの値は1になります。
実装の例
C++/x86 Assemblyのコード例を以下に示します。
C++
if (IsDebuggerPresent()) {
exit(1);
}
x86 Assembly
call IsDebuggerPresent
test eax, eax
jz short loc_debugger_not_found
push 1
call exit
回避手法
IsDebuggerPresentによるデバッガー検出を回避し、プログラムを解析する手法を以下に示します。一時的に検出を回避するときには1~3の手法を、恒久的に検出を回避するときには4の手法を使います。
- EAXレジスタの値を変更する
IsDebuggerPresent関数を呼び出した後のEAXレジスタを0に変更します。 - BeingDebuggedの値を変更する
IsDebuggerPresent関数を呼び出す前にBeingDebugged(PEBの0x02オフセット)の値を0に変更します。 - プラグインを利用する
ScyllaHide(Ollydbg, x64dbgなどで利用可能なプラグイン)の”BeingDebugged”の項目にチェックを入れます。 - プログラムを書き換える
IsDebuggerPresentを呼び出した後の分岐命令をJMP命令またはNOP命令に書き換え、変更を保存します。
検出手法
IsDebuggerPresentを検出するYARAルールを以下に示します。
YARAルール
rule Win32API_IsDebuggerPresent
{
strings:
$str ="IsDebuggerPresent"
condition:
$str
}