概要
指定したプロセスがデバッグされているかを判別するWin32 APIの関数です。
関数のプロトタイプは以下のとおりです。
C++
BOOL CheckRemoteDebuggerPresent(
[in] HANDLE hProcess,
[in, out] PBOOL pbDebuggerPresent
);
第一引数のhProcessに自身のプロセスハンドルを指定することで、別プロセスのデバッガーからアタッチされているかを確認できます。第二引数のpbDebuggerPresentがTRUEの場合は、指定したプロセスがデバッグされていることを示します。
実装の例
C++/x86 Assemblyのコード例を以下に示します。
C++
BOOL bDebuggerPresent = FALSE;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &bDebuggerPresent);
if (bDebuggerPresent) {
exit(1);
}
Assembly(x86)
lea eax, [ebp+bDebuggerPresent]
mov [ebp+bDebuggerPresent], 0
push eax ; bDebuggerPresent
call GetCurrentProcess
push eax ; hProcess
call CheckRemoteDebuggerPresent
cmp [ebp+bDebuggerPresent], 0
jz short loc_debugger_not_found
push 1
call exit
回避手法
CheckRemoteDebuggerPresentによるデバッガー検出を回避し、プログラムを解析する手法を以下に示します。一時的に検出を回避するときには1、2の手法を、恒久的に検出を回避するときには3の手法を使います。
- デバッグ中にレジスタの値を変更する
CheckRemoteDebuggerPresentを呼び出した後に、bDebuggerPresentの値を0に変更します。 - プラグインを利用する
ScyllaHide(Ollydbg, x64dbgなどで利用可能なプラグイン)の”NtQueryInformationProcess”の項目にチェックを入れます。 - プログラムを書き換える
CheckRemoteDebuggerPresentを呼び出した後の分岐命令をJMP命令またはNOP命令に書き換え、変更を保存します。
検出手法
CheckRemoteDebuggerPresentを検出するためのYARAルールを以下に紹介します。
YARAルール
rule Win32API_CheckRemoteDebuggerPresent
{
strings:
$str = "CheckRemoteDebuggerPresent"
condition:
$str
}