В 99% случаев, обнаружение удалённого отладчика реализовано весьма тривиально:
- Проверка глобальной экспортируемой переменной ядра KdDebuggerEnabled, которая при активном отладчике устанавливается в TRUE, и влияет на обработку исключений, и др.
- Вызов функции NtQuerySystemInformation c классом SystemDebuggerInformation, в возвращаемых данных будет следующая структура:
typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION { // Information Class 35 BOOLEAN DebuggerEnabled; BOOLEAN DebuggerNotPresent; } SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;
Оба способа обнаружения отладчика обходятся довольно просто: единственная сложность заключается в том, что для этого, по озвученным выше причинам, не подходит hotpatching ядра из своего драйвера. Поэтому, я написал патчер, которы модифицирует файл ядра на диске:
- Патчатся все xrefs на KdDebuggerEnabled таким образом, что бы значение оригинальной экспортируемой переменной никогда не изменялось.
- Перехватывается системный вызов NtQuerySystemInformation, с подменой значений обоих полей для соответствующего информационного класса.
Архив с бинарником и исходными текстоми доступен для загрузки.
Разумеется, данный патч не расчитан на защиту от всех теоретически возможных методов детекта WinDbg, но при необходимости, нужный функционал можно реализовать по аналогии с уже имеющимся (чем я и буду заниматься по мере необходимости).
Кроме, собственно, патча и readme к нему, в архиве лежит и драйвер, который позволяет проверить его работоспособность, выводя в debug output информацию о наличии отладчика.
На системе с активным удалённым отладчиком без патча:
nt!KdDebuggerEnabled: 0x8054b6c1 (TRUE) DebuggerEnabled=0x00000001 DebuggerNotPresent=0x00000000
На пропатченой системе с активным удалённым отладчиком:
nt!KdDebuggerEnabled: 0x8054b6c1 (FALSE) DebuggerEnabled=0x00000000 DebuggerNotPresent=0x00000001