Прототип:
NTSTATUS WINAPI NtQueryInformationProcess( _In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength );
Функция NtQueryInformationProcess(ProcessDebugPort) - ntdll.dll
Функция NtQueryInformationProcess находится в ntdll.dll. Этот недокументированный метод используется для получения информации о целевом процессе, в том числе, данных, связанных с отладкой. Функция принимает пять параметров, первые два из которых представляют для нас наибольший интерес. Первый параметр является дескриптором запрашиваемого процесса. В нашем примере, мы используем значение -1. Это значение говорит функции использовать текущий дескриптор запущенного процесса. Вторым параметром является константа (значение из перечисления ProcessInformationClass), указывающая на тип данных, которые хотим получить из целевого процесса. Вызов этой функции с дескриптором нашего текущего процесса, вместе со значением ProcessDebugPort (0x07) вернет нам номер порта для отладки процесса (EPROCESS -> DebugPort). Если текущий процесс в данный момент отлаживается, то порт будет назначен, и номер порта будет нам возвращен (значение 0xFFFFFFFF). А если текущий процесс не имеет отладчика, то нам вернется нулевое значение. Т.к. NtQueryInformationProcess используется для внутренних служб операционной системы, поэтому мы должны использовать динамическое связывание: загрузить модуль с помощью LoadLibrary и получить указатель на функцию с помощью GetProcAddress.
hmod = LoadLibrary(L"ntdll.dll"); _NtQueryInformationProcess = GetProcAddress(hmod,"NtQueryInformationProcess"); status = (_NtQueryInformationProcess) (-1, 0x07, &retVal, 4, NULL); if (retVal != 0) { MessageBox(NULL, L"Debugger Detected Via NtQueryInformationProcess ProcessDebugPort", L"Debugger Detected", MB_OK); } else { MessageBox(NULL, L"No Debugger Detected", L"No Debugger Detected", MB_OK); }
Функция NtQueryInformationProcess(ProcessDebugFlags) - ntdll.dll
Проверка ProcessDebugFlags также использует функцию NtQueryInformationProcess для обнаружения отладчика. В этом случае вместо вызова функции со вторым параметром 0x07 (ProcessDebugPort), мы используем значение 0x1F (ProcessDebugFlags). Функция возвращает значение бита EPROCESS -> NoDebugInherit, где 0 (FALSE) означает, что отладчик в настоящее время присоединен к процессу.
hmod = LoadLibrary(L"ntdll.dll"); _NtQueryInformationProcess = GetProcAddress(hmod,"NtQueryInformationProcess"); status = (_NtQueryInformationProcess) (-1, 31, &debugFlag, 4, NULL); // 31 (0x1F) = DebugProcessFlags if (debugFlag == 0x00000000) MessageBox(NULL, L"Debugger Detected via ProcessDebugFlags", L"Debugger Detected", MB_OK);
Функция NtQueryInformationProcess(ProcessDebugObjectHandle) - ntdll.dll
Начиная с Windows XP, в случае отладки процесса система создает так называемый «объект отладки», имеющий свой дескриптор. Его можно получить, используя вызов NtQueryInformationProcess со вторым параметром равным 0x1E (ProcessDebugObjectHandle). Если вызов этой функции возвращает ненулевое значение, то мы можем быть уверены, что целевой процесс отлаживается.
hmod = LoadLibrary(L"ntdll.dll"); _NtQueryInformationProcess = GetProcAddress(hmod,"NtQueryInformationProcess"); status = (_NtQueryInformationProcess) (-1, 30,&hDebugObject, 4, NULL); // 30 (0x1E) = ProcessDebugObjectHandle if (hDebugObject) MessageBox(NULL, L"Debugger Detected via ProcessDebugFlags", L"Debugger Detected", MB_OK); if (!hDebugObject) MessageBox(NULL, L"No Debugger Detected", L"No Debugger", MB_OK);