### Initialize Instrumentation Callback in DllMain Source: https://context7.com/jackullrich/syscall-detect/llms.txt The DLL entry point that performs system initialization, including retrieving module base addresses and registering an instrumentation callback. It uses the undocumented NtSetInformationProcess API to hook syscalls within the process. ```cpp BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { GetBaseAddresses(); AllocConsole(); freopen("CONOUT$", "w", stdout); PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION nirvana; nirvana.Callback = (PVOID)(ULONG_PTR)InstrumentationCallbackThunk; nirvana.Reserved = 0; nirvana.Version = 0; NtSetInformationProcess( GetCurrentProcess(), (PROCESS_INFORMATION_CLASS)40, &nirvana, sizeof(nirvana)); } return TRUE; } ``` -------------------------------- ### InstrumentationCallbackThunk Assembly Entry Point Source: https://context7.com/jackullrich/syscall-detect/llms.txt This assembly routine serves as the low-level entry point for the instrumentation callback. It preserves the CPU register state and stack pointer in the Thread Environment Block (TEB) before invoking the C-based instrumentation logic. ```asm InstrumentationCallbackThunk proc mov gs:[2e0h], rsp ; Win10 TEB InstrumentationCallbackPreviousSp mov gs:[2d8h], r10 ; Win10 TEB InstrumentationCallbackPreviousPc mov r10, rcx ; Save original RCX sub rsp, 4d0h ; Alloc stack space for CONTEXT structure and rsp, -10h ; RSP must be 16 byte aligned before calls mov rcx, rsp call __imp_RtlCaptureContext ; Save the current register state sub rsp, 20h ; Shadow space call InstrumentationCallback ; Call main instrumentation routine InstrumentationCallbackThunk endp ``` -------------------------------- ### GetBaseAddresses Module Discovery Source: https://context7.com/jackullrich/syscall-detect/llms.txt Retrieves the base memory addresses and image sizes for ntdll.dll and win32u.dll. These values are essential for the validation logic to determine if a syscall return address is legitimate. ```cpp VOID GetBaseAddresses() { PIMAGE_DOS_HEADER piDH; PIMAGE_NT_HEADERS piNH; // Get ntdll.dll base address and size g_NtdllBase = (ULONG_PTR)GetModuleHandle(TEXT("ntdll.dll")); piDH = (PIMAGE_DOS_HEADER)g_NtdllBase; piNH = (PIMAGE_NT_HEADERS)(g_NtdllBase + piDH->e_lfanew); g_NtdllSize = piNH->OptionalHeader.SizeOfImage; // Get win32u.dll base address and size (GUI syscalls) g_W32UBase = (ULONG_PTR)GetModuleHandle(TEXT("win32u.dll")); if (g_W32UBase) { piDH = (PIMAGE_DOS_HEADER)g_W32UBase; piNH = (PIMAGE_NT_HEADERS)(g_W32UBase + piDH->e_lfanew); g_W32USize = piNH->OptionalHeader.SizeOfImage; } } ``` -------------------------------- ### Define Instrumentation Callback Structures Source: https://context7.com/jackullrich/syscall-detect/llms.txt Defines the undocumented PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION structure and the function pointer type for NtSetInformationProcess. This is required for configuring the Windows kernel to trigger a callback on syscall execution. ```cpp typedef struct _PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION { ULONG Version; ULONG Reserved; PVOID Callback; } PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION; typedef NTSTATUS(NTAPI* pNtSetInformationProcess)( HANDLE ProcessHandle, PROCESS_INFORMATION_CLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength ); pNtSetInformationProcess NtSetInformationProcess = (pNtSetInformationProcess)GetProcAddress( GetModuleHandle(L"ntdll"), "NtSetInformationProcess"); ``` -------------------------------- ### InstrumentationCallback Syscall Validation Source: https://context7.com/jackullrich/syscall-detect/llms.txt The primary C callback function that intercepts syscall returns. It validates the instruction pointer (RIP) against known system module boundaries and triggers a DebugBreak if the syscall originated from an unauthorized memory region. ```cpp VOID InstrumentationCallback(PCONTEXT ctx) { ULONG_PTR pTEB = (ULONG_PTR)NtCurrentTeb(); // Restore context from TEB fields set by the thunk ctx->Rip = *((ULONG_PTR*)(pTEB + 0x02D8)); // InstrumentationCallbackPreviousPc ctx->Rsp = *((ULONG_PTR*)(pTEB + 0x02E0)); // InstrumentationCallbackPreviousSp ctx->Rcx = ctx->R10; // Check if callback recursion is disabled BOOLEAN bInstrumentationCallbackDisabled = *((BOOLEAN*)pTEB + 0x2ec); if (!bInstrumentationCallbackDisabled) { // Disable to prevent recursion *((BOOLEAN*)pTEB + 0x1b8) = TRUE; // Validate return address is within ntdll.dll or win32u.dll if (RIP_SANITY_CHECK(ctx->Rip, g_NtdllBase, g_NtdllSize)) { // Legitimate ntdll.dll syscall - OK } else if (RIP_SANITY_CHECK(ctx->Rip, g_W32UBase, g_W32USize)) { // Legitimate win32u.dll syscall - OK } else { // DETECTION: Syscall from unauthorized module! printf("[SYSCALL-DETECT] Kernel returns to unverified module!\n"); DebugBreak(); } // Re-enable callback for next syscall *((BOOLEAN*)pTEB + 0x2ec) = FALSE; } RtlRestoreContext(ctx, NULL); } ``` -------------------------------- ### Validate Instruction Pointer with RIP_SANITY_CHECK Source: https://context7.com/jackullrich/syscall-detect/llms.txt A preprocessor macro used to verify if a given instruction pointer (RIP) resides within the memory bounds of a specific module. It returns a boolean value indicating if the address is within the legitimate range of the base address and module size. ```cpp #define RIP_SANITY_CHECK(Rip, BaseAddress, ModuleSize) \ (Rip > BaseAddress) && (Rip < (BaseAddress + ModuleSize)) // Usage example: if (RIP_SANITY_CHECK(ctx->Rip, NtdllBase, NtdllSize)) { // Address is within ntdll.dll - legitimate syscall } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.