跳转至

CheckRemoteDebuggerPresent

关于CheckRemoteDebuggerPresent

kernel32CheckRemoteDebuggerPresent()函数用于检测指定进程是否正在被调试. Remote在单词里是指同一个机器中的不同进程.

BOOL WINAPI CheckRemoteDebuggerPresent(
  _In_    HANDLE hProcess,
  _Inout_ PBOOL  pbDebuggerPresent
);

如果调试器存在(通常是检测自己是否正在被调试), 该函数会将pbDebuggerPresent指向的值设为0xffffffff.

检测代码

可以用以下32位代码检测32位环境

push eax
push esp
push -1 ;GetCurrentProcess()
call CheckRemoteDebuggerPresent
pop eax
test eax, eax
jne being_debugged

或64位代码检测64位环境

enter 20h, 0
mov edx, ebp
or rcx, -1 ;GetCurrentProcess()
call CheckRemoteDebuggerPresent
leave
test ebp, ebp
jne being_debugged

如何绕过

比如有如下的代码

int main(int argc, char *argv[])
{
    BOOL isDebuggerPresent = FALSE;
    if (CheckRemoteDebuggerPresent(GetCurrentProcess(), &isDebuggerPresent ))
    {
        if (isDebuggerPresent )
        {
            std::cout << "Stop debugging program!" << std::endl;
            exit(-1);
        }
    }
    return 0;
}

我们可以直接修改isDebuggerPresent的值或修改跳转条件来绕过(注意不是CheckRemoteDebuggerPresent的izhi, 它的返回值是用于表示函数是否正确执行).

但如果要针对CheckRemoteDebuggerPresent这个api函数进行修改的话. 首先要知道CheckRemoteDebuggerPresent内部其实是通过调用NtQueryInformationProcess来完成功能的. 而我们就需要对NtQueryInformationProcess的返回值进行修改. 我们将在 NtQueryInformationProcess 篇进行介绍.