Introduction
User-mode hooks are unreliable and can be bypassed in various ways. While tools like makin can bypass hooks by loading ntdll from the %temp% directory, this approach is noisy due to DLL loading. Let’s explore a stealthier method - reimplementing ntdll functions.
The Approach
To achieve better stealth, we’ll:
- Work with undocumented functions
- Reimplement low-level functions directly
- Use Windows-specific implementation details
Note: This implementation targets Windows Version 1709 x64
Function Analysis
NtCreateFile Implementation
Using IDA or similar disassemblers, we can analyze the original implementation:
NtClose Implementation
Implementation
Assembly
.code
NtClose PROC mov r10, rcx; mov eax, 15; syscall; ret;NtClose ENDP
NtCreateFile PROC mov r10, rcx; mov eax, 85; syscall; ret;NtCreateFile ENDP
ENDMain Code
int main() { RtlInitUnicodeStringEx* initUnicode = (RtlInitUnicodeStringEx*)GetProcAddress(GetModuleHandle(L"ntdll"), "RtlInitUnicodeStringEx"); UNICODE_STRING un; initUnicode(&un, L"\\??\\C:\\file.txt");
HANDLE hFile; OBJECT_ATTRIBUTES objA{}; objA.Length = sizeof(OBJECT_ATTRIBUTES); objA.ObjectName = &un; _IO_STATUS_BLOCK IoStatusBlock{}; auto status = NtCreateFile(&hFile, GENERIC_ALL, &objA, &IoStatusBlock, 0, 0, 0, CREATE_NEW, 0, 0, 0);
NtClose(hFile);}Improving Stability
Pro Tip: For better stability, extract the index number from
ntdllat runtime:
Resources
Demonstration
Below is a demonstration of the hook bypassing in action: