├── README.md ├── toast.h └── toast.c /README.md: -------------------------------------------------------------------------------- 1 | # Toast 2 | Method to bypass user-mode hooks. 3 | --- 4 | https://scorchsecurity.wordpress.com/2016/08/26/bypassing-user-mode-the-sneaky-way/ 5 | 6 | ##Usage: 7 | To use the method, simply use the ResolveNtFunc function like this: 8 | ``` 9 | NtCreateSection = (fnNtCreateSection)ResolveNtFunc("NtCreateSection") 10 | ``` 11 | This function maps ntdll from the \\KnownDlls\ntdll.dll section into the current process the first time you use it and resolves the api from that. Loading ntdll this way can avoid tripping user-mode hooks. 12 | -------------------------------------------------------------------------------- /toast.h: -------------------------------------------------------------------------------- 1 | #ifndef _TOAST_H 2 | #define _TOAST_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 ) 9 | #define DEREF( pointer )*(ULONG_PTR *)(pointer) 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | LPVOID InitDll(PWSTR section_path); 15 | void *ResolveFunction(HMODULE module, const char *proc_name); 16 | void *ResolveNtFunc(const char *func_name); 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #endif // _TOAST_H 22 | -------------------------------------------------------------------------------- /toast.c: -------------------------------------------------------------------------------- 1 | #include "toast.h" 2 | 3 | typedef NTSTATUS(NTAPI *fnNtOpenSection)(HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *); 4 | typedef NTSTATUS(NTAPI *fnNtMapViewOfSection)(HANDLE, HANDLE, PVOID, ULONG_PTR, SIZE_T, PLARGE_INTEGER, PSIZE_T, DWORD, ULONG, ULONG); 5 | 6 | // I know that globals are bad, but this will increase friendliness 7 | HMODULE _Resolved_NTDLL_ = NULL; 8 | 9 | FORCEINLINE VOID NewRtlInitUnicodeString(PUNICODE_STRING DestinationString, PWSTR SourceString) 10 | { 11 | DestinationString->Buffer = SourceString; 12 | DestinationString->MaximumLength = DestinationString->Length = wcslen(SourceString) * sizeof(WCHAR); 13 | } 14 | 15 | void *ResolveFunction(HMODULE module, const char *proc_name) 16 | { 17 | char *pBaseAddress = (char *)module; 18 | 19 | IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER *)pBaseAddress; 20 | IMAGE_NT_HEADERS *pNtHeaders = (IMAGE_NT_HEADERS *)(pBaseAddress + pDosHeader->e_lfanew); 21 | IMAGE_OPTIONAL_HEADER *pOptionalHeader = &pNtHeaders->OptionalHeader; 22 | IMAGE_DATA_DIRECTORY *pDataDirectory = (IMAGE_DATA_DIRECTORY *)(&pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]); 23 | IMAGE_EXPORT_DIRECTORY *pExportDirectory = (IMAGE_EXPORT_DIRECTORY *)(pBaseAddress + pDataDirectory->VirtualAddress); 24 | 25 | void **ppFunctions = (void **)(pBaseAddress + pExportDirectory->AddressOfFunctions); 26 | WORD *pOrdinals = (WORD *)(pBaseAddress + pExportDirectory->AddressOfNameOrdinals); 27 | ULONG *pNames = (ULONG *)(pBaseAddress + pExportDirectory->AddressOfNames); 28 | /* char **pNames = (char **)(pBaseAddress + pExportDirectory->AddressOfNames); /* */ 29 | 30 | void *pAddress = NULL; 31 | 32 | DWORD i; 33 | 34 | if (((DWORD_PTR)proc_name >> 16) == 0) 35 | { 36 | WORD ordinal = LOWORD(proc_name); 37 | DWORD dwOrdinalBase = pExportDirectory->Base; 38 | 39 | if (ordinal < dwOrdinalBase || ordinal >= dwOrdinalBase + pExportDirectory->NumberOfFunctions) 40 | return NULL; 41 | 42 | pAddress = (FARPROC)(pBaseAddress + (DWORD_PTR)ppFunctions[ordinal - dwOrdinalBase]); 43 | } 44 | else 45 | { 46 | for (i = 0; i < pExportDirectory->NumberOfNames; i++) 47 | { 48 | char *szName = (char*)pBaseAddress + (DWORD_PTR)pNames[i]; 49 | if (strcmp(proc_name, szName) == 0) 50 | { 51 | pAddress = (FARPROC)(pBaseAddress + ((ULONG*)(pBaseAddress + pExportDirectory->AddressOfFunctions))[pOrdinals[i]]); 52 | break; 53 | } 54 | } 55 | } 56 | 57 | return pAddress; 58 | } 59 | 60 | LPVOID InitDll(PWSTR section_path) { 61 | // variable declarations 62 | fnNtOpenSection NtOpenSection = NULL; 63 | fnNtMapViewOfSection NtMapViewOfSection = NULL; 64 | PVOID baseAddress = NULL; 65 | ULONG_PTR peb_navigator = NULL; 66 | ULONG_PTR viewSize = NULL; 67 | HMODULE peb_ntdll = NULL; 68 | HANDLE sectionHandle; 69 | UNICODE_STRING ntSectionName; 70 | OBJECT_ATTRIBUTES ObjAttrs; 71 | NTSTATUS ntStatus; 72 | 73 | // resolve PEB 74 | #ifdef _WIN64 75 | peb_navigator = __readgsqword(0x60); 76 | #else 77 | #ifdef _WIN32 78 | peb_navigator = __readfsdword(0x30); 79 | #endif 80 | #endif 81 | peb_navigator = (ULONG_PTR)((PPEB)peb_navigator)->Ldr; 82 | peb_navigator = (ULONG_PTR)((PPEB_LDR_DATA)peb_navigator)->InMemoryOrderModuleList.Flink; 83 | peb_navigator = DEREF(peb_navigator); 84 | #ifdef _WIN64 85 | peb_ntdll = (HMODULE)DEREF(peb_navigator + 0x20); 86 | #else 87 | #ifdef _WIN32 88 | peb_ntdll = (HMODULE)DEREF(peb_navigator + 0x10); 89 | #endif 90 | #endif 91 | if (!peb_ntdll) 92 | return NULL; 93 | NtOpenSection = (fnNtOpenSection)ResolveFunction(peb_ntdll, "NtOpenSection"); 94 | NtMapViewOfSection = (fnNtMapViewOfSection)ResolveFunction(peb_ntdll, "NtMapViewOfSection"); 95 | 96 | NewRtlInitUnicodeString(&ntSectionName, section_path); 97 | 98 | InitializeObjectAttributes(&ObjAttrs, &ntSectionName, OBJ_CASE_INSENSITIVE, NULL, NULL); 99 | ntStatus = NtOpenSection(§ionHandle, SECTION_MAP_READ | SECTION_MAP_EXECUTE, &ObjAttrs); 100 | if (!NT_SUCCESS(ntStatus)) 101 | return NULL; 102 | ntStatus = NtMapViewOfSection(sectionHandle, NtCurrentProcess(), &baseAddress, 0, 0, NULL, &viewSize, 1, 0, PAGE_READONLY); 103 | if (!NT_SUCCESS(ntStatus)) 104 | return NULL; 105 | // At this point, the baseaddress is a pointer to ntdll 106 | if (!baseAddress) 107 | return NULL; 108 | 109 | return baseAddress; 110 | } 111 | 112 | void *ResolveNtFunc(const char *func_name) { 113 | if (_Resolved_NTDLL_ == NULL) 114 | #ifdef _WIN64 115 | _Resolved_NTDLL_ = InitDll(L"\\KnownDlls\\ntdll.dll"); 116 | #else 117 | #ifdef _WIN32 118 | _Resolved_NTDLL_ = InitDll(L"\\KnownDlls32\\ntdll.dll"); 119 | #endif 120 | #endif 121 | return ResolveFunction(_Resolved_NTDLL_, func_name); 122 | } 123 | --------------------------------------------------------------------------------