概要
現在のプロセスがユーザーモードデバッガー(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
}