├── define.h ├── function.cpp ├── function.h ├── hook.cpp ├── hook.h └── main.cpp /define.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #pragma comment(lib, "ntoskrnl.lib") 8 | 9 | typedef enum _SYSTEM_INFORMATION_CLASS 10 | { 11 | SystemBasicInformation, 12 | SystemProcessorInformation, 13 | SystemPerformanceInformation, 14 | SystemTimeOfDayInformation, 15 | SystemPathInformation, 16 | SystemProcessInformation, 17 | SystemCallCountInformation, 18 | SystemDeviceInformation, 19 | SystemProcessorPerformanceInformation, 20 | SystemFlagsInformation, 21 | SystemCallTimeInformation, 22 | SystemModuleInformation = 0x0B 23 | } SYSTEM_INFORMATION_CLASS, 24 | * PSYSTEM_INFORMATION_CLASS; 25 | 26 | typedef struct _RTL_PROCESS_MODULE_INFORMATION 27 | { 28 | HANDLE Section; 29 | PVOID MappedBase; 30 | PVOID ImageBase; 31 | ULONG ImageSize; 32 | ULONG Flags; 33 | USHORT LoadOrderIndex; 34 | USHORT InitOrderIndex; 35 | USHORT LoadCount; 36 | USHORT OffsetToFileName; 37 | UCHAR FullPathName[256]; 38 | } RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION; 39 | 40 | typedef struct _RTL_PROCESS_MODULES 41 | { 42 | ULONG NumberOfModules; 43 | RTL_PROCESS_MODULE_INFORMATION Modules[1]; 44 | } RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES; 45 | 46 | typedef struct _PEB_LDR_DATA { 47 | ULONG Length; 48 | BOOLEAN Initialized; 49 | PVOID SsHandle; 50 | LIST_ENTRY ModuleListLoadOrder; 51 | LIST_ENTRY ModuleListMemoryOrder; 52 | LIST_ENTRY ModuleListInitOrder; 53 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 54 | 55 | typedef struct _LDR_DATA_TABLE_ENTRY { 56 | LIST_ENTRY InLoadOrderModuleList; 57 | LIST_ENTRY InMemoryOrderModuleList; 58 | LIST_ENTRY InInitializationOrderModuleList; 59 | PVOID DllBase; 60 | PVOID EntryPoint; 61 | ULONG SizeOfImage; // in bytes 62 | UNICODE_STRING FullDllName; 63 | UNICODE_STRING BaseDllName; 64 | ULONG Flags; // LDR_* 65 | USHORT LoadCount; 66 | USHORT TlsIndex; 67 | LIST_ENTRY HashLinks; 68 | PVOID SectionPointer; 69 | ULONG CheckSum; 70 | ULONG TimeDateStamp; 71 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 72 | 73 | typedef struct _RTL_USER_PROCESS_PARAMETERS { 74 | BYTE Reserved1[16]; 75 | PVOID Reserved2[10]; 76 | UNICODE_STRING ImagePathName; 77 | UNICODE_STRING CommandLine; 78 | } RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS; 79 | 80 | typedef void(__stdcall* PPS_POST_PROCESS_INIT_ROUTINE)(void); // not exported 81 | 82 | typedef struct _PEB { 83 | BYTE Reserved1[2]; 84 | BYTE BeingDebugged; 85 | BYTE Reserved2[1]; 86 | PVOID Reserved3[2]; 87 | PPEB_LDR_DATA Ldr; 88 | PRTL_USER_PROCESS_PARAMETERS ProcessParameters; 89 | PVOID Reserved4[3]; 90 | PVOID AtlThunkSListPtr; 91 | PVOID Reserved5; 92 | ULONG Reserved6; 93 | PVOID Reserved7; 94 | ULONG Reserved8; 95 | ULONG AtlThunkSListPtr32; 96 | PVOID Reserved9[45]; 97 | BYTE Reserved10[96]; 98 | PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; 99 | BYTE Reserved11[128]; 100 | PVOID Reserved12[1]; 101 | ULONG SessionId; 102 | } PEB, * PPEB; 103 | 104 | extern "C" __declspec(dllimport) 105 | NTSTATUS NTAPI ZwProtectVirtualMemory( 106 | HANDLE ProcessHandle, 107 | PVOID * BaseAddress, 108 | PULONG ProtectSize, 109 | ULONG NewProtect, 110 | PULONG OldProtect 111 | ); 112 | 113 | extern "C" NTKERNELAPI 114 | PVOID 115 | NTAPI 116 | RtlFindExportedRoutineByName( 117 | _In_ PVOID ImageBase, 118 | _In_ PCCH RoutineNam 119 | ); 120 | 121 | extern "C" NTSTATUS ZwQuerySystemInformation(ULONG InfoClass, PVOID Buffer, ULONG Length, PULONG ReturnLength); 122 | 123 | extern "C" NTKERNELAPI 124 | PPEB 125 | PsGetProcessPeb( 126 | IN PEPROCESS Process 127 | ); 128 | 129 | extern "C" NTSTATUS NTAPI MmCopyVirtualMemory 130 | ( 131 | PEPROCESS SourceProcess, 132 | PVOID SourceAddress, 133 | PEPROCESS TargetProcess, 134 | PVOID TargetAddress, 135 | SIZE_T BufferSize, 136 | KPROCESSOR_MODE PreviousMode, 137 | PSIZE_T ReturnSize 138 | ); -------------------------------------------------------------------------------- /function.cpp: -------------------------------------------------------------------------------- 1 | #include "function.h" 2 | 3 | PVOID get_system_module_base(const char* module_name) 4 | { 5 | ULONG bytes = 0; 6 | NTSTATUS status = ZwQuerySystemInformation(SystemModuleInformation, NULL, bytes, &bytes); 7 | 8 | if (!bytes) 9 | return NULL; 10 | 11 | PRTL_PROCESS_MODULES modules = (PRTL_PROCESS_MODULES)ExAllocatePoolWithTag(NonPagedPool, bytes, 0x4e554c4c); 12 | 13 | status = ZwQuerySystemInformation(SystemModuleInformation, modules, bytes, &bytes); 14 | 15 | if (!NT_SUCCESS(status)) 16 | return NULL; 17 | 18 | 19 | 20 | PRTL_PROCESS_MODULE_INFORMATION module = modules->Modules; 21 | PVOID module_base = 0, module_size = 0; 22 | 23 | for (ULONG i = 0; i < modules->NumberOfModules; i++) 24 | { 25 | if (strcmp((char*)module[i].FullPathName, module_name) == NULL) 26 | { 27 | module_base = module[i].ImageBase; 28 | module_size = (PVOID)module[i].ImageSize; 29 | break; 30 | } 31 | } 32 | 33 | if (modules) 34 | ExFreePoolWithTag(modules, NULL); 35 | 36 | if (module_base <= NULL) 37 | return NULL; 38 | 39 | return module_base; 40 | } 41 | 42 | PVOID get_system_module_export(const char* module_name, LPCSTR routine_name) 43 | { 44 | PVOID lpModule = get_system_module_base(module_name); 45 | 46 | if (!lpModule) 47 | return NULL; 48 | 49 | return RtlFindExportedRoutineByName(lpModule, routine_name); 50 | } 51 | 52 | bool write_memory(void* address, void* buffer, size_t size) 53 | { 54 | if (!RtlCopyMemory(address, buffer, size)) 55 | { 56 | return false; 57 | } 58 | else 59 | { 60 | return true; 61 | } 62 | } 63 | 64 | bool write_to_read_only_memory(void* address, void* buffer, size_t size) 65 | { 66 | PMDL Mdl = IoAllocateMdl(address, size, FALSE, FALSE, NULL); 67 | 68 | if (!Mdl) 69 | return false; 70 | 71 | MmProbeAndLockPages(Mdl, KernelMode, IoReadAccess); 72 | PVOID Mapping = MmMapLockedPagesSpecifyCache(Mdl, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority); 73 | MmProtectMdlSystemAddress(Mdl, PAGE_READWRITE); 74 | 75 | write_memory(Mapping, buffer, size); 76 | 77 | MmUnmapLockedPages(Mapping, Mdl); 78 | MmUnlockPages(Mdl); 79 | IoFreeMdl(Mdl); 80 | 81 | return true; 82 | } 83 | 84 | ULONG64 get_module_base_x64(PEPROCESS proc, UNICODE_STRING module_name) 85 | { 86 | PPEB pPeb = PsGetProcessPeb(proc); 87 | 88 | if (!pPeb) 89 | { 90 | return NULL; 91 | } 92 | 93 | KAPC_STATE state; 94 | 95 | KeStackAttachProcess(proc, &state); 96 | 97 | PPEB_LDR_DATA pLdr = (PPEB_LDR_DATA)pPeb->Ldr; 98 | 99 | if (!pLdr) 100 | { 101 | KeUnstackDetachProcess(&state); 102 | return NULL; 103 | } 104 | 105 | for (PLIST_ENTRY list = (PLIST_ENTRY)pLdr->ModuleListLoadOrder.Flink; list != &pLdr->ModuleListLoadOrder; list = (PLIST_ENTRY)list->Flink) 106 | { 107 | PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(list, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList); 108 | 109 | if (RtlCompareUnicodeString(&pEntry->BaseDllName, &module_name, TRUE) == NULL) 110 | { 111 | ULONG64 baseAddr = (ULONG64)pEntry->DllBase; 112 | KeUnstackDetachProcess(&state); 113 | return baseAddr; 114 | } 115 | } 116 | 117 | KeUnstackDetachProcess(&state); 118 | return NULL; 119 | } 120 | 121 | bool read_kernel_memory(HANDLE pid, uintptr_t address, void* buffer, SIZE_T size) 122 | { 123 | if (!address || !buffer || !size) 124 | return false; 125 | 126 | SIZE_T bytes = 0; 127 | NTSTATUS status = STATUS_SUCCESS; 128 | PEPROCESS process; 129 | 130 | if ((HANDLE)pid == 0) return false; 131 | PsLookupProcessByProcessId((HANDLE)pid, &process); 132 | status = MmCopyVirtualMemory(process, (void*)address, (PEPROCESS)PsGetCurrentProcess(), (void*)buffer, size, KernelMode, &bytes); 133 | 134 | if (!NT_SUCCESS(status)) 135 | { 136 | return false; 137 | } 138 | else 139 | { 140 | return true; 141 | } 142 | } 143 | 144 | bool write_kernel_memory(HANDLE pid, uintptr_t address, void* buffer, SIZE_T size) 145 | { 146 | if (!address || !buffer || !size) 147 | return false; 148 | 149 | NTSTATUS status = STATUS_SUCCESS; 150 | PEPROCESS process; 151 | if ((HANDLE)pid == 0) return false; 152 | PsLookupProcessByProcessId((HANDLE)pid, &process); 153 | KAPC_STATE state; 154 | KeStackAttachProcess((PEPROCESS)process, &state); 155 | 156 | MEMORY_BASIC_INFORMATION info; 157 | 158 | status = ZwQueryVirtualMemory(ZwCurrentProcess(), (PVOID)address, MemoryBasicInformation, &info, sizeof(info), NULL); 159 | if (!NT_SUCCESS(status)) 160 | { 161 | KeUnstackDetachProcess(&state); 162 | return false; 163 | } 164 | 165 | if (((uintptr_t)info.BaseAddress + info.RegionSize) < (address + size)) 166 | { 167 | KeUnstackDetachProcess(&state); 168 | return false; 169 | } 170 | 171 | if (!(info.State & MEM_COMMIT) || (info.Protect & (PAGE_GUARD | PAGE_NOACCESS))) 172 | { 173 | KeUnstackDetachProcess(&state); 174 | return false; 175 | } 176 | 177 | if ((info.Protect & PAGE_EXECUTE_READWRITE) || (info.Protect & PAGE_EXECUTE_WRITECOPY) 178 | || (info.Protect & PAGE_READWRITE) || (info.Protect & PAGE_WRITECOPY)) 179 | { 180 | RtlCopyMemory((void*)address, buffer, size); 181 | } 182 | KeUnstackDetachProcess(&state); 183 | return true; 184 | } -------------------------------------------------------------------------------- /function.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "define.h" 3 | 4 | PVOID get_system_module_base(const char* module_name); 5 | PVOID get_system_module_export(const char* module_name, LPCSTR routine_name); 6 | bool write_memory(void* address, void* buffer, size_t size); 7 | bool write_to_read_only_memory(void* address, void* buffer, size_t size); 8 | ULONG64 get_module_base_x64(PEPROCESS proc, UNICODE_STRING module_name); 9 | bool read_kernel_memory(HANDLE pid, uintptr_t address, void* buffer, SIZE_T size); 10 | bool write_kernel_memory(HANDLE pid, uintptr_t address, void* buffer, SIZE_T size); 11 | 12 | typedef struct _NULL_MEMORY 13 | { 14 | void* buffer_address; 15 | UINT_PTR address; 16 | ULONGLONG size; 17 | ULONG pid; 18 | BOOLEAN write; 19 | BOOLEAN read; 20 | BOOLEAN req_base; 21 | void* output; 22 | const char* module_name; 23 | ULONG64 base_address; 24 | }NULL_MEMORY; -------------------------------------------------------------------------------- /hook.cpp: -------------------------------------------------------------------------------- 1 | #include "hook.h" 2 | 3 | bool call_kernel_function(void* kernel_function_address) 4 | { 5 | if (!kernel_function_address) 6 | return false; 7 | 8 | PVOID* function = reinterpret_cast(get_system_module_export("\\SystemRoot\\System32\\drivers\\dxgkrnl.sys", 9 | "NtOpenCompositionSurfaceSectionInfo")); // NtOpenCompositionSurfaceSectionInfo 10 | 11 | if (!function) 12 | return false; 13 | 14 | BYTE orig[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 15 | 16 | BYTE shell_code[] = { 0x48, 0xB8 }; // mov rax, xxx // 0x48 - 0xB8 17 | BYTE shell_code_end[] = { 0xFF, 0xE0 }; //jmp rax // 0xFF - 0xE0 18 | 19 | RtlSecureZeroMemory(&orig, sizeof(orig)); 20 | memcpy((PVOID)((ULONG_PTR)orig), &shell_code, sizeof(shell_code)); 21 | uintptr_t hook_address = reinterpret_cast(kernel_function_address); 22 | memcpy((PVOID)((ULONG_PTR)orig + sizeof(shell_code)), &hook_address, sizeof(void*)); 23 | memcpy((PVOID)((ULONG_PTR)orig + sizeof(shell_code) + sizeof(void*)), &shell_code_end, sizeof(shell_code_end)); 24 | 25 | write_to_read_only_memory(function, &orig, sizeof(orig)); 26 | 27 | return true; 28 | } 29 | 30 | NTSTATUS hook_handler(PVOID called_param) 31 | { 32 | NULL_MEMORY* instructions = (NULL_MEMORY*)called_param; 33 | 34 | if (instructions->req_base != FALSE) 35 | { 36 | ANSI_STRING AS; 37 | UNICODE_STRING ModuleName; 38 | 39 | RtlInitAnsiString(&AS, instructions->module_name); 40 | RtlAnsiStringToUnicodeString(&ModuleName, &AS, TRUE); 41 | 42 | PEPROCESS process; 43 | ULONG64 base_address64 = NULL; 44 | if ((HANDLE)instructions->pid != 0) { 45 | PsLookupProcessByProcessId((HANDLE)instructions->pid, &process); 46 | base_address64 = get_module_base_x64(process, ModuleName); 47 | } 48 | instructions->base_address = base_address64; 49 | RtlFreeUnicodeString(&ModuleName); 50 | } 51 | 52 | if (instructions->write != FALSE) 53 | { 54 | if (instructions->address < 0x7FFFFFFFFFFF && instructions->address > 0) 55 | { 56 | PVOID kernelBuff = ExAllocatePool(NonPagedPool, instructions->size); 57 | 58 | if (!kernelBuff) 59 | { 60 | return STATUS_UNSUCCESSFUL; 61 | } 62 | 63 | if (!memcpy(kernelBuff, instructions->buffer_address, instructions->size)) 64 | { 65 | return STATUS_UNSUCCESSFUL; 66 | } 67 | 68 | PEPROCESS process; 69 | if ((HANDLE)instructions->pid != 0) { 70 | PsLookupProcessByProcessId((HANDLE)instructions->pid, &process); 71 | write_kernel_memory((HANDLE)instructions->pid, instructions->address, kernelBuff, instructions->size); 72 | } 73 | ExFreePool(kernelBuff); 74 | } 75 | } 76 | 77 | if (instructions->read != FALSE) 78 | { 79 | if (instructions->address < 0x7FFFFFFFFFFF && instructions->address > 0) 80 | { 81 | read_kernel_memory((HANDLE)instructions->pid, instructions->address, instructions->output, instructions->size); 82 | } 83 | } 84 | 85 | return STATUS_SUCCESS; 86 | } -------------------------------------------------------------------------------- /hook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "function.h" 3 | 4 | bool call_kernel_function(void* kernel_function_address); 5 | NTSTATUS hook_handler(PVOID called_param); 6 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "hook.h" 2 | 3 | extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT driver_object, PUNICODE_STRING reg_path) 4 | { 5 | UNREFERENCED_PARAMETER(driver_object); 6 | UNREFERENCED_PARAMETER(reg_path); 7 | 8 | call_kernel_function(&hook_handler); 9 | 10 | return STATUS_SUCCESS; 11 | } --------------------------------------------------------------------------------