├── .gitignore ├── Driver ├── Driver.vcxproj ├── Driver.vcxproj.filters ├── Driver.vcxproj.user ├── includes.hpp ├── ioctl.hpp ├── main.cpp ├── memory.hpp └── undocumented.hpp ├── Dumper ├── Dumper │ ├── Dumper.vcxproj │ ├── Dumper.vcxproj.filters │ ├── Dumper.vcxproj.user │ ├── defs.h │ ├── driver.cpp │ ├── driver.hpp │ ├── dumper.cpp │ ├── dumper.h │ ├── engine.cpp │ ├── engine.h │ ├── generic.cpp │ ├── generic.h │ ├── includes.hpp │ ├── ioctl.hpp │ ├── main.cpp │ ├── memory.cpp │ ├── memory.h │ ├── utils.cpp │ ├── utils.h │ ├── wrappers.cpp │ └── wrappers.h └── include │ ├── fmt │ ├── core.h │ ├── format-inl.h │ ├── format.cc │ └── format.h │ ├── hash │ └── hash.h │ └── types.h ├── LICENSE ├── README.md └── RootKit.sln /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /Driver/Driver.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E} 39 | {1bc93793-694f-48fe-9372-81e2b05556fd} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | Driver 45 | 10.0.19041.0 46 | 47 | 48 | 49 | Windows10 50 | true 51 | WindowsKernelModeDriver10.0 52 | Driver 53 | KMDF 54 | Universal 55 | 56 | 57 | Windows10 58 | false 59 | WindowsKernelModeDriver10.0 60 | Driver 61 | KMDF 62 | Universal 63 | 64 | 65 | Windows10 66 | true 67 | WindowsKernelModeDriver10.0 68 | Driver 69 | KMDF 70 | Universal 71 | 72 | 73 | Windows10 74 | false 75 | WindowsKernelModeDriver10.0 76 | Driver 77 | KMDF 78 | Universal 79 | 80 | 81 | Windows10 82 | true 83 | WindowsKernelModeDriver10.0 84 | Driver 85 | KMDF 86 | Universal 87 | 88 | 89 | Windows10 90 | false 91 | WindowsKernelModeDriver10.0 92 | Driver 93 | KMDF 94 | Universal 95 | 96 | 97 | Windows10 98 | true 99 | WindowsKernelModeDriver10.0 100 | Driver 101 | KMDF 102 | Universal 103 | 104 | 105 | Windows10 106 | false 107 | WindowsKernelModeDriver10.0 108 | Driver 109 | KMDF 110 | Universal 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | DbgengKernelDebugger 122 | 123 | 124 | DbgengKernelDebugger 125 | 126 | 127 | DbgengKernelDebugger 128 | 129 | 130 | DbgengKernelDebugger 131 | false 132 | 133 | 134 | DbgengKernelDebugger 135 | 136 | 137 | DbgengKernelDebugger 138 | 139 | 140 | DbgengKernelDebugger 141 | 142 | 143 | DbgengKernelDebugger 144 | 145 | 146 | 147 | DriverEntry 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /Driver/Driver.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 | {8E41214B-6785-4CFE-B992-037D68949A14} 14 | inf;inv;inx;mof;mc; 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /Driver/Driver.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Off 5 | 6 | -------------------------------------------------------------------------------- /Driver/includes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | ULONG moduleSize; 5 | 6 | extern "C" NTSTATUS NTAPI MmCopyVirtualMemory(PEPROCESS SourceProcess, PVOID SourceAddress, PEPROCESS TargetProcess, PVOID TargetAddress, SIZE_T BufferSize, KPROCESSOR_MODE PreviousMode, PSIZE_T ReturnSize); 7 | extern "C" NTSTATUS NTAPI ZwProtectVirtualMemory(HANDLE ProcessHandle, PVOID * BaseAddress, SIZE_T * NumberOfBytesToProtect, ULONG NewAccessProtection, PULONG OldAccessProtection); 8 | extern "C" NTSTATUS NTAPI IoCreateDriver(PUNICODE_STRING DriverName, PDRIVER_INITIALIZE InitializationFunction); 9 | extern "C" PVOID NTAPI PsGetProcessSectionBaseAddress(__in PEPROCESS Process); 10 | extern "C" PPEB NTAPI PsGetProcessPeb(IN PEPROCESS Process); 11 | extern "C" PVOID PsGetProcessWow64Process(_In_ PEPROCESS Process); 12 | extern "C" NTSTATUS NTAPI ZwQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL); -------------------------------------------------------------------------------- /Driver/ioctl.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "includes.hpp" 3 | #include "undocumented.hpp" 4 | 5 | #define io_copy_memory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 6 | #define io_protect_memory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 7 | #define io_allocate_memory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x3, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 8 | #define io_free_memory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x4, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 9 | #define io_get_module_base_peb CTL_CODE(FILE_DEVICE_UNKNOWN, 0x5, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 10 | #define io_get_module_size CTL_CODE(FILE_DEVICE_UNKNOWN, 0x6, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 11 | 12 | typedef struct _copy_memory 13 | { 14 | INT32 pid; 15 | ULONGLONG address; 16 | ULONGLONG buffer; 17 | ULONGLONG size; 18 | BOOLEAN write; 19 | } copy_memory, *pcopy_memory; 20 | 21 | typedef struct _protect_memory 22 | { 23 | INT32 pid; 24 | ULONGLONG address; 25 | ULONGLONG size; 26 | DWORD32 new_protect; 27 | } protect_memory, *pprotect_memory; 28 | 29 | typedef struct _allocate_memory 30 | { 31 | INT32 pid; 32 | ULONGLONG address; 33 | ULONGLONG size; 34 | DWORD32 protect; 35 | } allocate_memory, *pallocate_memory; 36 | 37 | typedef struct _free_memory 38 | { 39 | INT32 pid; 40 | ULONGLONG address; 41 | } free_memory, *pfree_memory; 42 | 43 | typedef struct _get_module_base_peb 44 | { 45 | INT32 pid; 46 | ULONGLONG address; 47 | ULONG size; 48 | } get_module_base_peb, * pget_module_base_peb; -------------------------------------------------------------------------------- /Driver/main.cpp: -------------------------------------------------------------------------------- 1 | #include "memory.hpp" 2 | 3 | UNICODE_STRING DeviceName, SymbolicLink; 4 | 5 | NTSTATUS IoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) 6 | { 7 | UNREFERENCED_PARAMETER(DeviceObject); 8 | 9 | NTSTATUS Status = { }; 10 | ULONG BytesIO = { }; 11 | PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); 12 | 13 | ULONG ControlCode = Stack->Parameters.DeviceIoControl.IoControlCode; 14 | ULONG InputBufferLength = Stack->Parameters.DeviceIoControl.InputBufferLength; 15 | 16 | if (ControlCode == io_copy_memory) 17 | { 18 | if (InputBufferLength == sizeof(_copy_memory)) 19 | { 20 | pcopy_memory req = (pcopy_memory)(Irp->AssociatedIrp.SystemBuffer); 21 | 22 | Status = CopyVirtualMemory(req); 23 | BytesIO = sizeof(_copy_memory); 24 | } 25 | else 26 | { 27 | Status = STATUS_INFO_LENGTH_MISMATCH; 28 | BytesIO = 0; 29 | } 30 | } 31 | else if (ControlCode == io_protect_memory) 32 | { 33 | if (InputBufferLength == sizeof(_protect_memory)) 34 | { 35 | pprotect_memory req = (pprotect_memory)(Irp->AssociatedIrp.SystemBuffer); 36 | 37 | Status = ProtectVirtualMemory(req); 38 | BytesIO = sizeof(_protect_memory); 39 | } 40 | else 41 | { 42 | Status = STATUS_INFO_LENGTH_MISMATCH; 43 | BytesIO = 0; 44 | } 45 | } 46 | else if (ControlCode == io_allocate_memory) 47 | { 48 | if (InputBufferLength == sizeof(_allocate_memory)) 49 | { 50 | pallocate_memory req = (pallocate_memory)(Irp->AssociatedIrp.SystemBuffer); 51 | 52 | Status = AllocateVirtualMemory(req); 53 | BytesIO = sizeof(_allocate_memory); 54 | } 55 | else 56 | { 57 | Status = STATUS_INFO_LENGTH_MISMATCH; 58 | BytesIO = 0; 59 | } 60 | } 61 | else if (ControlCode == io_free_memory) 62 | { 63 | if (InputBufferLength == sizeof(_free_memory)) 64 | { 65 | pfree_memory req = (pfree_memory)(Irp->AssociatedIrp.SystemBuffer); 66 | 67 | Status = FreeVirtualMemory(req); 68 | BytesIO = sizeof(_free_memory); 69 | } 70 | else 71 | { 72 | Status = STATUS_INFO_LENGTH_MISMATCH; 73 | BytesIO = 0; 74 | } 75 | } 76 | else if (ControlCode == io_get_module_base_peb) 77 | { 78 | if (InputBufferLength == sizeof(_get_module_base_peb)) 79 | { 80 | pget_module_base_peb req = (pget_module_base_peb)(Irp->AssociatedIrp.SystemBuffer); 81 | 82 | Status = GetModuleBasePeb(req); 83 | BytesIO = sizeof(_get_module_base_peb); 84 | } 85 | else 86 | { 87 | Status = STATUS_INFO_LENGTH_MISMATCH; 88 | BytesIO = 0; 89 | } 90 | } 91 | else if (ControlCode == io_get_module_size) 92 | { 93 | PULONG OutPut = (PULONG)Irp->AssociatedIrp.SystemBuffer; 94 | *OutPut = moduleSize; 95 | 96 | Status = STATUS_SUCCESS; 97 | BytesIO = sizeof(*OutPut); 98 | } 99 | 100 | Irp->IoStatus.Status = Status; 101 | Irp->IoStatus.Information = BytesIO; 102 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 103 | 104 | return Status; 105 | } 106 | 107 | NTSTATUS UnsupportedDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) 108 | { 109 | UNREFERENCED_PARAMETER(DeviceObject); 110 | 111 | Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 112 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 113 | 114 | return Irp->IoStatus.Status; 115 | } 116 | 117 | NTSTATUS HandleDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) 118 | { 119 | UNREFERENCED_PARAMETER(DeviceObject); 120 | 121 | PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); 122 | 123 | switch (Stack->MajorFunction) 124 | { 125 | case IRP_MJ_CREATE: 126 | DbgPrint("[ RootKit ] Handle created to the symbolic link: %wZ\n", SymbolicLink); 127 | break; 128 | case IRP_MJ_CLOSE: 129 | DbgPrint("[ RootKit ] Handle closed to the symbolic link: %wZ\n", SymbolicLink); 130 | break; 131 | default: 132 | break; 133 | } 134 | 135 | IoCompleteRequest(Irp, IO_NO_INCREMENT); 136 | return Irp->IoStatus.Status; 137 | } 138 | 139 | VOID Unload(PDRIVER_OBJECT DriverObject) 140 | { 141 | NTSTATUS Status = { }; 142 | 143 | Status = IoDeleteSymbolicLink(&SymbolicLink); 144 | 145 | if (!NT_SUCCESS(Status)) 146 | { 147 | DbgPrint("[ RootKit ] Unable to delete the symbolic link, status: %X\n", Status); 148 | return; 149 | } 150 | 151 | IoDeleteDevice(DriverObject->DeviceObject); 152 | 153 | DbgPrint("[ RootKit ] Driver unloaded\n"); 154 | } 155 | 156 | NTSTATUS DriverInitialize(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) 157 | { 158 | UNREFERENCED_PARAMETER(RegistryPath); 159 | 160 | NTSTATUS Status = { }; 161 | PDEVICE_OBJECT DeviceObject = { }; 162 | 163 | RtlInitUnicodeString(&DeviceName, L"\\Device\\Xo1337GodPaster"); 164 | RtlInitUnicodeString(&SymbolicLink, L"\\DosDevices\\Xo1337GodPaster"); 165 | 166 | Status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject); 167 | 168 | if (!NT_SUCCESS(Status)) 169 | { 170 | DbgPrint("[ RootKit ] Unable to create device, status: %X\n", Status); 171 | return Status; 172 | } 173 | 174 | Status = IoCreateSymbolicLink(&SymbolicLink, &DeviceName); 175 | 176 | if (!NT_SUCCESS(Status)) 177 | { 178 | DbgPrint("[ RootKit ] Unable to create symbolic link, status: %X\n", Status); 179 | return Status; 180 | } 181 | 182 | for (int i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) 183 | DriverObject->MajorFunction[i] = &UnsupportedDispatch; 184 | 185 | DeviceObject->Flags |= DO_BUFFERED_IO; 186 | 187 | DriverObject->MajorFunction[IRP_MJ_CREATE] = &HandleDispatch; 188 | DriverObject->MajorFunction[IRP_MJ_CLOSE] = &HandleDispatch; 189 | DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &IoControl; 190 | DriverObject->DriverUnload = &Unload; 191 | 192 | DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 193 | 194 | return Status; 195 | } 196 | 197 | NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) 198 | { 199 | UNREFERENCED_PARAMETER(DriverObject); 200 | UNREFERENCED_PARAMETER(RegistryPath); 201 | 202 | return IoCreateDriver(NULL, &DriverInitialize); 203 | } 204 | -------------------------------------------------------------------------------- /Driver/memory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ioctl.hpp" 3 | #include 4 | 5 | NTSTATUS CopyVirtualMemory(pcopy_memory req) 6 | { 7 | NTSTATUS Status = { }; 8 | SIZE_T Bytes = { }; 9 | PEPROCESS TargetProcess = { }; 10 | 11 | Status = PsLookupProcessByProcessId((HANDLE)req->pid, &TargetProcess); 12 | 13 | if (!NT_SUCCESS(Status)) 14 | { 15 | DbgPrint("[ RootKit ] Unable to find process id: %X\n", Status); 16 | return Status; 17 | } 18 | 19 | BOOLEAN bWrite = req->write; 20 | 21 | if (bWrite) 22 | { 23 | Status = MmCopyVirtualMemory(IoGetCurrentProcess(), (PVOID)req->buffer, TargetProcess, (PVOID)req->address, req->size, UserMode, &Bytes); 24 | } 25 | else 26 | { 27 | Status = MmCopyVirtualMemory(TargetProcess, (PVOID)req->address, IoGetCurrentProcess(), (PVOID)req->buffer, req->size, UserMode, &Bytes); 28 | } 29 | 30 | if (!NT_SUCCESS(Status)) 31 | { 32 | DbgPrint("[ RootKit ] Unable to copy virtual memory: %X\n", Status); 33 | return Status; 34 | } 35 | 36 | ObfDereferenceObject(TargetProcess); 37 | return Status; 38 | } 39 | 40 | NTSTATUS ProtectVirtualMemory(pprotect_memory req) 41 | { 42 | NTSTATUS Status = { }; 43 | PEPROCESS TargetProcess = { }; 44 | KAPC_STATE ApcState = { }; 45 | 46 | Status = PsLookupProcessByProcessId((HANDLE)req->pid, &TargetProcess); 47 | 48 | if (!NT_SUCCESS(Status)) 49 | { 50 | DbgPrint("[ RootKit ] Unable to find process id: %X\n", Status); 51 | return Status; 52 | } 53 | 54 | KeStackAttachProcess(TargetProcess, &ApcState); 55 | 56 | PVOID BaseAddress = (PVOID)req->address; 57 | SIZE_T RegionSize = req->size; 58 | 59 | Status = ZwProtectVirtualMemory(ZwCurrentProcess(), &BaseAddress, &RegionSize, PAGE_EXECUTE_READWRITE, NULL); // if you want to pass protection via user mode, replace the fourth argument with req->new_protect 60 | 61 | if (!NT_SUCCESS(Status)) 62 | { 63 | DbgPrint("[ RootKit ] Unable to change page protection: %X\n", Status); 64 | return Status; 65 | } 66 | 67 | KeUnstackDetachProcess(&ApcState); 68 | ObfDereferenceObject(TargetProcess); 69 | 70 | return Status; 71 | } 72 | 73 | NTSTATUS AllocateVirtualMemory(pallocate_memory req) 74 | { 75 | NTSTATUS Status = { }; 76 | PEPROCESS TargetProcess = { }; 77 | 78 | Status = PsLookupProcessByProcessId((HANDLE)req->pid, &TargetProcess); 79 | 80 | if (!NT_SUCCESS(Status)) 81 | { 82 | DbgPrint("[ RootKit ] Unable to find process id: %X\n", Status); 83 | return Status; 84 | } 85 | 86 | KeAttachProcess(TargetProcess); 87 | 88 | PVOID BaseAddress = 0; 89 | SIZE_T RegionSize = req->size; 90 | 91 | Status = ZwAllocateVirtualMemory((HANDLE)-1, &BaseAddress, 0, &RegionSize, 0x3000, req->protect); 92 | MmSecureVirtualMemory(BaseAddress, RegionSize, 4); 93 | 94 | if (!NT_SUCCESS(Status)) 95 | { 96 | DbgPrint("[ RootKit ] Unable to allocate memory: %X\n", Status); 97 | return Status; 98 | } 99 | 100 | req->address = (ULONGLONG)BaseAddress; 101 | 102 | DbgPrint("[ RootKit ] %llx\n", (uintptr_t)req->address); 103 | 104 | KeDetachProcess(); 105 | ObfDereferenceObject(TargetProcess); 106 | 107 | return Status; 108 | } 109 | 110 | NTSTATUS FreeVirtualMemory(pfree_memory req) 111 | { 112 | NTSTATUS Status = { }; 113 | PEPROCESS TargetProcess = { }; 114 | 115 | Status = PsLookupProcessByProcessId((HANDLE)req->pid, &TargetProcess); 116 | 117 | if (!NT_SUCCESS(Status)) 118 | { 119 | DbgPrint("[ RootKit ] Unable to find process id: %X\n", Status); 120 | return Status; 121 | } 122 | 123 | PVOID BaseAddress = (PVOID)req->address; 124 | SIZE_T RegionSize = 0; 125 | 126 | Status = ZwFreeVirtualMemory(ZwCurrentProcess(), &BaseAddress, &RegionSize, MEM_RELEASE); 127 | 128 | if (!NT_SUCCESS(Status)) 129 | { 130 | DbgPrint("[ RootKit ] Unable to free the memory page: %X\n", Status); 131 | return Status; 132 | } 133 | 134 | ObfDereferenceObject(TargetProcess); 135 | 136 | return Status; 137 | } 138 | 139 | MODULEENTRY GetProcessModule(PEPROCESS Process, IN PUNICODE_STRING ModuleName) 140 | { 141 | KAPC_STATE KAPC = { 0 }; 142 | MODULEENTRY ret = { 0, 0 }; 143 | 144 | KeStackAttachProcess(Process, &KAPC); 145 | __try 146 | { 147 | LARGE_INTEGER time = { 0 }; 148 | time.QuadPart = -250ll * 10 * 1000; // 250 msec. 149 | 150 | PPEB peb = (PPEB)PsGetProcessPeb(Process); 151 | if (!peb) 152 | { 153 | DbgPrint("!peb\n"); 154 | KeUnstackDetachProcess(&KAPC); 155 | return ret; 156 | } 157 | 158 | // Wait for loader a bit 159 | for (INT i = 0; !peb->Ldr && i < 10; i++) 160 | { 161 | DbgPrint("Loader not intialiezd, waiting\n"); 162 | KeDelayExecutionThread(KernelMode, TRUE, &time); 163 | } 164 | 165 | if (!peb->Ldr) 166 | { 167 | KeUnstackDetachProcess(&KAPC); 168 | return ret; 169 | } 170 | 171 | for (PLIST_ENTRY pListEntry = peb->Ldr->InLoadOrderModuleList.Flink; 172 | pListEntry != &peb->Ldr->InLoadOrderModuleList; 173 | pListEntry = pListEntry->Flink) 174 | { 175 | PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 176 | if (RtlCompareUnicodeString(&pEntry->BaseDllName, ModuleName, TRUE) == 0) 177 | { 178 | DbgPrint("FOUND\n"); 179 | ret.Address = (ULONGLONG)pEntry->DllBase; 180 | ret.Size = pEntry->SizeOfImage; 181 | break; 182 | } 183 | } 184 | } 185 | __except (EXCEPTION_EXECUTE_HANDLER) 186 | { 187 | DbgPrint("%s: Exception, Code: 0x%X\n", __FUNCTION__, GetExceptionCode()); 188 | } 189 | 190 | KeUnstackDetachProcess(&KAPC); 191 | 192 | return ret; 193 | } 194 | 195 | NTSTATUS GetModuleBasePeb(pget_module_base_peb req) 196 | { 197 | NTSTATUS Status = { }; 198 | PEPROCESS TargetProcess = { }; 199 | 200 | Status = PsLookupProcessByProcessId((HANDLE)req->pid, &TargetProcess); 201 | 202 | if (!NT_SUCCESS(Status)) 203 | { 204 | DbgPrint("[ RootKit ] Unable to find process id: %X\n", Status); 205 | return Status; 206 | } 207 | 208 | KeAttachProcess(TargetProcess); 209 | 210 | UNICODE_STRING ustrNtdll; 211 | RtlUnicodeStringInit(&ustrNtdll, L"POLYGON-Win64-Shipping.exe"); // todo: pass value from usermode 212 | 213 | MODULEENTRY ClientEntry = GetProcessModule(TargetProcess, &ustrNtdll); 214 | 215 | req->address = ClientEntry.Address; 216 | req->size = ClientEntry.Size; 217 | moduleSize = req->size; 218 | 219 | DbgPrint("[ RootKit ] %llx\n", (uintptr_t)req->address); 220 | 221 | KeDetachProcess(); 222 | ObfDereferenceObject(TargetProcess); 223 | 224 | return Status; 225 | } 226 | -------------------------------------------------------------------------------- /Driver/undocumented.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma warning (disable : 4201) 3 | #include 4 | #include 5 | 6 | typedef struct _SYSTEM_SERVICE_DESCRIPTOR_TABLE 7 | { 8 | PULONG_PTR ServiceTableBase; 9 | PULONG ServiceCounterTableBase; 10 | ULONG_PTR NumberOfServices; 11 | PUCHAR ParamTableBase; 12 | } SYSTEM_SERVICE_DESCRIPTOR_TABLE, * PSYSTEM_SERVICE_DESCRIPTOR_TABLE; 13 | 14 | typedef union _PS_PROTECTION 15 | { 16 | UCHAR Level; 17 | struct 18 | { 19 | int Type : 3; 20 | int Audit : 1; 21 | int Signer : 4; 22 | } Flags; 23 | } PS_PROTECTION, * PPS_PROTECTION; 24 | 25 | typedef union _KEXECUTE_OPTIONS 26 | { 27 | struct 28 | { 29 | int ExecuteDisable : 1; // 0x01 30 | int ExecuteEnable : 1; // 0x02 31 | int DisableThunkEmulation : 1; // 0x04 32 | int Permanent : 1; // 0x08 33 | int ExecuteDispatchEnable : 1; // 0x10 34 | int ImageDispatchEnable : 1; // 0x20 35 | int DisableExceptionChainValidation : 1; // 0x40 36 | int Spare : 1; 37 | } Flags; 38 | 39 | UCHAR ExecuteOptions; 40 | } KEXECUTE_OPTIONS, * PKEXECUTE_OPTIONS; 41 | 42 | typedef struct _EPROCESS_FLAGS2 43 | { 44 | unsigned int JobNotReallyActive : 1; 45 | unsigned int AccountingFolded : 1; 46 | unsigned int NewProcessReported : 1; 47 | unsigned int ExitProcessReported : 1; 48 | unsigned int ReportCommitChanges : 1; 49 | unsigned int LastReportMemory : 1; 50 | unsigned int ForceWakeCharge : 1; 51 | unsigned int CrossSessionCreate : 1; 52 | unsigned int NeedsHandleRundown : 1; 53 | unsigned int RefTraceEnabled : 1; 54 | unsigned int DisableDynamicCode : 1; 55 | unsigned int EmptyJobEvaluated : 1; 56 | unsigned int DefaultPagePriority : 3; 57 | unsigned int PrimaryTokenFrozen : 1; 58 | unsigned int ProcessVerifierTarget : 1; 59 | unsigned int StackRandomizationDisabled : 1; 60 | unsigned int AffinityPermanent : 1; 61 | unsigned int AffinityUpdateEnable : 1; 62 | unsigned int PropagateNode : 1; 63 | unsigned int ExplicitAffinity : 1; 64 | unsigned int ProcessExecutionState : 2; 65 | unsigned int DisallowStrippedImages : 1; 66 | unsigned int HighEntropyASLREnabled : 1; 67 | unsigned int ExtensionPointDisable : 1; 68 | unsigned int ForceRelocateImages : 1; 69 | unsigned int ProcessStateChangeRequest : 2; 70 | unsigned int ProcessStateChangeInProgress : 1; 71 | unsigned int DisallowWin32kSystemCalls : 1; 72 | } EPROCESS_FLAGS2, * PEPROCESS_FLAGS2; 73 | 74 | typedef struct _MITIGATION_FLAGS 75 | { 76 | unsigned int ControlFlowGuardEnabled : 1; 77 | unsigned int ControlFlowGuardExportSuppressionEnabled : 1; 78 | unsigned int ControlFlowGuardStrict : 1; 79 | unsigned int DisallowStrippedImages : 1; 80 | unsigned int ForceRelocateImages : 1; 81 | unsigned int HighEntropyASLREnabled : 1; 82 | unsigned int StackRandomizationDisabled : 1; 83 | unsigned int ExtensionPointDisable : 1; 84 | unsigned int DisableDynamicCode : 1; 85 | unsigned int DisableDynamicCodeAllowOptOut : 1; 86 | unsigned int DisableDynamicCodeAllowRemoteDowngrade : 1; 87 | unsigned int AuditDisableDynamicCode : 1; 88 | unsigned int DisallowWin32kSystemCalls : 1; 89 | unsigned int AuditDisallowWin32kSystemCalls : 1; 90 | unsigned int EnableFilteredWin32kAPIs : 1; 91 | unsigned int AuditFilteredWin32kAPIs : 1; 92 | unsigned int DisableNonSystemFonts : 1; 93 | unsigned int AuditNonSystemFontLoading : 1; 94 | unsigned int PreferSystem32Images : 1; 95 | unsigned int ProhibitRemoteImageMap : 1; 96 | unsigned int AuditProhibitRemoteImageMap : 1; 97 | unsigned int ProhibitLowILImageMap : 1; 98 | unsigned int AuditProhibitLowILImageMap : 1; 99 | unsigned int SignatureMitigationOptIn : 1; 100 | unsigned int AuditBlockNonMicrosoftBinaries : 1; 101 | unsigned int AuditBlockNonMicrosoftBinariesAllowStore : 1; 102 | unsigned int LoaderIntegrityContinuityEnabled : 1; 103 | unsigned int AuditLoaderIntegrityContinuity : 1; 104 | unsigned int EnableModuleTamperingProtection : 1; 105 | unsigned int EnableModuleTamperingProtectionNoInherit : 1; 106 | unsigned int RestrictIndirectBranchPrediction; 107 | unsigned int IsolateSecurityDomain; 108 | } MITIGATION_FLAGS, * PMITIGATION_FLAGS; 109 | 110 | typedef union _EXHANDLE 111 | { 112 | struct 113 | { 114 | int TagBits : 2; 115 | int Index : 30; 116 | } u; 117 | void* GenericHandleOverlay; 118 | ULONG_PTR Value; 119 | } EXHANDLE, * PEXHANDLE; 120 | 121 | #pragma warning(disable : 4214 4201) 122 | 123 | #pragma pack(push, 1) 124 | typedef struct _POOL_HEADER // Size=16 125 | { 126 | union 127 | { 128 | struct 129 | { 130 | unsigned long PreviousSize : 8; // Size=4 Offset=0 BitOffset=0 BitCount=8 131 | unsigned long PoolIndex : 8; // Size=4 Offset=0 BitOffset=8 BitCount=8 132 | unsigned long BlockSize : 8; // Size=4 Offset=0 BitOffset=16 BitCount=8 133 | unsigned long PoolType : 8; // Size=4 Offset=0 BitOffset=24 BitCount=8 134 | }; 135 | unsigned long Ulong1; // Size=4 Offset=0 136 | }; 137 | unsigned long PoolTag; // Size=4 Offset=4 138 | union 139 | { 140 | struct _EPROCESS* ProcessBilled; // Size=8 Offset=8 141 | struct 142 | { 143 | unsigned short AllocatorBackTraceIndex; // Size=2 Offset=8 144 | unsigned short PoolTagHash; // Size=2 Offset=10 145 | }; 146 | }; 147 | } POOL_HEADER, * PPOOL_HEADER; 148 | #pragma pack(pop) 149 | 150 | typedef struct _HANDLE_TABLE_ENTRY // Size=16 151 | { 152 | union 153 | { 154 | ULONG_PTR VolatileLowValue; // Size=8 Offset=0 155 | ULONG_PTR LowValue; // Size=8 Offset=0 156 | struct _HANDLE_TABLE_ENTRY_INFO* InfoTable; // Size=8 Offset=0 157 | struct 158 | { 159 | ULONG_PTR Unlocked : 1; // Size=8 Offset=0 BitOffset=0 BitCount=1 160 | ULONG_PTR RefCnt : 16; // Size=8 Offset=0 BitOffset=1 BitCount=16 161 | ULONG_PTR Attributes : 3; // Size=8 Offset=0 BitOffset=17 BitCount=3 162 | ULONG_PTR ObjectPointerBits : 44; // Size=8 Offset=0 BitOffset=20 BitCount=44 163 | }; 164 | }; 165 | union 166 | { 167 | ULONG_PTR HighValue; // Size=8 Offset=8 168 | struct _HANDLE_TABLE_ENTRY* NextFreeHandleEntry; // Size=8 Offset=8 169 | union _EXHANDLE LeafHandleValue; // Size=8 Offset=8 170 | struct 171 | { 172 | ULONG GrantedAccessBits : 25; // Size=4 Offset=8 BitOffset=0 BitCount=25 173 | ULONG NoRightsUpgrade : 1; // Size=4 Offset=8 BitOffset=25 BitCount=1 174 | ULONG Spare : 6; // Size=4 Offset=8 BitOffset=26 BitCount=6 175 | }; 176 | }; 177 | ULONG TypeInfo; // Size=4 Offset=12 178 | } HANDLE_TABLE_ENTRY, * PHANDLE_TABLE_ENTRY; 179 | 180 | 181 | 182 | typedef struct _OBJECT_HEADER // Size=56 183 | { 184 | ULONG_PTR PointerCount; // Size=8 Offset=0 185 | union 186 | { 187 | ULONG_PTR HandleCount; // Size=8 Offset=8 188 | void* NextToFree; // Size=8 Offset=8 189 | }; 190 | void* Lock; // Size=8 Offset=16 191 | UCHAR TypeIndex; // Size=1 Offset=24 192 | union 193 | { 194 | UCHAR TraceFlags; // Size=1 Offset=25 195 | struct 196 | { 197 | UCHAR DbgRefTrace : 1; // Size=1 Offset=25 BitOffset=0 BitCount=1 198 | UCHAR DbgTracePermanent : 1; // Size=1 Offset=25 BitOffset=1 BitCount=1 199 | }; 200 | }; 201 | UCHAR InfoMask; // Size=1 Offset=26 202 | union 203 | { 204 | UCHAR Flags; // Size=1 Offset=27 205 | struct 206 | { 207 | UCHAR NewObject : 1; // Size=1 Offset=27 BitOffset=0 BitCount=1 208 | UCHAR KernelObject : 1; // Size=1 Offset=27 BitOffset=1 BitCount=1 209 | UCHAR KernelOnlyAccess : 1; // Size=1 Offset=27 BitOffset=2 BitCount=1 210 | UCHAR ExclusiveObject : 1; // Size=1 Offset=27 BitOffset=3 BitCount=1 211 | UCHAR PermanentObject : 1; // Size=1 Offset=27 BitOffset=4 BitCount=1 212 | UCHAR DefaultSecurityQuota : 1; // Size=1 Offset=27 BitOffset=5 BitCount=1 213 | UCHAR SingleHandleEntry : 1; // Size=1 Offset=27 BitOffset=6 BitCount=1 214 | UCHAR DeletedInline : 1; // Size=1 Offset=27 BitOffset=7 BitCount=1 215 | }; 216 | }; 217 | ULONG Spare; // Size=4 Offset=28 218 | union 219 | { 220 | struct _OBJECT_CREATE_INFORMATION* ObjectCreateInfo; // Size=8 Offset=32 221 | void* QuotaBlockCharged; // Size=8 Offset=32 222 | }; 223 | void* SecurityDescriptor; // Size=8 Offset=40 224 | struct _QUAD Body; // Size=8 Offset=48 225 | } OBJECT_HEADER, * POBJECT_HEADER; 226 | 227 | typedef union _EX_FAST_REF // Size=8 228 | { 229 | void* Object; 230 | struct 231 | { 232 | unsigned __int64 RefCnt : 4; 233 | }; 234 | unsigned __int64 Value; 235 | } EX_FAST_REF, * PEX_FAST_REF; 236 | 237 | typedef struct _CONTROL_AREA // Size=120 238 | { 239 | struct _SEGMENT* Segment; 240 | struct _LIST_ENTRY ListHead; 241 | unsigned __int64 NumberOfSectionReferences; 242 | unsigned __int64 NumberOfPfnReferences; 243 | unsigned __int64 NumberOfMappedViews; 244 | unsigned __int64 NumberOfUserReferences; 245 | unsigned long f1; 246 | unsigned long f2; 247 | EX_FAST_REF FilePointer; 248 | // Other fields 249 | } CONTROL_AREA, * PCONTROL_AREA; 250 | 251 | typedef struct _SUBSECTION // Size=56 252 | { 253 | PCONTROL_AREA ControlArea; 254 | // Other fields 255 | } SUBSECTION, * PSUBSECTION; 256 | 257 | typedef struct _MEMORY_BASIC_INFORMATION_EX 258 | { 259 | PVOID BaseAddress; 260 | PVOID AllocationBase; 261 | ULONG AllocationProtect; 262 | SIZE_T RegionSize; 263 | ULONG State; 264 | ULONG Protect; 265 | ULONG Type; 266 | } MEMORY_BASIC_INFORMATION_EX, * PMEMORY_BASIC_INFORMATION_EX; 267 | 268 | typedef struct _SYSTEM_CALL_COUNT_INFORMATION 269 | { 270 | ULONG Length; 271 | ULONG NumberOfTables; 272 | ULONG limits[2]; 273 | } SYSTEM_CALL_COUNT_INFORMATION, * PSYSTEM_CALL_COUNT_INFORMATION; 274 | 275 | typedef struct _SYSTEM_THREAD_INFORMATION 276 | { 277 | LARGE_INTEGER KernelTime; 278 | LARGE_INTEGER UserTime; 279 | LARGE_INTEGER CreateTime; 280 | ULONG WaitTime; 281 | PVOID StartAddress; 282 | CLIENT_ID ClientId; 283 | KPRIORITY Priority; 284 | LONG BasePriority; 285 | ULONG ContextSwitches; 286 | ULONG ThreadState; 287 | KWAIT_REASON WaitReason; 288 | }SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION; 289 | 290 | typedef struct _THREAD_BASIC_INFORMATION 291 | { 292 | NTSTATUS ExitStatus; 293 | PVOID TebBaseAddress; 294 | CLIENT_ID ClientId; 295 | ULONG_PTR AffinityMask; 296 | LONG Priority; 297 | LONG BasePriority; 298 | } THREAD_BASIC_INFORMATION, * PTHREAD_BASIC_INFORMATION; 299 | 300 | typedef struct _SYSTEM_PROCESS_INFO 301 | { 302 | ULONG NextEntryOffset; 303 | ULONG NumberOfThreads; 304 | LARGE_INTEGER WorkingSetPrivateSize; 305 | ULONG HardFaultCount; 306 | ULONG NumberOfThreadsHighWatermark; 307 | ULONGLONG CycleTime; 308 | LARGE_INTEGER CreateTime; 309 | LARGE_INTEGER UserTime; 310 | LARGE_INTEGER KernelTime; 311 | UNICODE_STRING ImageName; 312 | KPRIORITY BasePriority; 313 | HANDLE UniqueProcessId; 314 | HANDLE InheritedFromUniqueProcessId; 315 | ULONG HandleCount; 316 | ULONG SessionId; 317 | ULONG_PTR UniqueProcessKey; 318 | SIZE_T PeakVirtualSize; 319 | SIZE_T VirtualSize; 320 | ULONG PageFaultCount; 321 | SIZE_T PeakWorkingSetSize; 322 | SIZE_T WorkingSetSize; 323 | SIZE_T QuotaPeakPagedPoolUsage; 324 | SIZE_T QuotaPagedPoolUsage; 325 | SIZE_T QuotaPeakNonPagedPoolUsage; 326 | SIZE_T QuotaNonPagedPoolUsage; 327 | SIZE_T PagefileUsage; 328 | SIZE_T PeakPagefileUsage; 329 | SIZE_T PrivatePageCount; 330 | LARGE_INTEGER ReadOperationCount; 331 | LARGE_INTEGER WriteOperationCount; 332 | LARGE_INTEGER OtherOperationCount; 333 | LARGE_INTEGER ReadTransferCount; 334 | LARGE_INTEGER WriteTransferCount; 335 | LARGE_INTEGER OtherTransferCount; 336 | SYSTEM_THREAD_INFORMATION Threads[1]; 337 | }SYSTEM_PROCESS_INFO, * PSYSTEM_PROCESS_INFO; 338 | 339 | #pragma warning(disable : 4214) 340 | typedef struct _MMPTE_HARDWARE64 341 | { 342 | ULONGLONG Valid : 1; 343 | ULONGLONG Dirty1 : 1; 344 | ULONGLONG Owner : 1; 345 | ULONGLONG WriteThrough : 1; 346 | ULONGLONG CacheDisable : 1; 347 | ULONGLONG Accessed : 1; 348 | ULONGLONG Dirty : 1; 349 | ULONGLONG LargePage : 1; 350 | ULONGLONG Global : 1; 351 | ULONGLONG CopyOnWrite : 1; 352 | ULONGLONG Unused : 1; 353 | ULONGLONG Write : 1; 354 | ULONGLONG PageFrameNumber : 36; 355 | ULONGLONG reserved1 : 4; 356 | ULONGLONG SoftwareWsIndex : 11; 357 | ULONGLONG NoExecute : 1; 358 | } MMPTE_HARDWARE64, * PMMPTE_HARDWARE64; 359 | 360 | typedef struct _MMPTE 361 | { 362 | union 363 | { 364 | ULONG_PTR Long; 365 | MMPTE_HARDWARE64 Hard; 366 | } u; 367 | } MMPTE; 368 | typedef MMPTE* PMMPTE; 369 | 370 | #pragma warning(default : 4214) 371 | 372 | typedef struct _NT_PROC_THREAD_ATTRIBUTE_ENTRY 373 | { 374 | ULONG Attribute; // PROC_THREAD_ATTRIBUTE_XXX 375 | SIZE_T Size; 376 | ULONG_PTR Value; 377 | ULONG Unknown; 378 | } NT_PROC_THREAD_ATTRIBUTE_ENTRY, * NT_PPROC_THREAD_ATTRIBUTE_ENTRY; 379 | 380 | typedef struct _NT_PROC_THREAD_ATTRIBUTE_LIST 381 | { 382 | ULONG Length; 383 | NT_PROC_THREAD_ATTRIBUTE_ENTRY Entry[1]; 384 | } NT_PROC_THREAD_ATTRIBUTE_LIST, * PNT_PROC_THREAD_ATTRIBUTE_LIST; 385 | 386 | 387 | typedef struct _RTL_PROCESS_MODULE_INFORMATION 388 | { 389 | HANDLE Section; // Not filled in 390 | PVOID MappedBase; 391 | PVOID ImageBase; 392 | ULONG ImageSize; 393 | ULONG Flags; 394 | USHORT LoadOrderIndex; 395 | USHORT InitOrderIndex; 396 | USHORT LoadCount; 397 | USHORT OffsetToFileName; 398 | UCHAR FullPathName[MAXIMUM_FILENAME_LENGTH]; 399 | } RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION; 400 | 401 | typedef struct _RTL_PROCESS_MODULES 402 | { 403 | ULONG NumberOfModules; 404 | RTL_PROCESS_MODULE_INFORMATION Modules[1]; 405 | } RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES; 406 | 407 | #pragma warning(disable : 4214) 408 | typedef union _MEMORY_WORKING_SET_EX_BLOCK 409 | { 410 | ULONG_PTR Flags; 411 | struct 412 | { 413 | ULONG_PTR Valid : 1; 414 | ULONG_PTR ShareCount : 3; 415 | ULONG_PTR Win32Protection : 11; 416 | ULONG_PTR Shared : 1; 417 | ULONG_PTR Node : 6; 418 | ULONG_PTR Locked : 1; 419 | ULONG_PTR LargePage : 1; 420 | ULONG_PTR Reserved : 7; 421 | ULONG_PTR Bad : 1; 422 | 423 | #if defined(_WIN64) 424 | ULONG_PTR ReservedUlong : 32; 425 | #endif 426 | }; 427 | } MEMORY_WORKING_SET_EX_BLOCK, * PMEMORY_WORKING_SET_EX_BLOCK; 428 | 429 | typedef struct _MEMORY_WORKING_SET_EX_INFORMATION 430 | { 431 | PVOID VirtualAddress; 432 | MEMORY_WORKING_SET_EX_BLOCK VirtualAttributes; 433 | } MEMORY_WORKING_SET_EX_INFORMATION, * PMEMORY_WORKING_SET_EX_INFORMATION; 434 | 435 | #pragma warning(default : 4214) 436 | 437 | 438 | typedef struct _PEB_LDR_DATA 439 | { 440 | ULONG Length; 441 | UCHAR Initialized; 442 | PVOID SsHandle; 443 | LIST_ENTRY InLoadOrderModuleList; 444 | LIST_ENTRY InMemoryOrderModuleList; 445 | LIST_ENTRY InInitializationOrderModuleList; 446 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 447 | 448 | typedef struct _LDR_DATA_TABLE_ENTRY 449 | { 450 | LIST_ENTRY InLoadOrderLinks; 451 | LIST_ENTRY InMemoryOrderLinks; 452 | LIST_ENTRY InInitializationOrderLinks; 453 | PVOID DllBase; 454 | PVOID EntryPoint; 455 | ULONG SizeOfImage; 456 | UNICODE_STRING FullDllName; 457 | UNICODE_STRING BaseDllName; 458 | ULONG Flags; 459 | USHORT LoadCount; 460 | USHORT TlsIndex; 461 | LIST_ENTRY HashLinks; 462 | ULONG TimeDateStamp; 463 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 464 | 465 | 466 | typedef struct _PEB 467 | { 468 | UCHAR InheritedAddressSpace; 469 | UCHAR ReadImageFileExecOptions; 470 | UCHAR BeingDebugged; 471 | UCHAR BitField; 472 | PVOID Mutant; 473 | PVOID ImageBaseAddress; 474 | PPEB_LDR_DATA Ldr; 475 | PVOID ProcessParameters; 476 | PVOID SubSystemData; 477 | PVOID ProcessHeap; 478 | PVOID FastPebLock; 479 | PVOID AtlThunkSListPtr; 480 | PVOID IFEOKey; 481 | PVOID CrossProcessFlags; 482 | PVOID KernelCallbackTable; 483 | ULONG SystemReserved; 484 | ULONG AtlThunkSListPtr32; 485 | PVOID ApiSetMap; 486 | } PEB, * PPEB; 487 | 488 | typedef struct _PEB_LDR_DATA32 489 | { 490 | ULONG Length; 491 | UCHAR Initialized; 492 | ULONG SsHandle; 493 | LIST_ENTRY32 InLoadOrderModuleList; 494 | LIST_ENTRY32 InMemoryOrderModuleList; 495 | LIST_ENTRY32 InInitializationOrderModuleList; 496 | } PEB_LDR_DATA32, * PPEB_LDR_DATA32; 497 | 498 | typedef struct _LDR_DATA_TABLE_ENTRY32 499 | { 500 | LIST_ENTRY32 InLoadOrderLinks; 501 | LIST_ENTRY32 InMemoryOrderLinks; 502 | LIST_ENTRY32 InInitializationOrderLinks; 503 | ULONG DllBase; 504 | ULONG EntryPoint; 505 | ULONG SizeOfImage; 506 | UNICODE_STRING32 FullDllName; 507 | UNICODE_STRING32 BaseDllName; 508 | ULONG Flags; 509 | USHORT LoadCount; 510 | USHORT TlsIndex; 511 | LIST_ENTRY32 HashLinks; 512 | ULONG TimeDateStamp; 513 | } LDR_DATA_TABLE_ENTRY32, * PLDR_DATA_TABLE_ENTRY32; 514 | 515 | typedef struct _PEB32 516 | { 517 | UCHAR InheritedAddressSpace; 518 | UCHAR ReadImageFileExecOptions; 519 | UCHAR BeingDebugged; 520 | UCHAR BitField; 521 | ULONG Mutant; 522 | ULONG ImageBaseAddress; 523 | ULONG Ldr; 524 | ULONG ProcessParameters; 525 | ULONG SubSystemData; 526 | ULONG ProcessHeap; 527 | ULONG FastPebLock; 528 | ULONG AtlThunkSListPtr; 529 | ULONG IFEOKey; 530 | ULONG CrossProcessFlags; 531 | ULONG UserSharedInfoPtr; 532 | ULONG SystemReserved; 533 | ULONG AtlThunkSListPtr32; 534 | ULONG ApiSetMap; 535 | } PEB32, * PPEB32; 536 | 537 | typedef struct _WOW64_PROCESS 538 | { 539 | PPEB32 Wow64; 540 | } WOW64_PROCESS, * PWOW64_PROCESS; 541 | 542 | typedef union _WOW64_APC_CONTEXT 543 | { 544 | struct 545 | { 546 | ULONG Apc32BitContext; 547 | ULONG Apc32BitRoutine; 548 | }; 549 | 550 | PVOID Apc64BitContext; 551 | 552 | } WOW64_APC_CONTEXT, * PWOW64_APC_CONTEXT; 553 | 554 | typedef struct _NON_PAGED_DEBUG_INFO 555 | { 556 | USHORT Signature; 557 | USHORT Flags; 558 | ULONG Size; 559 | USHORT Machine; 560 | USHORT Characteristics; 561 | ULONG TimeDateStamp; 562 | ULONG CheckSum; 563 | ULONG SizeOfImage; 564 | ULONGLONG ImageBase; 565 | } NON_PAGED_DEBUG_INFO, * PNON_PAGED_DEBUG_INFO; 566 | 567 | typedef struct _KLDR_DATA_TABLE_ENTRY 568 | { 569 | LIST_ENTRY InLoadOrderLinks; 570 | PVOID ExceptionTable; 571 | ULONG ExceptionTableSize; 572 | // ULONG padding on IA64 573 | PVOID GpValue; 574 | PNON_PAGED_DEBUG_INFO NonPagedDebugInfo; 575 | PVOID DllBase; 576 | PVOID EntryPoint; 577 | ULONG SizeOfImage; 578 | UNICODE_STRING FullDllName; 579 | UNICODE_STRING BaseDllName; 580 | ULONG Flags; 581 | USHORT LoadCount; 582 | USHORT __Unused5; 583 | PVOID SectionPointer; 584 | ULONG CheckSum; 585 | // ULONG padding on IA64 586 | PVOID LoadedImports; 587 | PVOID PatchInformation; 588 | } KLDR_DATA_TABLE_ENTRY, * PKLDR_DATA_TABLE_ENTRY; 589 | 590 | 591 | // 592 | // This structure is used by the debugger for all targets 593 | // It is the same size as DBGKD_DATA_HEADER on all systems 594 | // 595 | typedef struct _DBGKD_DEBUG_DATA_HEADER64 { 596 | 597 | // 598 | // Link to other blocks 599 | // 600 | 601 | LIST_ENTRY64 List; 602 | 603 | // 604 | // This is a unique tag to identify the owner of the block. 605 | // If your component only uses one pool tag, use it for this, too. 606 | // 607 | 608 | ULONG OwnerTag; 609 | 610 | // 611 | // This must be initialized to the size of the data block, 612 | // including this structure. 613 | // 614 | 615 | ULONG Size; 616 | 617 | } DBGKD_DEBUG_DATA_HEADER64, * PDBGKD_DEBUG_DATA_HEADER64; 618 | 619 | 620 | // 621 | // This structure is the same size on all systems. The only field 622 | // which must be translated by the debugger is Header.List. 623 | // 624 | 625 | // 626 | // DO NOT ADD OR REMOVE FIELDS FROM THE MIDDLE OF THIS STRUCTURE!!! 627 | // 628 | // If you remove a field, replace it with an "unused" placeholder. 629 | // Do not reuse fields until there has been enough time for old debuggers 630 | // and extensions to age out. 631 | // 632 | typedef struct _KDDEBUGGER_DATA64 { 633 | 634 | DBGKD_DEBUG_DATA_HEADER64 Header; 635 | 636 | // 637 | // Base address of kernel image 638 | // 639 | 640 | ULONG64 KernBase; 641 | 642 | // 643 | // DbgBreakPointWithStatus is a function which takes an argument 644 | // and hits a breakpoint. This field contains the address of the 645 | // breakpoint instruction. When the debugger sees a breakpoint 646 | // at this address, it may retrieve the argument from the first 647 | // argument register, or on x86 the eax register. 648 | // 649 | 650 | ULONG64 BreakpointWithStatus; // address of breakpoint 651 | 652 | // 653 | // Address of the saved context record during a bugcheck 654 | // 655 | // N.B. This is an automatic in KeBugcheckEx's frame, and 656 | // is only valid after a bugcheck. 657 | // 658 | 659 | ULONG64 SavedContext; 660 | 661 | // 662 | // help for walking stacks with user callbacks: 663 | // 664 | 665 | // 666 | // The address of the thread structure is provided in the 667 | // WAIT_STATE_CHANGE packet. This is the offset from the base of 668 | // the thread structure to the pointer to the kernel stack frame 669 | // for the currently active usermode callback. 670 | // 671 | 672 | USHORT ThCallbackStack; // offset in thread data 673 | 674 | // 675 | // these values are offsets into that frame: 676 | // 677 | 678 | USHORT NextCallback; // saved pointer to next callback frame 679 | USHORT FramePointer; // saved frame pointer 680 | 681 | // 682 | // pad to a quad boundary 683 | // 684 | USHORT PaeEnabled; 685 | 686 | // 687 | // Address of the kernel callout routine. 688 | // 689 | 690 | ULONG64 KiCallUserMode; // kernel routine 691 | 692 | // 693 | // Address of the usermode entry point for callbacks. 694 | // 695 | 696 | ULONG64 KeUserCallbackDispatcher; // address in ntdll 697 | 698 | 699 | // 700 | // Addresses of various kernel data structures and lists 701 | // that are of interest to the kernel debugger. 702 | // 703 | 704 | ULONG64 PsLoadedModuleList; 705 | ULONG64 PsActiveProcessHead; 706 | ULONG64 PspCidTable; 707 | 708 | ULONG64 ExpSystemResourcesList; 709 | ULONG64 ExpPagedPoolDescriptor; 710 | ULONG64 ExpNumberOfPagedPools; 711 | 712 | ULONG64 KeTimeIncrement; 713 | ULONG64 KeBugCheckCallbackListHead; 714 | ULONG64 KiBugcheckData; 715 | 716 | ULONG64 IopErrorLogListHead; 717 | 718 | ULONG64 ObpRootDirectoryObject; 719 | ULONG64 ObpTypeObjectType; 720 | 721 | ULONG64 MmSystemCacheStart; 722 | ULONG64 MmSystemCacheEnd; 723 | ULONG64 MmSystemCacheWs; 724 | 725 | ULONG64 MmPfnDatabase; 726 | ULONG64 MmSystemPtesStart; 727 | ULONG64 MmSystemPtesEnd; 728 | ULONG64 MmSubsectionBase; 729 | ULONG64 MmNumberOfPagingFiles; 730 | 731 | ULONG64 MmLowestPhysicalPage; 732 | ULONG64 MmHighestPhysicalPage; 733 | ULONG64 MmNumberOfPhysicalPages; 734 | 735 | ULONG64 MmMaximumNonPagedPoolInBytes; 736 | ULONG64 MmNonPagedSystemStart; 737 | ULONG64 MmNonPagedPoolStart; 738 | ULONG64 MmNonPagedPoolEnd; 739 | 740 | ULONG64 MmPagedPoolStart; 741 | ULONG64 MmPagedPoolEnd; 742 | ULONG64 MmPagedPoolInformation; 743 | ULONG64 MmPageSize; 744 | 745 | ULONG64 MmSizeOfPagedPoolInBytes; 746 | 747 | ULONG64 MmTotalCommitLimit; 748 | ULONG64 MmTotalCommittedPages; 749 | ULONG64 MmSharedCommit; 750 | ULONG64 MmDriverCommit; 751 | ULONG64 MmProcessCommit; 752 | ULONG64 MmPagedPoolCommit; 753 | ULONG64 MmExtendedCommit; 754 | 755 | ULONG64 MmZeroedPageListHead; 756 | ULONG64 MmFreePageListHead; 757 | ULONG64 MmStandbyPageListHead; 758 | ULONG64 MmModifiedPageListHead; 759 | ULONG64 MmModifiedNoWritePageListHead; 760 | ULONG64 MmAvailablePages; 761 | ULONG64 MmResidentAvailablePages; 762 | 763 | ULONG64 PoolTrackTable; 764 | ULONG64 NonPagedPoolDescriptor; 765 | 766 | ULONG64 MmHighestUserAddress; 767 | ULONG64 MmSystemRangeStart; 768 | ULONG64 MmUserProbeAddress; 769 | 770 | ULONG64 KdPrintCircularBuffer; 771 | ULONG64 KdPrintCircularBufferEnd; 772 | ULONG64 KdPrintWritePointer; 773 | ULONG64 KdPrintRolloverCount; 774 | 775 | ULONG64 MmLoadedUserImageList; 776 | 777 | // NT 5.1 Addition 778 | 779 | ULONG64 NtBuildLab; 780 | ULONG64 KiNormalSystemCall; 781 | 782 | // NT 5.0 hotfix addition 783 | 784 | ULONG64 KiProcessorBlock; 785 | ULONG64 MmUnloadedDrivers; 786 | ULONG64 MmLastUnloadedDriver; 787 | ULONG64 MmTriageActionTaken; 788 | ULONG64 MmSpecialPoolTag; 789 | ULONG64 KernelVerifier; 790 | ULONG64 MmVerifierData; 791 | ULONG64 MmAllocatedNonPagedPool; 792 | ULONG64 MmPeakCommitment; 793 | ULONG64 MmTotalCommitLimitMaximum; 794 | ULONG64 CmNtCSDVersion; 795 | 796 | // NT 5.1 Addition 797 | 798 | ULONG64 MmPhysicalMemoryBlock; 799 | ULONG64 MmSessionBase; 800 | ULONG64 MmSessionSize; 801 | ULONG64 MmSystemParentTablePage; 802 | 803 | // Server 2003 addition 804 | 805 | ULONG64 MmVirtualTranslationBase; 806 | 807 | USHORT OffsetKThreadNextProcessor; 808 | USHORT OffsetKThreadTeb; 809 | USHORT OffsetKThreadKernelStack; 810 | USHORT OffsetKThreadInitialStack; 811 | 812 | USHORT OffsetKThreadApcProcess; 813 | USHORT OffsetKThreadState; 814 | USHORT OffsetKThreadBStore; 815 | USHORT OffsetKThreadBStoreLimit; 816 | 817 | USHORT SizeEProcess; 818 | USHORT OffsetEprocessPeb; 819 | USHORT OffsetEprocessParentCID; 820 | USHORT OffsetEprocessDirectoryTableBase; 821 | 822 | USHORT SizePrcb; 823 | USHORT OffsetPrcbDpcRoutine; 824 | USHORT OffsetPrcbCurrentThread; 825 | USHORT OffsetPrcbMhz; 826 | 827 | USHORT OffsetPrcbCpuType; 828 | USHORT OffsetPrcbVendorString; 829 | USHORT OffsetPrcbProcStateContext; 830 | USHORT OffsetPrcbNumber; 831 | 832 | USHORT SizeEThread; 833 | 834 | ULONG64 KdPrintCircularBufferPtr; 835 | ULONG64 KdPrintBufferSize; 836 | 837 | ULONG64 KeLoaderBlock; 838 | 839 | USHORT SizePcr; 840 | USHORT OffsetPcrSelfPcr; 841 | USHORT OffsetPcrCurrentPrcb; 842 | USHORT OffsetPcrContainedPrcb; 843 | 844 | USHORT OffsetPcrInitialBStore; 845 | USHORT OffsetPcrBStoreLimit; 846 | USHORT OffsetPcrInitialStack; 847 | USHORT OffsetPcrStackLimit; 848 | 849 | USHORT OffsetPrcbPcrPage; 850 | USHORT OffsetPrcbProcStateSpecialReg; 851 | USHORT GdtR0Code; 852 | USHORT GdtR0Data; 853 | 854 | USHORT GdtR0Pcr; 855 | USHORT GdtR3Code; 856 | USHORT GdtR3Data; 857 | USHORT GdtR3Teb; 858 | 859 | USHORT GdtLdt; 860 | USHORT GdtTss; 861 | USHORT Gdt64R3CmCode; 862 | USHORT Gdt64R3CmTeb; 863 | 864 | ULONG64 IopNumTriageDumpDataBlocks; 865 | ULONG64 IopTriageDumpDataBlocks; 866 | 867 | // Longhorn addition 868 | 869 | ULONG64 VfCrashDataBlock; 870 | ULONG64 MmBadPagesDetected; 871 | ULONG64 MmZeroedPageSingleBitErrorsDetected; 872 | 873 | // Windows 7 addition 874 | 875 | ULONG64 EtwpDebuggerData; 876 | USHORT OffsetPrcbContext; 877 | 878 | // Windows 8 addition 879 | 880 | USHORT OffsetPrcbMaxBreakpoints; 881 | USHORT OffsetPrcbMaxWatchpoints; 882 | 883 | ULONG OffsetKThreadStackLimit; 884 | ULONG OffsetKThreadStackBase; 885 | ULONG OffsetKThreadQueueListEntry; 886 | ULONG OffsetEThreadIrpList; 887 | 888 | USHORT OffsetPrcbIdleThread; 889 | USHORT OffsetPrcbNormalDpcState; 890 | USHORT OffsetPrcbDpcStack; 891 | USHORT OffsetPrcbIsrStack; 892 | 893 | USHORT SizeKDPC_STACK_FRAME; 894 | 895 | // Windows 8.1 Addition 896 | 897 | USHORT OffsetKPriQueueThreadListHead; 898 | USHORT OffsetKThreadWaitReason; 899 | 900 | // Windows 10 RS1 Addition 901 | 902 | USHORT Padding; 903 | ULONG64 PteBase; 904 | 905 | // Windows 10 RS5 Addition 906 | 907 | ULONG64 RetpolineStubFunctionTable; 908 | ULONG RetpolineStubFunctionTableSize; 909 | ULONG RetpolineStubOffset; 910 | ULONG RetpolineStubSize; 911 | 912 | } KDDEBUGGER_DATA64, * PKDDEBUGGER_DATA64; 913 | 914 | 915 | typedef struct _DUMP_HEADER 916 | { 917 | ULONG Signature; 918 | ULONG ValidDump; 919 | ULONG MajorVersion; 920 | ULONG MinorVersion; 921 | ULONG_PTR DirectoryTableBase; 922 | ULONG_PTR PfnDataBase; 923 | PLIST_ENTRY PsLoadedModuleList; 924 | PLIST_ENTRY PsActiveProcessHead; 925 | ULONG MachineImageType; 926 | ULONG NumberProcessors; 927 | ULONG BugCheckCode; 928 | ULONG_PTR BugCheckParameter1; 929 | ULONG_PTR BugCheckParameter2; 930 | ULONG_PTR BugCheckParameter3; 931 | ULONG_PTR BugCheckParameter4; 932 | CHAR VersionUser[32]; 933 | struct _KDDEBUGGER_DATA64* KdDebuggerDataBlock; 934 | } DUMP_HEADER, * PDUMP_HEADER; 935 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, Signature) == 0); 936 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, ValidDump) == 4); 937 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, MajorVersion) == 8); 938 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, MinorVersion) == 0xc); 939 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, DirectoryTableBase) == 0x10); 940 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, PfnDataBase) == 0x18); 941 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, PsLoadedModuleList) == 0x20); 942 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, PsActiveProcessHead) == 0x28); 943 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, MachineImageType) == 0x30); 944 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, NumberProcessors) == 0x34); 945 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, BugCheckCode) == 0x38); 946 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, BugCheckParameter1) == 0x40); 947 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, BugCheckParameter2) == 0x48); 948 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, BugCheckParameter3) == 0x50); 949 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, BugCheckParameter4) == 0x58); 950 | C_ASSERT(FIELD_OFFSET(DUMP_HEADER, KdDebuggerDataBlock) == 0x80); 951 | 952 | 953 | typedef struct _MODULEENTRY 954 | { 955 | ULONGLONG Address; 956 | ULONG Size; 957 | } MODULEENTRY, * PMODULEENTRY; -------------------------------------------------------------------------------- /Dumper/Dumper/Dumper.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | 16.0 15 | Win32Proj 16 | {4e175db2-cffd-48f9-888f-af140e44068d} 17 | Dumper 18 | 19 | 20 | 21 | Application 22 | true 23 | v142 24 | MultiByte 25 | 26 | 27 | false 28 | v142 29 | true 30 | MultiByte 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | true 46 | $(SolutionDir)include;$(IncludePath) 47 | $(SolutionDir)bin\$(Configuration)\ 48 | obj\$(Configuration)\ 49 | $(SolutionDir)libs;$(LibraryPath) 50 | 51 | 52 | false 53 | ..\include;$(SolutionDir)include;$(IncludePath) 54 | false 55 | $(SolutionDir)libs;$(LibraryPath) 56 | 57 | 58 | 59 | Level3 60 | false 61 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 62 | false 63 | stdcpplatest 64 | FastCall 65 | true 66 | Async 67 | 68 | 69 | Console 70 | true 71 | RequireAdministrator 72 | ntdll.lib;%(AdditionalDependencies) 73 | 74 | 75 | 76 | 77 | Level3 78 | true 79 | true 80 | false 81 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 82 | false 83 | stdcpplatest 84 | FastCall 85 | ProgramDatabase 86 | false 87 | Async 88 | AnySuitable 89 | true 90 | Default 91 | CompileAsCpp 92 | 93 | 94 | false 95 | true 96 | 97 | 98 | Console 99 | true 100 | true 101 | true 102 | ntdll.lib;%(AdditionalDependencies) 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /Dumper/Dumper/Dumper.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 6 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 7 | 8 | 9 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 10 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 11 | 12 | 13 | {7feed74c-41d0-4a17-93ca-9e368259955d} 14 | 15 | 16 | {fa04ece9-af5e-44b6-9f99-319055d65faa} 17 | 18 | 19 | {b0bb4cbc-e3e6-446a-a8ad-0998a0a3bf83} 20 | 21 | 22 | {7eababf1-cc2c-4c96-b184-25dec6f786eb} 23 | 24 | 25 | 26 | 27 | Sources 28 | 29 | 30 | Sources 31 | 32 | 33 | Sources 34 | 35 | 36 | Sources 37 | 38 | 39 | Sources\include\fmt 40 | 41 | 42 | Sources 43 | 44 | 45 | Sources 46 | 47 | 48 | Sources 49 | 50 | 51 | Sources\driver 52 | 53 | 54 | 55 | 56 | Headers 57 | 58 | 59 | Headers 60 | 61 | 62 | Headers 63 | 64 | 65 | Headers 66 | 67 | 68 | Headers 69 | 70 | 71 | Headers 72 | 73 | 74 | Headers 75 | 76 | 77 | Sources\driver 78 | 79 | 80 | Sources\stuffs 81 | 82 | 83 | Sources\stuffs 84 | 85 | 86 | -------------------------------------------------------------------------------- /Dumper/Dumper/Dumper.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | WindowsLocalDebugger 7 | 8 | 9 | 10 | 11 | WindowsLocalDebugger 12 | 13 | -------------------------------------------------------------------------------- /Dumper/Dumper/defs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #ifdef GetObject 5 | #undef GetObject 6 | #endif 7 | 8 | enum class STATUS { 9 | SUCCESS, 10 | FAILED, 11 | WINDOW_NOT_FOUND, 12 | PROCESS_NOT_FOUND, 13 | READER_ERROR, 14 | CANNOT_GET_PROCNAME, 15 | MODULE_NOT_FOUND, 16 | ENGINE_NOT_FOUND, 17 | ENGINE_FAILED, 18 | CANNOT_READ, 19 | INVALID_IMAGE, 20 | FILE_NOT_OPEN, 21 | ZERO_PACKAGES 22 | }; -------------------------------------------------------------------------------- /Dumper/Dumper/driver.cpp: -------------------------------------------------------------------------------- 1 | #include "driver.hpp" 2 | 3 | void driver::init() 4 | { 5 | this->DriverHandle = CreateFile("\\\\.\\\Xo1337GodPaster", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 6 | 7 | if (DriverHandle == INVALID_HANDLE_VALUE) 8 | this->DriverHandle = nullptr; 9 | } 10 | 11 | void driver::read_virtual_memory(PVOID Base, PVOID Buffer, DWORD Size) 12 | { 13 | _copy_memory req = { 0 }; 14 | 15 | req.address = (ULONGLONG)Base; 16 | req.buffer = (ULONGLONG)Buffer; 17 | req.size = Size; 18 | 19 | req.pid = ProcessId; 20 | req.write = FALSE; 21 | 22 | DeviceIoControl(DriverHandle, io_copy_memory, &req, sizeof(req), nullptr, 0, NULL, NULL); 23 | } 24 | 25 | void driver::write_virtual_memory(PVOID Base, PVOID Buffer, DWORD Size) 26 | { 27 | _copy_memory req = { 0 }; 28 | 29 | req.address = (ULONGLONG)Base; 30 | req.buffer = (ULONGLONG)Buffer; 31 | req.size = Size; 32 | 33 | req.pid = ProcessId; 34 | req.write = TRUE; 35 | 36 | DeviceIoControl(DriverHandle, io_copy_memory, &req, sizeof(req), nullptr, 0, NULL, NULL); 37 | } 38 | 39 | void driver::protect_virtual_memory(PVOID Base, DWORD Size, DWORD Protection) 40 | { 41 | _protect_memory req = { 0 }; 42 | 43 | req.address = (ULONGLONG)Base; 44 | req.size = Size; 45 | req.new_protect = Protection; 46 | 47 | req.pid = ProcessId; 48 | 49 | DeviceIoControl(DriverHandle, io_protect_memory, &req, sizeof(req), nullptr, 0, NULL, NULL); 50 | } 51 | 52 | PVOID driver::allocate_virtual_memory(DWORD Size, DWORD Protection) 53 | { 54 | _allocate_memory req = { 0 }; 55 | 56 | req.size = Size; 57 | req.protect = Protection; 58 | 59 | req.pid = ProcessId; 60 | 61 | DeviceIoControl(DriverHandle, io_allocate_memory, &req, sizeof(req), &req, sizeof(req), NULL, NULL); 62 | 63 | return (PVOID)req.address; 64 | } 65 | 66 | void driver::free_virtual_memory(PVOID Address) 67 | { 68 | _free_memory req = { 0 }; 69 | 70 | req.address = (ULONGLONG)Address; 71 | req.pid = ProcessId; 72 | 73 | DeviceIoControl(DriverHandle, io_free_memory, &req, sizeof(req), nullptr, 0, NULL, NULL); 74 | } 75 | 76 | PVOID driver::get_module_base_peb() 77 | { 78 | _get_module_base_peb req = { 0 }; 79 | 80 | req.pid = ProcessId; 81 | 82 | DeviceIoControl(DriverHandle, io_get_module_base_peb, &req, sizeof(req), &req, sizeof(req), NULL, NULL); 83 | 84 | return (PVOID)req.address; 85 | } 86 | 87 | DWORD driver::get_module_size() 88 | { 89 | ULONG Address; 90 | DWORD Bytes; 91 | 92 | DeviceIoControl(DriverHandle, io_get_module_size, &Address, sizeof(Address), &Address, sizeof(Address), &Bytes, NULL); 93 | return Address; 94 | } -------------------------------------------------------------------------------- /Dumper/Dumper/driver.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ioctl.hpp" 3 | 4 | class driver 5 | { 6 | HANDLE DriverHandle = { }; 7 | DWORD ProcessId = { }; 8 | public: 9 | driver(DWORD pid) : ProcessId(pid) { }; 10 | 11 | void init(); 12 | 13 | void read_virtual_memory(PVOID Base, PVOID Buffer, DWORD Size); 14 | void write_virtual_memory(PVOID Base, PVOID Buffer, DWORD Size); 15 | void protect_virtual_memory(PVOID Base, DWORD Size, DWORD Protection); 16 | 17 | PVOID allocate_virtual_memory(DWORD Size, DWORD Protection); 18 | 19 | void free_virtual_memory(PVOID Address); 20 | 21 | PVOID get_module_base_peb(); 22 | DWORD get_module_size(); 23 | }; -------------------------------------------------------------------------------- /Dumper/Dumper/dumper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "dumper.h" 4 | #include "engine.h" 5 | #include "memory.h" 6 | #include "utils.h" 7 | #include "wrappers.h" 8 | 9 | Dumper::~Dumper() { 10 | if (Image) VirtualFree(Image, 0, MEM_RELEASE); 11 | } 12 | 13 | STATUS Dumper::Init(int argc, char *argv[]) { 14 | for (auto i = 1; i < argc; i++) { 15 | auto arg = argv[i]; 16 | uint16 arg16 = *(uint16*)arg; 17 | if (arg16 == 'h-') { 18 | printf("'-p' - dump only names and objects\n'-w' - wait for input (it gives me time to inject mods)\n'-f packageNameHere' - specifies package where we should look for pointers in paddings (can take a lot of time)"); 19 | return STATUS::FAILED; 20 | } else if (arg16 == 'p-') { 21 | Full = false; 22 | } else if (arg16 == 'w-') { 23 | Wait = true; 24 | } else if ((arg16 == 'f-')) { 25 | i++; 26 | if (i < argc) { PackageName = argv[i]; } 27 | else { return STATUS::FAILED; } 28 | } 29 | else if (!strcmp(arg, "--spacing")) { 30 | Spacing = true; 31 | } 32 | } 33 | 34 | if (Wait) { 35 | system("pause"); 36 | } 37 | 38 | uint32_t pid = 0; 39 | 40 | { 41 | HWND hWnd = FindWindowA("UnrealWindow", nullptr); 42 | if (!hWnd) { 43 | return STATUS::WINDOW_NOT_FOUND; 44 | }; 45 | GetWindowThreadProcessId(hWnd, (DWORD*)(&pid)); 46 | if (!pid) { 47 | return STATUS::PROCESS_NOT_FOUND; 48 | }; 49 | 50 | mem = new driver(pid); 51 | mem->init(); 52 | } 53 | 54 | if (!ReaderInit(pid)) { 55 | return STATUS::READER_ERROR; 56 | }; 57 | 58 | fs::path processName; 59 | 60 | { 61 | wchar_t processPath[MAX_PATH]{}; 62 | if (!GetProccessPath(pid, processPath, MAX_PATH)) { return STATUS::CANNOT_GET_PROCNAME; }; 63 | processName = fs::path(processPath).filename(); 64 | printf("Found UE4 game: %ls\n", processName.c_str()); 65 | } 66 | 67 | { 68 | auto root = fs::path(argv[0]); 69 | root.remove_filename(); 70 | auto game = processName.stem(); 71 | Directory = root / "Games" / game; 72 | fs::create_directories(Directory); 73 | 74 | //auto [base, size] = GetModuleInfo(pid, processName); 75 | auto base = mem->get_module_base_peb(); 76 | auto size = mem->get_module_size(); 77 | if (!(base && size)) { return STATUS::MODULE_NOT_FOUND; } 78 | Base = (uint64)base; 79 | Image = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 80 | if (!Read(base, Image, size)) { 81 | return STATUS::CANNOT_READ; 82 | } 83 | return EngineInit(game.string(), Image); 84 | } 85 | } 86 | 87 | STATUS Dumper::Dump() { 88 | /* 89 | * Names dumping. 90 | * We go through each block, except last, that is not fully filled. 91 | * In each block we calculate next entry depending on previous entry size. 92 | */ 93 | { 94 | File file(Directory / "NamesDump.txt", "w"); 95 | if (!file) { return STATUS::FILE_NOT_OPEN; } 96 | size_t size = 0; 97 | NamePoolData.Dump([&file, &size](std::string_view name, uint32_t id) { 98 | fmt::print(file, "[{:0>6}] {}\n", id, name); 99 | size++; 100 | }); 101 | fmt::print("Names: {}\n", size); 102 | } 103 | { 104 | // Why we need to iterate all objects twice? We dumping objects and filling 105 | // packages simultaneously. 106 | std::unordered_map> packages; 107 | { 108 | File file(Directory / "ObjectsDump.txt", "w"); 109 | if (!file) { return STATUS::FILE_NOT_OPEN; } 110 | size_t size = 0; 111 | 112 | 113 | std::function callback; 114 | if (Full) { 115 | callback = [&file, &size, &packages](UE_UObject object) { 116 | fmt::print(file, "[{:0>6}] <{}> <{}> {}\n", object.GetIndex(), object.GetAddress(), Read(object.GetAddress()), object.GetFullName()); 117 | size++; 118 | if (object.IsA() || object.IsA()) { 119 | auto packageObj = object.GetPackageObject(); 120 | packages[packageObj].push_back(object); 121 | } 122 | }; 123 | } 124 | else { 125 | callback = [&file, &size](UE_UObject object){ 126 | fmt::print(file, "[{:0>6}] <{}> <{}> {}\n", object.GetIndex(), object.GetAddress(), Read(object.GetAddress()), object.GetFullName()); 127 | size++; 128 | }; 129 | } 130 | 131 | ObjObjects.Dump(callback); 132 | 133 | fmt::print("Objects: {}\n", size); 134 | } 135 | 136 | if (!Full) { 137 | return STATUS::SUCCESS; 138 | } 139 | 140 | //{ 141 | // // Clearing all packages with small amount of objects (comment this if 142 | // you need all packages to be dumped) size_t size = packages.size(); 143 | // size_t erased = std::erase_if(packages, [](std::pair>& package) { return package.second.size() < 2; 145 | // }); 146 | 147 | // fmt::print("Wiped {} out of {}\n", erased, size); 148 | //} 149 | 150 | // Checking if we have any package after clearing. 151 | if (!packages.size()) { 152 | return STATUS::ZERO_PACKAGES; 153 | } 154 | 155 | fmt::print("Packages: {}\n", packages.size()); 156 | 157 | { 158 | auto path = Directory / "DUMP"; 159 | fs::create_directories(path); 160 | 161 | int i = 1; 162 | int saved = 0; 163 | std::string unsaved{}; 164 | 165 | bool lock = true; 166 | if (PackageName) lock = false; 167 | 168 | for (UE_UPackage package : packages) { 169 | fmt::print("\rProcessing: {}/{}", i++, packages.size()); 170 | 171 | if (!lock && package.GetObject().GetName() == PackageName) { 172 | package.FindPointers = true; 173 | lock = true; 174 | } 175 | 176 | package.Process(); 177 | if (package.Save(path, Spacing)) { 178 | saved++; 179 | } else { 180 | unsaved += (package.GetObject().GetName() + ", "); 181 | }; 182 | } 183 | 184 | fmt::print("\nSaved packages: {}\n", saved); 185 | 186 | if (unsaved.size()) { 187 | unsaved.erase(unsaved.size() - 2); 188 | fmt::print("Unsaved empty packages: [ {} ]\n", unsaved); 189 | } 190 | } 191 | } 192 | return STATUS::SUCCESS; 193 | } 194 | -------------------------------------------------------------------------------- /Dumper/Dumper/dumper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "defs.h" 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | class Dumper { 8 | protected: 9 | bool Full = true; 10 | bool Wait = false; 11 | bool Spacing = false; 12 | fs::path Directory; 13 | const char* PackageName = nullptr; 14 | void* Image = nullptr; 15 | 16 | 17 | private: 18 | Dumper(){}; 19 | 20 | public: 21 | static Dumper* GetInstance() { 22 | static Dumper dumper; 23 | return &dumper; 24 | } 25 | ~Dumper(); 26 | STATUS Init(int argc, char *argv[]); 27 | STATUS Dump(); 28 | }; 29 | -------------------------------------------------------------------------------- /Dumper/Dumper/engine.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "engine.h" 3 | #include "generic.h" 4 | #include "memory.h" 5 | #include "utils.h" 6 | #include "wrappers.h" 7 | 8 | Offsets offsets; 9 | 10 | ansi_fn Decrypt_ANSI = nullptr; 11 | // wide_fn Decrypt_WIDE = nullptr; 12 | 13 | struct { 14 | uint16 Stride = 2; 15 | struct { 16 | uint16 Size = 24; 17 | } FUObjectItem; 18 | struct { 19 | uint16 Number = 4; 20 | } FName; 21 | struct { 22 | uint16 Info = 0; 23 | uint16 WideBit = 0; 24 | uint16 LenBit = 6; 25 | uint16 HeaderSize = 2; 26 | } FNameEntry; 27 | struct { 28 | uint16 Index = 0xC; 29 | uint16 Class = 0x10; 30 | uint16 Name = 0x18; 31 | uint16 Outer = 0x20; 32 | } UObject; 33 | struct { 34 | uint16 Next = 0x28; 35 | } UField; 36 | struct { 37 | uint16 SuperStruct = 0x40; 38 | uint16 Children = 0x48; 39 | uint16 ChildProperties = 0x50; 40 | uint16 PropertiesSize = 0x58; 41 | } UStruct; 42 | struct { 43 | uint16 Names = 0x40; 44 | } UEnum; 45 | struct { 46 | uint16 FunctionFlags = 0xB0; 47 | uint16 Func = 0xB0 + 0x28; 48 | } UFunction; 49 | struct { 50 | uint16 Class = 0x8; 51 | uint16 Next = 0x20; 52 | uint16 Name = 0x28; 53 | } FField; 54 | struct { 55 | uint16 ArrayDim = 0x38; 56 | uint16 ElementSize = 0x3C; 57 | uint16 PropertyFlags = 0x40; 58 | uint16 Offset = 0x4C; 59 | uint16 Size = 0x78; 60 | } FProperty; 61 | struct { 62 | uint16 ArrayDim = 0; 63 | uint16 ElementSize = 0; 64 | uint16 PropertyFlags = 0; 65 | uint16 Offset = 0; 66 | uint16 Size = 0; // sizeof(UProperty) 67 | } UProperty; 68 | } Default; 69 | static_assert(sizeof(Default) == sizeof(Offsets)); 70 | 71 | struct { 72 | uint16 Stride = 4; 73 | struct { 74 | uint16 Size = 24; 75 | } FUObjectItem; 76 | struct { 77 | uint16 Number = 8; 78 | } FName; 79 | struct { 80 | uint16 Info = 4; 81 | uint16 WideBit = 0; 82 | uint16 LenBit = 1; 83 | uint16 HeaderSize = 6; 84 | } FNameEntry; 85 | struct { 86 | uint16 Index = 0xC; 87 | uint16 Class = 0x10; 88 | uint16 Name = 0x18; 89 | uint16 Outer = 0x28; 90 | } UObject; 91 | struct { 92 | uint16 Next = 0x30; 93 | } UField; 94 | struct { 95 | uint16 SuperStruct = 0x48; 96 | uint16 Children = 0x50; 97 | uint16 ChildProperties = 0x58; 98 | uint16 PropertiesSize = 0x60; 99 | } UStruct; 100 | struct { 101 | uint16 Names = 0x48; 102 | } UEnum; 103 | struct { 104 | uint16 FunctionFlags = 0xB8; 105 | uint16 Func = 0xB8 + 0x28; // ue3-ue4, always +0x28 from flags location. 106 | } UFunction; 107 | struct { 108 | uint16 Class = 0x8; 109 | uint16 Next = 0x20; 110 | uint16 Name = 0x28; 111 | } FField; 112 | struct { 113 | uint16 ArrayDim = 0x38; 114 | uint16 ElementSize = 0x3C; 115 | uint16 PropertyFlags = 0x40; 116 | uint16 Offset = 0x4C; 117 | uint16 Size = 0x80; 118 | } FProperty; 119 | struct { 120 | uint16 ArrayDim = 0; 121 | uint16 ElementSize = 0; 122 | uint16 PropertyFlags = 0; 123 | uint16 Offset = 0; 124 | uint16 Size = 0; // sizeof(UProperty) 125 | } UProperty; 126 | } DeadByDaylight; 127 | static_assert(sizeof(DeadByDaylight) == sizeof(Offsets)); 128 | 129 | struct { 130 | uint16 Stride = 2; 131 | struct { 132 | uint16 Size = 24; 133 | } FUObjectItem; 134 | struct { 135 | uint16 Number = 4; 136 | } FName; 137 | struct { 138 | uint16 Info = 0; 139 | uint16 WideBit = 0; 140 | uint16 LenBit = 6; 141 | uint16 HeaderSize = 2; 142 | } FNameEntry; 143 | struct { 144 | uint16 Index = 0xC; 145 | uint16 Class = 0x10; 146 | uint16 Name = 0x18; 147 | uint16 Outer = 0x20; 148 | } UObject; 149 | struct { 150 | uint16 Next = 0x28; 151 | } UField; 152 | struct { 153 | uint16 SuperStruct = 0x40; 154 | uint16 Children = 0x48; 155 | uint16 ChildProperties = 0x50; 156 | uint16 PropertiesSize = 0x58; 157 | } UStruct; 158 | struct { 159 | uint16 Names = 0x40; 160 | } UEnum; 161 | struct { 162 | uint16 FunctionFlags = 0xB0; 163 | uint16 Func = 0xB0 + 0x30; 164 | } UFunction; 165 | struct { 166 | uint16 Class = 0x8; 167 | uint16 Next = 0x20; 168 | uint16 Name = 0x28; 169 | } FField; 170 | struct { 171 | uint16 ArrayDim = 0x38; 172 | uint16 ElementSize = 0x3C; 173 | uint16 PropertyFlags = 0x40; 174 | uint16 Offset = 0x4C; 175 | uint16 Size = 0x78; 176 | } FProperty; 177 | struct { 178 | uint16 ArrayDim = 0; 179 | uint16 ElementSize = 0; 180 | uint16 PropertyFlags = 0; 181 | uint16 Offset = 0; 182 | uint16 Size = 0; // sizeof(UProperty) 183 | } UProperty; 184 | } Scavengers; 185 | static_assert(sizeof(Scavengers) == sizeof(Offsets)); 186 | 187 | struct { 188 | uint16 Stride = 2; 189 | struct { 190 | uint16 Size = 32; 191 | } FUObjectItem; 192 | struct { 193 | uint16 Number = 4; 194 | } FName; 195 | struct { 196 | uint16 Info = 0; 197 | uint16 WideBit = 0; 198 | uint16 LenBit = 6; 199 | uint16 HeaderSize = 2; 200 | } FNameEntry; 201 | struct { 202 | uint16 Index = 0xC; 203 | uint16 Class = 0x10; 204 | uint16 Name = 0x18; 205 | uint16 Outer = 0x20; 206 | } UObject; 207 | struct { 208 | uint16 Next = 0x28; 209 | } UField; 210 | struct { 211 | uint16 SuperStruct = 0x40; 212 | uint16 Children = 0x48; 213 | uint16 ChildProperties = 0x50; 214 | uint16 PropertiesSize = 0x58; 215 | } UStruct; 216 | struct { 217 | uint16 Names = 0x40; 218 | } UEnum; 219 | struct { 220 | uint16 FunctionFlags = 0xB0; 221 | uint16 Func = 0xB0 + 0x28; 222 | } UFunction; 223 | struct { 224 | uint16 Class = 0x8; 225 | uint16 Next = 0x20; 226 | uint16 Name = 0x28; 227 | } FField; 228 | struct { 229 | uint16 ArrayDim = 0x38; 230 | uint16 ElementSize = 0x3C; 231 | uint16 PropertyFlags = 0x40; 232 | uint16 Offset = 0x4C; 233 | uint16 Size = 0x78; 234 | } FProperty; 235 | struct { 236 | uint16 ArrayDim = 0; 237 | uint16 ElementSize = 0; 238 | uint16 PropertyFlags = 0; 239 | uint16 Offset = 0; 240 | uint16 Size = 0; // sizeof(UProperty) 241 | } UProperty; 242 | } Brickadia; 243 | static_assert(sizeof(Brickadia) == sizeof(Offsets)); 244 | 245 | struct { 246 | void* offsets; // address to filled offsets structure 247 | std::pair names; // NamePoolData signature 248 | std::pair objects; // ObjObjects signature 249 | std::function*)> callback; 250 | } engines[] = { 251 | { // RogueCompany | PropWitchHuntModule-Win64-Shipping | Scum 252 | &Default, 253 | {"\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xC6\x05\x00\x00\x00\x00\x01\x0F\x10\x03\x4C\x8D\x44\x24\x20\x48\x8B\xC8", 30}, 254 | {"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x04\xD1\xEB", 16}, 255 | nullptr 256 | }, 257 | { // Scavenger-Win64-Shipping 258 | &Scavengers, 259 | {"\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xC6\x05\x00\x00\x00\x00\x01\x0F\x10\x03\x4C\x8D\x44\x24\x20\x48\x8B\xC8", 30}, 260 | {"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x04\xD1\xEB", 16}, 261 | nullptr 262 | }, 263 | { // DeadByDaylight-Win64-Shipping 264 | &DeadByDaylight, 265 | {"\x48\x8D\x35\x00\x00\x00\x00\xEB\x16", 9}, 266 | {"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x04\xD1\xEB", 16}, 267 | nullptr 268 | }, 269 | { // Brickadia-Win64-Shipping 270 | &Brickadia, 271 | {"\x48\x8D\x0D\x00\x00\x00\x00\xE9\x73\xAB\xFF\xFF", 12}, 272 | {"\x48\x8B\x05\x00\x00\x00\x00\x48\x63\x8C\x24\xE0", 12}, 273 | nullptr 274 | }, 275 | { // POLYGON-Win64-Shipping 276 | &Default, 277 | {"\x48\x8D\x35\x00\x00\x00\x00\xEB\x16", 9}, 278 | {"\x48\x8d\x1d\x00\x00\x00\x00\x39\x44\x24\x68", 11}, 279 | nullptr 280 | }, 281 | { // FortniteClient-Win64-Shipping 282 | &Default, 283 | {"\x4C\x8D\x35\x00\x00\x00\x00\x0F\x10\x07\x83\xFB\x01", 13}, 284 | {"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x04\xD1\xEB", 16}, 285 | [](std::pair* s) { 286 | if (!Decrypt_ANSI) { 287 | auto decryptAnsi = FindPointer(s->first, s->second, "\xE8\x00\x00\x00\x00\x0F\xB7\x1B\xC1\xEB\x06\x4C\x89\x36\x4C\x89\x76\x08\x85\xDB\x74\x48", 22); 288 | if (decryptAnsi) { 289 | /* 290 | mov [rsp +8], rbx 291 | push rdi 292 | sub rsp, 0x20 293 | mov edi, edx 294 | mov rbx, rcx 295 | mov rax, 0xDEADBEEFDEADBEEF 296 | jmp rax 297 | */ 298 | uint8 trampoline[] = { 0x48, 0x89, 0x5C, 0x24, 0x08, 0x57, 0x48, 0x83, 0xEC, 0x20, 0x89, 0xD7, 0x48, 0x89, 0xCB, 0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xFF, 0xE0 }; 299 | *(uint64*)(trampoline + 17) = (uint64)((uint8*)decryptAnsi + 0x4A); // https://i.imgur.com/zWtMDar.png 300 | Decrypt_ANSI = (ansi_fn)VirtualAlloc(0, sizeof(trampoline), MEM_COMMIT, PAGE_EXECUTE_READWRITE); 301 | if (Decrypt_ANSI) { 302 | memcpy(Decrypt_ANSI, trampoline, sizeof(trampoline)); 303 | return true; 304 | } 305 | } 306 | } 307 | return false; 308 | } 309 | }, 310 | { // TheIsleClient-Win64-Shipping 311 | &Default, 312 | {"\x48\x8D\x05\x00\x00\x00\x00\xEB\x13\x48\x8D\x0D", 12}, 313 | {"\x48\x8b\x05\x00\x00\x00\x00\x48\x8b\x0c\xc8\x48\x8d\x04\xd1\xeb\x00\x49\x8b\xc6\x8b\x40\x00\xc1\xe8\x00\xa8\x00\x0f\x85\x00\x00\x00\x00\xf7\x86", 36}, 314 | nullptr 315 | }, 316 | { // PortalWars-Win64-Shipping 317 | &Default, 318 | {"\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xC6\x05\x00\x00\x00\x00\x01\x0F\x10\x03\x4C\x8D\x44\x24\x20\x48\x8B\xC8", 30}, 319 | {"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x1C\xD1\xEB\x03\x49\x8B\xDD", 20}, 320 | nullptr 321 | }, 322 | { // Tiger-Win64-Shipping.exe 323 | &Default, 324 | {"\x48\x8D\x35\x00\x00\x00\x00\xEB\x16", 9}, 325 | {"\x48\x8d\x1d\x00\x00\x00\x00\x39\x44\x24\x68", 11}, 326 | nullptr 327 | }, 328 | }; 329 | 330 | std::unordered_map games = { 331 | {"RogueCompany", &engines[0]}, 332 | {"SCUM", &engines[0]}, 333 | {"PropWitchHuntModule-Win64-Shipping", &engines[0]}, 334 | {"HLL-Win64-Shipping", &engines[0]}, 335 | {"Scavenger-Win64-Shipping", &engines[1]}, 336 | {"DeadByDaylight-Win64-Shipping", &engines[2]}, 337 | {"Brickadia-Win64-Shipping", &engines[3]}, 338 | {"POLYGON-Win64-Shipping", &engines[4]}, 339 | {"FortniteClient-Win64-Shipping", &engines[5]}, 340 | {"TheIsleClient-Win64-Shipping", &engines[6]}, 341 | {"PortalWars-Win64-Shipping", &engines[7]}, 342 | {"Tiger-Win64-Shipping", &engines[0]} 343 | }; 344 | 345 | STATUS EngineInit(std::string game, void* image) { 346 | auto sections = GetExSections(image); 347 | auto it = games.find(game); 348 | if (it == games.end()) { return STATUS::ENGINE_NOT_FOUND; } 349 | 350 | auto engine = it->second; 351 | offsets = *(Offsets*)(engine->offsets); 352 | 353 | void* names = nullptr; 354 | void* objects = nullptr; 355 | bool callback = false; 356 | 357 | uint8 found = 0; 358 | if (!engine->callback) { 359 | callback = true; 360 | found |= 4; 361 | } 362 | 363 | for (auto i = 0; i < sections.size(); i++) { 364 | auto &s = sections.at(i); 365 | if (!names) if (names = FindPointer(s.first, s.second, engine->names.first, engine->names.second)) found |= 1; 366 | if (!objects) if (objects = FindPointer(s.first, s.second, engine->objects.first, engine->objects.second)) found |= 2; 367 | if (!callback) if (callback = engine->callback(&s)) found |= 4; 368 | if (found == 7) break; 369 | } 370 | 371 | if (found != 7) return STATUS::ENGINE_FAILED; 372 | 373 | NamePoolData = *(decltype(NamePoolData)*)names; 374 | ObjObjects = *(decltype(ObjObjects)*)objects; 375 | 376 | auto entry = UE_FNameEntry(NamePoolData.GetEntry(0)); 377 | 378 | // exception handler exclusively for Decrypt_ANSI 379 | try { 380 | if (*(uint32*)entry.String().data() != 'enoN') return STATUS::ENGINE_FAILED; 381 | } 382 | catch (...) { 383 | return STATUS::ENGINE_FAILED; 384 | } 385 | 386 | return STATUS::SUCCESS; 387 | } 388 | -------------------------------------------------------------------------------- /Dumper/Dumper/engine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "defs.h" 3 | #include 4 | #include 5 | 6 | struct Offsets { 7 | uint16 Stride = 0; // alignof(FNameEntry) 8 | struct { 9 | uint16 Size = 0; 10 | } FUObjectItem; 11 | struct { 12 | uint16 Number = 0; 13 | } FName; 14 | struct { 15 | uint16 Info = 16 | 0; // Offset to Memory filled with info about type and size of string 17 | uint16 WideBit = 18 | 0; // Offset to bit which shows if string uses wide characters 19 | uint16 LenBit = 0; // Offset to bit which has lenght of string 20 | uint16 HeaderSize = 21 | 0; // Size of FNameEntry header (offset where a string begins) 22 | } FNameEntry; 23 | struct { 24 | uint16 Index = 0; // Offset to index of this object in all objects array 25 | uint16 Class = 0; // Offset to UClass pointer (UClass* ClassPrivate) 26 | uint16 Name = 0; // Offset to FName structure 27 | uint16 Outer = 0; // (UObject* OuterPrivate) 28 | } UObject; 29 | struct { 30 | uint16 Next = 0; 31 | } UField; 32 | struct { 33 | uint16 SuperStruct = 0; 34 | uint16 Children = 0; 35 | uint16 ChildProperties = 0; 36 | uint16 PropertiesSize = 0; 37 | } UStruct; 38 | struct { 39 | uint16 Names = 0; 40 | } UEnum; 41 | struct { 42 | uint16 FunctionFlags = 0; 43 | uint16 Func = 0; // ue3-ue4, always +0x28 from flags location. 44 | } UFunction; 45 | struct { 46 | uint16 Class = 0; 47 | uint16 Next = 0; 48 | uint16 Name = 0; 49 | } FField; 50 | struct { 51 | uint16 ArrayDim = 0; 52 | uint16 ElementSize = 0; 53 | uint16 PropertyFlags = 0; 54 | uint16 Offset = 0; 55 | uint16 Size = 0; // sizeof(FProperty) 56 | } FProperty; 57 | struct { 58 | uint16 ArrayDim = 0; 59 | uint16 ElementSize = 0; 60 | uint16 PropertyFlags = 0; 61 | uint16 Offset = 0; 62 | uint16 Size = 0; // sizeof(UProperty) 63 | } UProperty; 64 | }; 65 | 66 | extern Offsets offsets; 67 | 68 | typedef int64(_fastcall* ansi_fn)(char* a1, int a2); // buf, len 69 | // typedef int64(_fastcall*wide_fn)(wchar_t* a1, int a2); 70 | 71 | extern ansi_fn Decrypt_ANSI; 72 | // extern wide_fn Decrypt_WIDE; 73 | 74 | STATUS EngineInit(std::string game, void* image); 75 | -------------------------------------------------------------------------------- /Dumper/Dumper/generic.cpp: -------------------------------------------------------------------------------- 1 | #include "engine.h" 2 | #include "memory.h" 3 | #include "wrappers.h" 4 | 5 | uint8* FNamePool::GetEntry(FNameEntryHandle handle) const { 6 | if (handle.Block >= 8192) return nullptr; 7 | return (uint8*)(Blocks[handle.Block] + offsets.Stride * (uint64)(handle.Offset)); 8 | } 9 | 10 | void FNamePool::DumpBlock(uint32 blockId, uint32 blockSize, std::function callback) const { 11 | uint8* it = Blocks[blockId]; 12 | uint8* end = it + blockSize - offsets.FNameEntry.HeaderSize; 13 | FNameEntryHandle entryHandle = {blockId, 0}; 14 | while (it < end) { 15 | auto entry = UE_FNameEntry(it); 16 | auto [wide, len] = entry.Info(); 17 | if (len) { 18 | char buf[1024]{}; 19 | entry.String(buf, wide, len); 20 | callback(std::string_view(buf, len), entryHandle); 21 | uint16 size = UE_FNameEntry::Size(wide, len); 22 | entryHandle.Offset += size / offsets.Stride; 23 | it += size; 24 | } else { 25 | break; 26 | }; 27 | } 28 | } 29 | 30 | void FNamePool::Dump(std::function callback) const { 31 | for (uint32 i = 0; i < CurrentBlock; i++) { 32 | DumpBlock(i, offsets.Stride * 65536, callback); 33 | } 34 | DumpBlock(CurrentBlock, CurrentByteCursor, callback); 35 | } 36 | 37 | uint8* TUObjectArray::GetObjectPtr(uint32 id) const { 38 | if (id >= NumElements) return nullptr; 39 | uint64 chunkIndex = id / 65536; 40 | if (chunkIndex >= NumChunks) return nullptr; 41 | uint8 *chunk = Read(Objects + chunkIndex); 42 | if (!chunk) return nullptr; 43 | uint32 withinChunkIndex = id % 65536 * offsets.FUObjectItem.Size; 44 | auto item = Read(chunk + withinChunkIndex); 45 | return item; 46 | } 47 | 48 | void TUObjectArray::Dump(std::function callback) const { 49 | for (uint32 i = 0; i < NumElements; i++) { 50 | uint8* object = GetObjectPtr(i); 51 | if (!object) continue; 52 | callback(object); 53 | } 54 | } 55 | 56 | UE_UObject TUObjectArray::FindObject(const std::string &name) const { 57 | for (uint32 i = 0; i < NumElements; i++) { 58 | UE_UObject object = GetObjectPtr(i); 59 | if (object && object.GetFullName() == name) { 60 | return object; 61 | } 62 | } 63 | return nullptr; 64 | } 65 | 66 | void TUObjectArray::ForEachObjectOfClass(const UE_UClass cmp, std::function callback) const { 67 | for (uint32 i = 0; i < NumElements; i++) { 68 | UE_UObject object = GetObjectPtr(i); 69 | if (object && object.IsA(cmp) && object.GetName().find("_Default") == std::string::npos) { 70 | if (callback(object)) return; 71 | } 72 | } 73 | } 74 | 75 | bool TUObjectArray::IsObject(UE_UObject address) const { 76 | for (uint32 i = 0; i < NumElements; i++) { 77 | UE_UObject object = GetObjectPtr(i); 78 | if (address == object) { 79 | return true; 80 | } 81 | } 82 | return false; 83 | } 84 | 85 | TUObjectArray ObjObjects; 86 | FNamePool NamePoolData; 87 | -------------------------------------------------------------------------------- /Dumper/Dumper/generic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "defs.h" 3 | #include 4 | 5 | struct TArray { 6 | uint8* Data; 7 | uint32 Count; 8 | uint32 Max; 9 | }; 10 | 11 | struct FNameEntryHandle { 12 | uint32 Block = 0; 13 | uint32 Offset = 0; 14 | FNameEntryHandle(uint32 block, uint32 offset) : Block(block), Offset(offset){}; 15 | FNameEntryHandle(uint32 id) : Block(id >> 16), Offset(id & 65535){}; 16 | operator uint32() const { return (Block << 16 | Offset); } 17 | }; 18 | 19 | struct FNamePool { 20 | uint8 Lock[8]; 21 | uint32 CurrentBlock; 22 | uint32 CurrentByteCursor; 23 | uint8* Blocks[8192]; 24 | uint8* GetEntry(FNameEntryHandle handle) const; 25 | void DumpBlock(uint32 blockId, uint32 blockSize, std::function callback) const; 26 | void Dump(std::function callback) const; 27 | }; 28 | 29 | struct TUObjectArray { 30 | uint8** Objects; 31 | uint8* PreAllocatedObjects; 32 | uint32 MaxElements; 33 | uint32 NumElements; 34 | uint32 MaxChunks; 35 | uint32 NumChunks; 36 | 37 | uint8* GetObjectPtr(uint32 id) const; 38 | void Dump(std::function callback) const; 39 | class UE_UObject FindObject(const std::string &name) const; 40 | void ForEachObjectOfClass(const class UE_UClass cmp, std::function callback) const; 41 | bool IsObject(UE_UObject address) const; 42 | }; 43 | 44 | extern TUObjectArray ObjObjects; 45 | extern FNamePool NamePoolData; 46 | -------------------------------------------------------------------------------- /Dumper/Dumper/includes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include -------------------------------------------------------------------------------- /Dumper/Dumper/ioctl.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "includes.hpp" 3 | 4 | #include 5 | 6 | #define io_copy_memory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 7 | #define io_protect_memory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 8 | #define io_allocate_memory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x3, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 9 | #define io_free_memory CTL_CODE(FILE_DEVICE_UNKNOWN, 0x4, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 10 | #define io_get_module_base_peb CTL_CODE(FILE_DEVICE_UNKNOWN, 0x5, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 11 | #define io_get_module_size CTL_CODE(FILE_DEVICE_UNKNOWN, 0x6, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) 12 | 13 | typedef struct _MODULEENTRY 14 | { 15 | ULONGLONG Address; 16 | ULONG Size; 17 | } MODULEENTRY, * PMODULEENTRY; 18 | 19 | typedef struct _copy_memory 20 | { 21 | INT32 pid; 22 | ULONGLONG address; 23 | ULONGLONG buffer; 24 | ULONGLONG size; 25 | BOOLEAN write; 26 | } copy_memory, * pcopy_memory; 27 | 28 | typedef struct _protect_memory 29 | { 30 | INT32 pid; 31 | ULONGLONG address; 32 | ULONGLONG size; 33 | DWORD32 new_protect; 34 | } protect_memory, * pprotect_memory; 35 | 36 | typedef struct _allocate_memory 37 | { 38 | INT32 pid; 39 | ULONGLONG address; 40 | ULONGLONG size; 41 | DWORD32 protect; 42 | } allocate_memory, * pallocate_memory; 43 | 44 | typedef struct _free_memory 45 | { 46 | INT32 pid; 47 | ULONGLONG address; 48 | } free_memory, * pfree_memory; 49 | 50 | typedef struct _module_memory 51 | { 52 | INT32 pid; 53 | ULONGLONG address; 54 | } module_memory, * pmodule_memory; 55 | 56 | typedef struct _get_module_base_peb 57 | { 58 | INT32 pid; 59 | ULONGLONG address; 60 | ULONG size; 61 | } get_module_base_peb, * pget_module_base_peb; -------------------------------------------------------------------------------- /Dumper/Dumper/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dumper.h" 3 | #include "utils.h" 4 | 5 | int main(int argc, char* argv[]) 6 | { 7 | uint64 start; 8 | uint64 end; 9 | uint64 time; 10 | 11 | auto dumper = Dumper::GetInstance(); 12 | 13 | start = GetTime(); 14 | switch (dumper->Init(argc, argv)) 15 | { 16 | case STATUS::WINDOW_NOT_FOUND: { puts("Can't find UE4 window"); return 1; } 17 | case STATUS::PROCESS_NOT_FOUND: { puts("Can't find process"); return 1; } 18 | case STATUS::READER_ERROR: { puts("Can't init reader"); return 1; } 19 | case STATUS::CANNOT_GET_PROCNAME: { puts("Can't get process name"); return 1; } 20 | case STATUS::ENGINE_NOT_FOUND: { puts("Can't find offsets for this game"); return 1; } 21 | case STATUS::ENGINE_FAILED: { puts("Can't init engine for this game"); return 1; } 22 | case STATUS::MODULE_NOT_FOUND: { puts("Can't enumerate modules (protected process?)"); return 1; } 23 | case STATUS::CANNOT_READ: { puts("Can't read process memory"); return 1; } 24 | case STATUS::INVALID_IMAGE: { puts("Can't get executable sections"); return 1; } 25 | case STATUS::SUCCESS: { break; }; 26 | default: { return 1; } 27 | } 28 | end = GetTime(); 29 | time = (end - start) / 10000; 30 | fmt::print("Init time: {} ms\n", time); 31 | 32 | start = GetTime(); 33 | switch (dumper->Dump()) 34 | { 35 | case STATUS::FILE_NOT_OPEN: { puts("Can't open file"); return 1; } 36 | case STATUS::ZERO_PACKAGES: { puts("Size of packages is zero"); return 1; } 37 | case STATUS::SUCCESS: { break; } 38 | default: { return 1; } 39 | } 40 | end = GetTime(); 41 | time = (end - start) / 10000; 42 | fmt::print("Dump time: {} ms\n", time); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /Dumper/Dumper/memory.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "memory.h" 3 | 4 | HANDLE hProcess; 5 | uint64 Base; 6 | 7 | bool Read(void *address, void *buffer, uint64 size) { 8 | mem->read_virtual_memory((void*)address, (void*)buffer, (uint64)size); 9 | return true; 10 | } 11 | 12 | bool ReaderInit(uint32 pid) { 13 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 14 | return hProcess != nullptr; 15 | } 16 | -------------------------------------------------------------------------------- /Dumper/Dumper/memory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "defs.h" 3 | #include "utils.h" 4 | 5 | extern uint64 Base; 6 | 7 | bool Read(void* address, void* buffer, uint64 size); 8 | template T Read(void *address) { 9 | T buffer{}; 10 | Read(address, &buffer, sizeof(T)); 11 | return buffer; 12 | } 13 | 14 | bool ReaderInit(uint32 pid); 15 | -------------------------------------------------------------------------------- /Dumper/Dumper/utils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "utils.h" 5 | 6 | uint32 GetProcessId(std::wstring name) { 7 | uint32 pid = 0; 8 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 9 | if (snapshot != INVALID_HANDLE_VALUE) { 10 | PROCESSENTRY32W entry = {sizeof(entry)}; 11 | while (Process32NextW(snapshot, &entry)) { 12 | if (name == entry.szExeFile) { 13 | pid = entry.th32ProcessID; 14 | break; 15 | } 16 | } 17 | CloseHandle(snapshot); 18 | } 19 | return pid; 20 | } 21 | 22 | /*std::pair GetModuleInfo(uint32 pid, std::wstring name) { // gonna plan this to be full kernel 23 | 24 | std::pair info; 25 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); 26 | if (snapshot != INVALID_HANDLE_VALUE) { 27 | MODULEENTRY32W modEntry = { sizeof(modEntry) }; 28 | while (Module32NextW(snapshot, &modEntry)) { 29 | if (name == modEntry.szModule) { 30 | info = { modEntry.modBaseAddr, modEntry.modBaseSize }; 31 | break; 32 | } 33 | } 34 | } 35 | 36 | return { (uint8*)mem->module_memory(pid), info.second }; 37 | }*/ 38 | 39 | bool Compare(uint8* data, uint8 *sig, uint32 size) { 40 | for (uint32 i = 0; i < size; i++) { 41 | if (data[i] != sig[i] && sig[i] != 0x00) { 42 | return false; 43 | } 44 | } 45 | return true; 46 | } 47 | 48 | uint8* FindSignature(uint8* start, uint8* end, const char* sig, uint32 size) { 49 | for (uint8* it = start; it < end - size; it++) { 50 | if (Compare(it, (uint8*)sig, size)) { 51 | return it; 52 | }; 53 | } 54 | return nullptr; 55 | } 56 | 57 | void* FindPointer(uint8* start, uint8* end, const char* sig, uint32 size, int32 addition) { 58 | uint8* address = FindSignature(start, end, sig, size); 59 | if (!address) return nullptr; 60 | int32 k = 0; 61 | for (; sig[k]; k++); 62 | int32 offset = *(int32*)(address + k); 63 | return address + k + 4 + offset + addition; 64 | } 65 | 66 | std::vector> GetExSections(void* data) { 67 | std::vector> sections; 68 | auto dos = (PIMAGE_DOS_HEADER)data; 69 | auto nt = (PIMAGE_NT_HEADERS)((uint8*)data + dos->e_lfanew); 70 | auto s = IMAGE_FIRST_SECTION(nt); 71 | for (auto i = 0; i < nt->FileHeader.NumberOfSections; i++, s++) { 72 | if (s->Characteristics & IMAGE_SCN_CNT_CODE) { 73 | auto start = (uint8*)data + s->PointerToRawData; 74 | auto end = start + s->SizeOfRawData; 75 | sections.push_back({start, end}); 76 | } 77 | } 78 | return sections; 79 | } 80 | 81 | uint32 GetProccessPath(uint32 pid, wchar_t* processName, uint32 size) { 82 | HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid); 83 | if (!QueryFullProcessImageNameW(hProcess, 0, processName, (DWORD*)(&size))) { 84 | size = 0; 85 | }; 86 | CloseHandle(hProcess); 87 | return size; 88 | } 89 | 90 | extern "C" NTSTATUS NtQuerySystemTime(uint64* SystemTime); 91 | 92 | uint64 GetTime() { 93 | uint64 ret; 94 | NtQuerySystemTime(&ret); 95 | return ret; 96 | } 97 | -------------------------------------------------------------------------------- /Dumper/Dumper/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "defs.h" 3 | #include "driver.hpp" 4 | #include 5 | #include 6 | 7 | uint32 GetProcessId(std::wstring name); 8 | //std::pair GetModuleInfo(uint32 pid, std::wstring name); 9 | bool Compare(uint8* data, uint8* sig, uint32 size); 10 | uint8* FindSignature(uint8* start, uint8* end, const char* sig, uint32 size); 11 | void* FindPointer(uint8* start, uint8* end, const char* sig, uint32 size, int32 addition = 0); 12 | std::vector> GetExSections(void *data); 13 | uint32 GetProccessPath(uint32 pid, wchar_t* processName, uint32 size); 14 | uint64 GetTime(); 15 | 16 | inline driver* mem; -------------------------------------------------------------------------------- /Dumper/Dumper/wrappers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "engine.h" 6 | #include "memory.h" 7 | #include "wrappers.h" 8 | 9 | std::pair UE_FNameEntry::Info() const { 10 | auto info = Read(object + offsets.FNameEntry.Info); 11 | auto len = info >> offsets.FNameEntry.LenBit; 12 | bool wide = (info >> offsets.FNameEntry.WideBit) & 1; 13 | return {wide, len}; 14 | } 15 | 16 | std::string UE_FNameEntry::String(bool wide, uint16 len) const { 17 | std::string name("\x0", len); 18 | String(name.data(), wide, len); 19 | return name; 20 | } 21 | 22 | void UE_FNameEntry::String(char *buf, bool wide, uint16 len) const { 23 | if (wide) { 24 | wchar_t wbuf[1024]{}; 25 | Read(object + offsets.FNameEntry.HeaderSize, wbuf, len * 2ull); 26 | /*if (Decrypt_WIDE) { Decrypt_WIDE(wbuf, len); }*/ 27 | auto copied = WideCharToMultiByte(CP_UTF8, 0, wbuf, len, buf, len, 0, 0); 28 | if (copied == 0) { 29 | buf[0] = '\x0'; 30 | } 31 | } else { 32 | Read(object + offsets.FNameEntry.HeaderSize, buf, len); 33 | if (Decrypt_ANSI) { 34 | Decrypt_ANSI(buf, len); 35 | } 36 | } 37 | } 38 | 39 | std::string UE_FNameEntry::String() const { 40 | auto [wide, len] = this->Info(); 41 | return this->String(wide, len); 42 | } 43 | 44 | uint16 UE_FNameEntry::Size(bool wide, uint16 len) { 45 | uint16 bytes = offsets.FNameEntry.HeaderSize + len * (wide ? 2 : 1); 46 | return (bytes + offsets.Stride - 1u) & ~(offsets.Stride - 1u); 47 | } 48 | 49 | std::string UE_FName::GetName() const { 50 | uint32 index = Read(object); 51 | auto entry = UE_FNameEntry(NamePoolData.GetEntry(index)); 52 | if (!entry) return std::string(); 53 | auto [wide, len] = entry.Info(); 54 | auto name = entry.String(wide, len); 55 | uint32 number = Read(object + offsets.FName.Number); 56 | if (number > 0) { 57 | name += '_' + std::to_string(number); 58 | } 59 | auto pos = name.rfind('/'); 60 | if (pos != std::string::npos) { 61 | name = name.substr(pos + 1); 62 | } 63 | return name; 64 | } 65 | 66 | uint32 UE_UObject::GetIndex() const { 67 | return Read(object + offsets.UObject.Index); 68 | }; 69 | 70 | UE_UClass UE_UObject::GetClass() const { 71 | return Read(object + offsets.UObject.Class); 72 | } 73 | 74 | UE_UObject UE_UObject::GetOuter() const { 75 | return Read(object + offsets.UObject.Outer); 76 | } 77 | 78 | UE_UObject UE_UObject::GetPackageObject() const { 79 | UE_UObject package(nullptr); 80 | for (auto outer = GetOuter(); outer; outer = outer.GetOuter()) { 81 | package = outer; 82 | } 83 | return package; 84 | } 85 | 86 | std::string UE_UObject::GetName() const { 87 | auto fname = UE_FName(object + offsets.UObject.Name); 88 | return fname.GetName(); 89 | } 90 | 91 | std::string UE_UObject::GetFullName() const { 92 | std::string temp; 93 | for (auto outer = GetOuter(); outer; outer = outer.GetOuter()) { 94 | temp = outer.GetName() + "." + temp; 95 | } 96 | UE_UClass objectClass = GetClass(); 97 | std::string name = objectClass.GetName() + " " + temp + GetName(); 98 | return name; 99 | } 100 | 101 | std::string UE_UObject::GetCppName() const { 102 | std::string name; 103 | if (IsA()) { 104 | for (auto c = Cast(); c; c = c.GetSuper()) { 105 | if (c == UE_AActor::StaticClass()) { 106 | name = "A"; 107 | break; 108 | } else if (c == UE_UObject::StaticClass()) { 109 | name = "U"; 110 | break; 111 | } 112 | } 113 | } else { 114 | name = "F"; 115 | } 116 | 117 | name += GetName(); 118 | return name; 119 | } 120 | 121 | bool UE_UObject::IsA(UE_UClass cmp) const { 122 | for (auto super = GetClass(); super; super = super.GetSuper().Cast()) { 123 | if (super == cmp) { 124 | return true; 125 | } 126 | } 127 | 128 | return false; 129 | } 130 | 131 | UE_UClass UE_UObject::StaticClass() { 132 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.Object")); 133 | return obj; 134 | }; 135 | 136 | UE_UClass UE_AActor::StaticClass() { 137 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class Engine.Actor")); 138 | return obj; 139 | } 140 | 141 | UE_UField UE_UField::GetNext() const { 142 | return Read(object + offsets.UField.Next); 143 | } 144 | 145 | UE_UClass UE_UField::StaticClass() { 146 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.Field")); 147 | return obj; 148 | }; 149 | 150 | std::string IUProperty::GetName() const { 151 | return ((UE_UProperty*)(this->prop))->GetName(); 152 | } 153 | 154 | int32 IUProperty::GetArrayDim() const { 155 | return ((UE_UProperty*)(this->prop))->GetArrayDim(); 156 | } 157 | 158 | int32 IUProperty::GetSize() const { 159 | return ((UE_UProperty*)(this->prop))->GetSize(); 160 | } 161 | 162 | int32 IUProperty::GetOffset() const { 163 | return ((UE_UProperty*)(this->prop))->GetOffset(); 164 | } 165 | 166 | uint64 IUProperty::GetPropertyFlags() const { 167 | return ((UE_UProperty*)(this->prop))->GetPropertyFlags(); 168 | } 169 | 170 | std::pair IUProperty::GetType() const { 171 | return ((UE_UProperty*)(this->prop))->GetType(); 172 | } 173 | 174 | uint8 IUProperty::GetFieldMask() const { 175 | return ((UE_UBoolProperty *)(this->prop))->GetFieldMask(); 176 | } 177 | 178 | int32 UE_UProperty::GetArrayDim() const { 179 | return Read(object + offsets.UProperty.ArrayDim); 180 | } 181 | 182 | int32 UE_UProperty::GetSize() const { 183 | return Read(object + offsets.UProperty.ElementSize); 184 | } 185 | 186 | int32 UE_UProperty::GetOffset() const { 187 | return Read(object + offsets.UProperty.Offset); 188 | } 189 | 190 | uint64 UE_UProperty::GetPropertyFlags() const { 191 | return Read(object + offsets.UProperty.PropertyFlags); 192 | } 193 | 194 | std::pair UE_UProperty::GetType() const { 195 | if (IsA()) { return {PropertyType::DoubleProperty,Cast().GetTypeStr()}; }; 196 | if (IsA()) { return {PropertyType::FloatProperty, Cast().GetTypeStr()}; }; 197 | if (IsA()) { return {PropertyType::IntProperty, Cast().GetTypeStr()}; }; 198 | if (IsA()) { return {PropertyType::Int16Property,Cast().GetTypeStr()}; }; 199 | if (IsA()) { return {PropertyType::Int64Property, Cast().GetTypeStr()}; }; 200 | if (IsA()) { return {PropertyType::Int8Property, Cast().GetTypeStr()}; }; 201 | if (IsA()) { return {PropertyType::UInt16Property, Cast().GetTypeStr()}; }; 202 | if (IsA()) { return {PropertyType::UInt32Property, Cast().GetTypeStr()}; } 203 | if (IsA()) { return {PropertyType::UInt64Property, Cast().GetTypeStr()}; }; 204 | if (IsA()) { return {PropertyType::TextProperty, Cast().GetTypeStr()}; } 205 | if (IsA()) { return {PropertyType::TextProperty, Cast().GetTypeStr()}; }; 206 | if (IsA()) { return {PropertyType::ClassProperty, Cast().GetTypeStr()}; }; 207 | if (IsA()) { return {PropertyType::StructProperty, Cast().GetTypeStr()}; }; 208 | if (IsA()) { return {PropertyType::NameProperty, Cast().GetTypeStr()}; }; 209 | if (IsA()) { return {PropertyType::BoolProperty, Cast().GetTypeStr()}; } 210 | if (IsA()) { return {PropertyType::ByteProperty, Cast().GetTypeStr()}; }; 211 | if (IsA()) { return {PropertyType::ArrayProperty, Cast().GetTypeStr()}; }; 212 | if (IsA()) { return {PropertyType::EnumProperty, Cast().GetTypeStr()}; }; 213 | if (IsA()) { return {PropertyType::SetProperty, Cast().GetTypeStr()}; }; 214 | if (IsA()) { return {PropertyType::MapProperty, Cast().GetTypeStr()}; }; 215 | if (IsA()) { return {PropertyType::InterfaceProperty, Cast().GetTypeStr()}; }; 216 | if (IsA()) { return {PropertyType::MulticastDelegateProperty, Cast().GetTypeStr()}; }; 217 | if (IsA()) { return { PropertyType::WeakObjectProperty, Cast().GetTypeStr() }; }; 218 | if (IsA()) { return {PropertyType::ObjectProperty, Cast().GetTypeStr()}; }; 219 | return {PropertyType::Unknown, GetClass().GetName()}; 220 | } 221 | 222 | IUProperty UE_UProperty::GetInterface() const { return IUProperty(this); } 223 | 224 | UE_UClass UE_UProperty::StaticClass() { 225 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.Property")); 226 | return obj; 227 | } 228 | 229 | UE_UStruct UE_UStruct::GetSuper() const { 230 | return Read(object + offsets.UStruct.SuperStruct); 231 | } 232 | 233 | UE_FField UE_UStruct::GetChildProperties() const { 234 | if (offsets.UStruct.ChildProperties) return Read(object + offsets.UStruct.ChildProperties); 235 | else return nullptr; 236 | } 237 | 238 | UE_UField UE_UStruct::GetChildren() const { 239 | return Read(object + offsets.UStruct.Children); 240 | } 241 | 242 | int32 UE_UStruct::GetSize() const { 243 | return Read(object + offsets.UStruct.PropertiesSize); 244 | }; 245 | 246 | UE_UClass UE_UStruct::StaticClass() { 247 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.Struct")); 248 | return obj; 249 | }; 250 | 251 | uint64 UE_UFunction::GetFunc() const { 252 | return Read(object + offsets.UFunction.Func); 253 | } 254 | 255 | std::string UE_UFunction::GetFunctionFlags() const { 256 | auto flags = Read(object + offsets.UFunction.FunctionFlags); 257 | std::string result; 258 | if (flags == FUNC_None) { 259 | result = "None"; 260 | } else { 261 | if (flags & FUNC_Final) { 262 | result += "Final|"; 263 | } 264 | if (flags & FUNC_RequiredAPI) { 265 | result += "RequiredAPI|"; 266 | } 267 | if (flags & FUNC_BlueprintAuthorityOnly) { 268 | result += "BlueprintAuthorityOnly|"; 269 | } 270 | if (flags & FUNC_BlueprintCosmetic) { 271 | result += "BlueprintCosmetic|"; 272 | } 273 | if (flags & FUNC_Net) { 274 | result += "Net|"; 275 | } 276 | if (flags & FUNC_NetReliable) { 277 | result += "NetReliable"; 278 | } 279 | if (flags & FUNC_NetRequest) { 280 | result += "NetRequest|"; 281 | } 282 | if (flags & FUNC_Exec) { 283 | result += "Exec|"; 284 | } 285 | if (flags & FUNC_Native) { 286 | result += "Native|"; 287 | } 288 | if (flags & FUNC_Event) { 289 | result += "Event|"; 290 | } 291 | if (flags & FUNC_NetResponse) { 292 | result += "NetResponse|"; 293 | } 294 | if (flags & FUNC_Static) { 295 | result += "Static|"; 296 | } 297 | if (flags & FUNC_NetMulticast) { 298 | result += "NetMulticast|"; 299 | } 300 | if (flags & FUNC_UbergraphFunction) { 301 | result += "UbergraphFunction|"; 302 | } 303 | if (flags & FUNC_MulticastDelegate) { 304 | result += "MulticastDelegate|"; 305 | } 306 | if (flags & FUNC_Public) { 307 | result += "Public|"; 308 | } 309 | if (flags & FUNC_Private) { 310 | result += "Private|"; 311 | } 312 | if (flags & FUNC_Protected) { 313 | result += "Protected|"; 314 | } 315 | if (flags & FUNC_Delegate) { 316 | result += "Delegate|"; 317 | } 318 | if (flags & FUNC_NetServer) { 319 | result += "NetServer|"; 320 | } 321 | if (flags & FUNC_HasOutParms) { 322 | result += "HasOutParms|"; 323 | } 324 | if (flags & FUNC_HasDefaults) { 325 | result += "HasDefaults|"; 326 | } 327 | if (flags & FUNC_NetClient) { 328 | result += "NetClient|"; 329 | } 330 | if (flags & FUNC_DLLImport) { 331 | result += "DLLImport|"; 332 | } 333 | if (flags & FUNC_BlueprintCallable) { 334 | result += "BlueprintCallable|"; 335 | } 336 | if (flags & FUNC_BlueprintEvent) { 337 | result += "BlueprintEvent|"; 338 | } 339 | if (flags & FUNC_BlueprintPure) { 340 | result += "BlueprintPure|"; 341 | } 342 | if (flags & FUNC_EditorOnly) { 343 | result += "EditorOnly|"; 344 | } 345 | if (flags & FUNC_Const) { 346 | result += "Const|"; 347 | } 348 | if (flags & FUNC_NetValidate) { 349 | result += "NetValidate|"; 350 | } 351 | if (result.size()) { 352 | result.erase(result.size() - 1); 353 | } 354 | } 355 | return result; 356 | } 357 | 358 | UE_UClass UE_UFunction::StaticClass() { 359 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.Function")); 360 | return obj; 361 | } 362 | 363 | UE_UClass UE_UScriptStruct::StaticClass() { 364 | static UE_UClass obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.ScriptStruct")); 365 | return obj; 366 | }; 367 | 368 | UE_UClass UE_UClass::StaticClass() { 369 | static UE_UClass obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.Class")); 370 | return obj; 371 | }; 372 | 373 | TArray UE_UEnum::GetNames() const { 374 | return Read(object + offsets.UEnum.Names); 375 | } 376 | 377 | UE_UClass UE_UEnum::StaticClass() { 378 | static UE_UClass obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.Enum")); 379 | return obj; 380 | } 381 | 382 | std::string UE_UDoubleProperty::GetTypeStr() const { return "double"; } 383 | 384 | UE_UClass UE_UDoubleProperty::StaticClass() { 385 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.DoubleProperty")); 386 | return obj; 387 | } 388 | 389 | UE_UStruct UE_UStructProperty::GetStruct() const { 390 | return Read(object + offsets.UProperty.Size); 391 | } 392 | 393 | std::string UE_UStructProperty::GetTypeStr() const { 394 | return "struct " + GetStruct().GetCppName(); 395 | } 396 | 397 | UE_UClass UE_UStructProperty::StaticClass() { 398 | static auto obj = (UE_UClass)( ObjObjects.FindObject("Class CoreUObject.StructProperty")); 399 | return obj; 400 | } 401 | 402 | std::string UE_UNameProperty::GetTypeStr() const { return "struct FName"; } 403 | 404 | UE_UClass UE_UNameProperty::StaticClass() { 405 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.NameProperty")); 406 | return obj; 407 | } 408 | 409 | UE_UClass UE_UObjectPropertyBase::GetPropertyClass() const { 410 | return Read(object + offsets.UProperty.Size); 411 | } 412 | 413 | std::string UE_UObjectPropertyBase::GetTypeStr() const { 414 | return "struct " + GetPropertyClass().GetCppName() + "*"; 415 | } 416 | 417 | UE_UClass UE_UObjectPropertyBase::StaticClass() { 418 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.ObjectPropertyBase")); 419 | return obj; 420 | } 421 | 422 | UE_UProperty UE_UArrayProperty::GetInner() const { 423 | return Read(object + offsets.UProperty.Size); 424 | } 425 | 426 | std::string UE_UArrayProperty::GetTypeStr() const { 427 | return "struct TArray<" + GetInner().GetType().second + ">"; 428 | } 429 | 430 | UE_UClass UE_UArrayProperty::StaticClass() { 431 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.ArrayProperty")); 432 | return obj; 433 | } 434 | 435 | UE_UEnum UE_UByteProperty::GetEnum() const { 436 | return Read(object + offsets.UProperty.Size); 437 | } 438 | 439 | std::string UE_UByteProperty::GetTypeStr() const { 440 | auto e = GetEnum(); 441 | if (e) return "enum class " + e.GetName(); 442 | return "char"; 443 | } 444 | 445 | UE_UClass UE_UByteProperty::StaticClass() { 446 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.ByteProperty")); 447 | return obj; 448 | } 449 | 450 | uint8 UE_UBoolProperty::GetFieldMask() const { 451 | return Read(object + offsets.UProperty.Size + 3); 452 | } 453 | 454 | std::string UE_UBoolProperty::GetTypeStr() const { 455 | if (GetFieldMask() == 0xFF) { 456 | return "bool"; 457 | }; 458 | return "char"; 459 | } 460 | 461 | UE_UClass UE_UBoolProperty::StaticClass() { 462 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.BoolProperty")); 463 | return obj; 464 | } 465 | 466 | std::string UE_UFloatProperty::GetTypeStr() const { return "float"; } 467 | 468 | UE_UClass UE_UFloatProperty::StaticClass() { 469 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.FloatProperty")); 470 | return obj; 471 | } 472 | 473 | std::string UE_UIntProperty::GetTypeStr() const { return "int"; } 474 | 475 | UE_UClass UE_UIntProperty::StaticClass() { 476 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.IntProperty")); 477 | return obj; 478 | } 479 | 480 | std::string UE_UInt16Property::GetTypeStr() const { return "int16"; } 481 | 482 | UE_UClass UE_UInt16Property::StaticClass() { 483 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.Int16Property")); 484 | return obj; 485 | } 486 | 487 | std::string UE_UInt64Property::GetTypeStr() const { return "int64"; } 488 | 489 | UE_UClass UE_UInt64Property::StaticClass() { 490 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.Int64Property")); 491 | return obj; 492 | } 493 | 494 | std::string UE_UInt8Property::GetTypeStr() const { return "uint8"; } 495 | 496 | UE_UClass UE_UInt8Property::StaticClass() { 497 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.Int8Property")); 498 | return obj; 499 | } 500 | 501 | std::string UE_UUInt16Property::GetTypeStr() const { return "uint16"; } 502 | 503 | UE_UClass UE_UUInt16Property::StaticClass() { 504 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.UInt16Property")); 505 | return obj; 506 | } 507 | 508 | std::string UE_UUInt32Property::GetTypeStr() const { return "uint32"; } 509 | 510 | UE_UClass UE_UUInt32Property::StaticClass() { 511 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.UInt32Property")); 512 | return obj; 513 | } 514 | 515 | std::string UE_UUInt64Property::GetTypeStr() const { return "uint64"; } 516 | 517 | UE_UClass UE_UUInt64Property::StaticClass() { 518 | static auto obj = (UE_UClass)( ObjObjects.FindObject("Class CoreUObject.UInt64Property")); 519 | return obj; 520 | } 521 | 522 | std::string UE_UTextProperty::GetTypeStr() const { return "struct FText"; } 523 | 524 | UE_UClass UE_UTextProperty::StaticClass() { 525 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.TextProperty")); 526 | return obj; 527 | } 528 | 529 | std::string UE_UStrProperty::GetTypeStr() const { return "struct FString"; } 530 | 531 | UE_UClass UE_UStrProperty::StaticClass() { 532 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.StrProperty")); 533 | return obj; 534 | } 535 | 536 | UE_UClass UE_UEnumProperty::GetEnum() const { 537 | return Read(object + offsets.UProperty.Size + 8); 538 | } 539 | 540 | std::string UE_UEnumProperty::GetTypeStr() const { 541 | return "enum class " + GetEnum().GetName(); 542 | } 543 | 544 | UE_UClass UE_UEnumProperty::StaticClass() { 545 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.EnumProperty")); 546 | return obj; 547 | } 548 | 549 | UE_UClass UE_UClassProperty::GetMetaClass() const { 550 | return Read(object + offsets.UProperty.Size + 8); 551 | } 552 | 553 | std::string UE_UClassProperty::GetTypeStr() const { 554 | return "struct " + GetMetaClass().GetCppName() + "*"; 555 | } 556 | 557 | UE_UClass UE_UClassProperty::StaticClass() { 558 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.ClassProperty")); 559 | return obj; 560 | } 561 | 562 | UE_UProperty UE_USetProperty::GetElementProp() const { 563 | return Read(object + offsets.UProperty.Size); 564 | } 565 | 566 | std::string UE_USetProperty::GetTypeStr() const { 567 | return "struct TSet<" + GetElementProp().GetType().second + ">"; 568 | } 569 | 570 | UE_UClass UE_USetProperty::StaticClass() { 571 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.SetProperty")); 572 | return obj; 573 | } 574 | 575 | UE_UProperty UE_UMapProperty::GetKeyProp() const { 576 | return Read(object + offsets.UProperty.Size); 577 | } 578 | 579 | UE_UProperty UE_UMapProperty::GetValueProp() const { 580 | return Read(object + offsets.UProperty.Size + 8); 581 | } 582 | 583 | std::string UE_UMapProperty::GetTypeStr() const { 584 | return fmt::format("struct TMap<{}, {}>", GetKeyProp().GetType().second, GetValueProp().GetType().second); 585 | } 586 | 587 | UE_UClass UE_UMapProperty::StaticClass() { 588 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.MapProperty")); 589 | return obj; 590 | } 591 | 592 | UE_UProperty UE_UInterfaceProperty::GetInterfaceClass() const { 593 | return Read(object + offsets.UProperty.Size); 594 | } 595 | 596 | std::string UE_UInterfaceProperty::GetTypeStr() const { 597 | return "struct TScriptInterface<" + GetInterfaceClass().GetType().second + ">"; 598 | } 599 | 600 | UE_UClass UE_UInterfaceProperty::StaticClass() { 601 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.InterfaceProperty")); 602 | return obj; 603 | } 604 | 605 | std::string UE_UMulticastDelegateProperty::GetTypeStr() const { 606 | return "struct FScriptMulticastDelegate"; 607 | } 608 | 609 | UE_UClass UE_UMulticastDelegateProperty::StaticClass() { 610 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.MulticastDelegateProperty")); 611 | return obj; 612 | } 613 | 614 | std::string UE_UWeakObjectProperty::GetTypeStr() const { 615 | return "struct TWeakObjectPtr<" + this->Cast().GetTypeStr() + ">"; 616 | } 617 | 618 | UE_UClass UE_UWeakObjectProperty::StaticClass() { 619 | static auto obj = (UE_UClass)(ObjObjects.FindObject("Class CoreUObject.WeakObjectProperty")); 620 | return obj; 621 | } 622 | 623 | std::string UE_FFieldClass::GetName() const { 624 | auto name = UE_FName(object); 625 | return name.GetName(); 626 | } 627 | 628 | UE_FField UE_FField::GetNext() const { 629 | return Read(object + offsets.FField.Next); 630 | }; 631 | 632 | std::string UE_FField::GetName() const { 633 | auto name = UE_FName(object + offsets.FField.Name); 634 | return name.GetName(); 635 | } 636 | 637 | std::string IFProperty::GetName() const { 638 | return ((UE_FProperty *)prop)->GetName(); 639 | } 640 | 641 | int32 IFProperty::GetArrayDim() const { 642 | return ((UE_FProperty*)prop)->GetArrayDim(); 643 | } 644 | 645 | int32 IFProperty::GetSize() const { return ((UE_FProperty *)prop)->GetSize(); } 646 | 647 | int32 IFProperty::GetOffset() const { 648 | return ((UE_FProperty*)prop)->GetOffset(); 649 | } 650 | 651 | uint64 IFProperty::GetPropertyFlags() const { 652 | return ((UE_FProperty*)prop)->GetPropertyFlags(); 653 | } 654 | 655 | std::pair IFProperty::GetType() const { 656 | return ((UE_FProperty*)prop)->GetType(); 657 | } 658 | 659 | uint8 IFProperty::GetFieldMask() const { 660 | return ((UE_FBoolProperty *)prop)->GetFieldMask(); 661 | } 662 | 663 | int32 UE_FProperty::GetArrayDim() const { 664 | return Read(object + offsets.FProperty.ArrayDim); 665 | } 666 | 667 | int32 UE_FProperty::GetSize() const { 668 | return Read(object + offsets.FProperty.ElementSize); 669 | } 670 | 671 | int32 UE_FProperty::GetOffset() const { 672 | return Read(object + offsets.FProperty.Offset); 673 | } 674 | 675 | uint64 UE_FProperty::GetPropertyFlags() const { 676 | return Read(object + offsets.FProperty.PropertyFlags); 677 | } 678 | 679 | type UE_FProperty::GetType() const { 680 | auto objectClass = Read(object + offsets.FField.Class); 681 | type type = {PropertyType::Unknown, objectClass.GetName()}; 682 | 683 | auto& str = type.second; 684 | auto hash = Hash(str.c_str(), str.size()); 685 | switch (hash) { 686 | case HASH("StructProperty"): { 687 | auto obj = this->Cast(); 688 | type = { PropertyType::StructProperty, obj.GetTypeStr() }; 689 | break; 690 | } 691 | case HASH("ObjectProperty"): { 692 | auto obj = this->Cast(); 693 | type = { PropertyType::ObjectProperty, obj.GetTypeStr() }; 694 | break; 695 | } 696 | case HASH("SoftObjectProperty"): { 697 | auto obj = this->Cast(); 698 | type = { PropertyType::SoftObjectProperty, "struct TSoftObjectPtr<" + obj.GetPropertyClass().GetCppName() + ">" }; 699 | break; 700 | } 701 | case HASH("FloatProperty"): { 702 | type = { PropertyType::FloatProperty, "float" }; 703 | break; 704 | } 705 | case HASH("ByteProperty"): { 706 | auto obj = this->Cast(); 707 | type = { PropertyType::ByteProperty, obj.GetTypeStr() }; 708 | break; 709 | } 710 | case HASH("BoolProperty"): { 711 | auto obj = this->Cast(); 712 | type = { PropertyType::BoolProperty, obj.GetTypeStr() }; 713 | break; 714 | } 715 | case HASH("IntProperty"): { 716 | type = { PropertyType::IntProperty, "int32_t" }; 717 | break; 718 | } 719 | case HASH("Int8Property"): { 720 | type = { PropertyType::Int8Property, "int8_t" }; 721 | break; 722 | } 723 | case HASH("Int16Property"): { 724 | type = { PropertyType::Int16Property, "int16_t" }; 725 | break; 726 | } 727 | case HASH("Int64Property"): { 728 | type = { PropertyType::Int64Property, "int64_t" }; 729 | break; 730 | } 731 | case HASH("UInt16Property"): { 732 | type = { PropertyType::UInt16Property, "uint16_t" }; 733 | break; 734 | } 735 | case HASH("UInt32Property"): { 736 | type = { PropertyType::UInt32Property, "uint32_t" }; 737 | break; 738 | } 739 | case HASH("UInt64Property"): { 740 | type = { PropertyType::UInt64Property, "uint64_t" }; 741 | break; 742 | } 743 | case HASH("NameProperty"): { 744 | type = { PropertyType::NameProperty, "struct FName" }; 745 | break; 746 | } 747 | case HASH("DelegateProperty"): { 748 | type = { PropertyType::DelegateProperty, "struct FDelegate" }; 749 | break; 750 | } 751 | case HASH("SetProperty"): { 752 | auto obj = this->Cast(); 753 | type = { PropertyType::SetProperty, obj.GetTypeStr() }; 754 | break; 755 | } 756 | case HASH("ArrayProperty"): { 757 | auto obj = this->Cast(); 758 | type = { PropertyType::ArrayProperty, obj.GetTypeStr() }; 759 | break; 760 | } 761 | case HASH("WeakObjectProperty"): { 762 | auto obj = this->Cast(); 763 | type = { PropertyType::WeakObjectProperty, "struct TWeakObjectPtr<" + obj.GetTypeStr() + ">" }; 764 | 765 | break; 766 | } 767 | case HASH("StrProperty"): { 768 | type = { PropertyType::StrProperty, "struct FString" }; 769 | break; 770 | } 771 | case HASH("TextProperty"): { 772 | type = { PropertyType::TextProperty, "struct FText" }; 773 | break; 774 | } 775 | case HASH("MulticastSparseDelegateProperty"): { 776 | type = { PropertyType::MulticastSparseDelegateProperty, "struct FMulticastSparseDelegate" }; 777 | break; 778 | } 779 | case HASH("EnumProperty"): { 780 | auto obj = this->Cast(); 781 | type = { PropertyType::EnumProperty, obj.GetTypeStr() }; 782 | break; 783 | } 784 | case HASH("DoubleProperty"): { 785 | type = { PropertyType::DoubleProperty, "double" }; 786 | break; 787 | } 788 | case HASH("MulticastDelegateProperty"): { 789 | type = { PropertyType::MulticastDelegateProperty, "FMulticastDelegate" }; 790 | break; 791 | } 792 | case HASH("ClassProperty"): { 793 | auto obj = this->Cast(); 794 | type = { PropertyType::ClassProperty, obj.GetTypeStr() }; 795 | break; 796 | } 797 | case HASH("MulticastInlineDelegateProperty"): { 798 | type = { PropertyType::MulticastDelegateProperty, "struct FMulticastInlineDelegate" }; 799 | break; 800 | } 801 | case HASH("MapProperty"): { 802 | auto obj = this->Cast(); 803 | type = { PropertyType::MapProperty, obj.GetTypeStr() }; 804 | break; 805 | } 806 | case HASH("InterfaceProperty"): { 807 | auto obj = this->Cast(); 808 | type = { PropertyType::InterfaceProperty, obj.GetTypeStr() }; 809 | break; 810 | } 811 | case HASH("FieldPathProperty"): { 812 | auto obj = this->Cast(); 813 | type = { PropertyType::FieldPathProperty, obj.GetTypeStr() }; 814 | break; 815 | } 816 | case HASH("SoftClassProperty"): { 817 | type = { PropertyType::SoftClassProperty, "struct TSoftClassPtr" }; 818 | break; 819 | } 820 | } 821 | 822 | return type; 823 | } 824 | 825 | IFProperty UE_FProperty::GetInterface() const { return IFProperty(this); } 826 | 827 | UE_UStruct UE_FStructProperty::GetStruct() const { 828 | return Read(object + offsets.FProperty.Size); 829 | } 830 | 831 | std::string UE_FStructProperty::GetTypeStr() const { 832 | return "struct " + GetStruct().GetCppName(); 833 | } 834 | 835 | UE_UClass UE_FObjectPropertyBase::GetPropertyClass() const { 836 | return Read(object + offsets.FProperty.Size); 837 | } 838 | 839 | std::string UE_FObjectPropertyBase::GetTypeStr() const { 840 | return "struct " + GetPropertyClass().GetCppName() + "*"; 841 | } 842 | 843 | UE_FProperty UE_FArrayProperty::GetInner() const { 844 | return Read(object + offsets.FProperty.Size); 845 | } 846 | 847 | std::string UE_FArrayProperty::GetTypeStr() const { 848 | return "struct TArray<" + GetInner().GetType().second + ">"; 849 | } 850 | 851 | UE_UEnum UE_FByteProperty::GetEnum() const { 852 | return Read(object + offsets.FProperty.Size); 853 | } 854 | 855 | std::string UE_FByteProperty::GetTypeStr() const { 856 | auto e = GetEnum(); 857 | if (e) return "enum class " + e.GetName(); 858 | return "char"; 859 | } 860 | 861 | uint8 UE_FBoolProperty::GetFieldMask() const { 862 | return Read(object + offsets.FProperty.Size + 3); 863 | } 864 | 865 | std::string UE_FBoolProperty::GetTypeStr() const { 866 | if (GetFieldMask() == 0xFF) { 867 | return "bool"; 868 | }; 869 | return "char"; 870 | } 871 | 872 | UE_UClass UE_FEnumProperty::GetEnum() const { 873 | return Read(object + offsets.FProperty.Size + 8); 874 | } 875 | 876 | std::string UE_FEnumProperty::GetTypeStr() const { 877 | return "enum class " + GetEnum().GetName(); 878 | } 879 | 880 | UE_UClass UE_FClassProperty::GetMetaClass() const { 881 | return Read(object + offsets.FProperty.Size + 8); 882 | } 883 | 884 | std::string UE_FClassProperty::GetTypeStr() const { 885 | return "struct " + GetMetaClass().GetCppName() + "*"; 886 | } 887 | 888 | UE_FProperty UE_FSetProperty::GetElementProp() const { 889 | return Read(object + offsets.FProperty.Size); 890 | } 891 | 892 | std::string UE_FSetProperty::GetTypeStr() const { 893 | return "struct TSet<" + GetElementProp().GetType().second + ">"; 894 | } 895 | 896 | UE_FProperty UE_FMapProperty::GetKeyProp() const { 897 | return Read(object + offsets.FProperty.Size); 898 | } 899 | 900 | UE_FProperty UE_FMapProperty::GetValueProp() const { 901 | return Read(object + offsets.FProperty.Size + 8); 902 | } 903 | 904 | std::string UE_FMapProperty::GetTypeStr() const { 905 | return fmt::format("struct TMap<{}, {}>", GetKeyProp().GetType().second, GetValueProp().GetType().second); 906 | } 907 | 908 | UE_UClass UE_FInterfaceProperty::GetInterfaceClass() const { 909 | return Read(object + offsets.FProperty.Size); 910 | } 911 | 912 | std::string UE_FInterfaceProperty::GetTypeStr() const { 913 | return "struct TScriptInterface"; 914 | } 915 | 916 | UE_FName UE_FFieldPathProperty::GetPropertyName() const { 917 | return Read(object + offsets.FProperty.Size); 918 | } 919 | 920 | std::string UE_FFieldPathProperty::GetTypeStr() const { 921 | return "struct TFieldPath"; 922 | } 923 | 924 | void UE_UPackage::GenerateBitPadding(std::vector& members, uint32 offset, uint8 bitOffset, uint8 size) { 925 | Member padding; 926 | padding.Type = "char"; 927 | padding.Name = fmt::format("pad_{:0X}_{} : {}", offset, bitOffset, size); 928 | padding.Offset = offset; 929 | padding.Size = 1; 930 | members.push_back(padding); 931 | } 932 | 933 | void UE_UPackage::GeneratePadding(std::vector& members, uint32 offset, uint32 size) { 934 | Member padding; 935 | padding.Type = "char"; 936 | padding.Name = fmt::format("pad_{:0X}[{:#0x}]", offset, size); 937 | padding.Offset = offset; 938 | padding.Size = size; 939 | members.push_back(padding); 940 | } 941 | 942 | void UE_UPackage::FillPadding(UE_UStruct object, std::vector& members, uint32& offset, uint8& bitOffset, uint32 end, bool findPointers) { 943 | if (bitOffset && bitOffset < 8) { 944 | UE_UPackage::GenerateBitPadding(members, offset, bitOffset, 8 - bitOffset); 945 | bitOffset = 0; 946 | offset++; 947 | } 948 | 949 | auto size = end - offset; 950 | if (findPointers && size >= 8) { 951 | 952 | auto normalizedOffset = (offset + 7) & ~7; 953 | 954 | if (normalizedOffset != offset) { 955 | auto diff = normalizedOffset - offset; 956 | GeneratePadding(members, offset, diff); 957 | offset += diff; 958 | } 959 | 960 | auto normalizedSize = size - size % 8; 961 | 962 | auto num = normalizedSize / 8; 963 | 964 | uint64* pointers = new uint64[num * 2](); 965 | uint64* buffer = pointers + num; 966 | 967 | uint32 found = 0; 968 | auto callback = [&](UE_UObject object) { 969 | 970 | auto address = (uint64*)((uint64)object.GetAddress() + offset); 971 | 972 | Read(address, buffer, normalizedSize); 973 | 974 | for (uint32 i = 0; i < num; i++) { 975 | 976 | if (pointers[i]) continue; 977 | 978 | auto ptr = buffer[i]; 979 | if (!ptr) continue; 980 | 981 | uint64 vftable; 982 | if (Read((void*)ptr, &vftable, 8)) { 983 | pointers[i] = ptr; 984 | } 985 | else { 986 | pointers[i] = (uint64)-1; 987 | } 988 | 989 | found++; 990 | } 991 | 992 | if (found == num) return true; 993 | 994 | return false; 995 | 996 | }; 997 | 998 | ObjObjects.ForEachObjectOfClass((UE_UClass)object, callback); 999 | 1000 | auto start = offset; 1001 | for (uint32 i = 0; i < num; i++) { 1002 | auto ptr = pointers[i]; 1003 | if (ptr && ptr != (uint64)-1) { 1004 | 1005 | auto ptrObject = UE_UObject((void*)ptr); 1006 | 1007 | auto ptrOffset = start + i * 8; 1008 | if (ptrOffset > offset) { 1009 | GeneratePadding(members, offset, ptrOffset - offset); 1010 | offset = ptrOffset; 1011 | } 1012 | 1013 | Member m; 1014 | m.Offset = offset; 1015 | m.Size = 8; 1016 | 1017 | if (ptrObject.IsA()) { 1018 | m.Type = "struct " + ptrObject.GetClass().GetCppName() + "*"; 1019 | m.Name = ptrObject.GetName(); 1020 | } 1021 | else { 1022 | m.Type = "void*"; 1023 | m.Name = fmt::format("ptr_{:x}", ptr); 1024 | } 1025 | 1026 | 1027 | members.push_back(m); 1028 | 1029 | offset += 8; 1030 | } 1031 | } 1032 | delete[] pointers; 1033 | 1034 | } 1035 | 1036 | 1037 | if (offset != end) { 1038 | GeneratePadding(members, offset, end - offset); 1039 | offset = end; 1040 | } 1041 | } 1042 | 1043 | void UE_UPackage::GenerateFunction(UE_UFunction fn, Function *out) { 1044 | out->FullName = fn.GetFullName(); 1045 | out->Flags = fn.GetFunctionFlags(); 1046 | out->Func = fn.GetFunc(); 1047 | 1048 | auto generateParam = [&](IProperty *prop) { 1049 | auto flags = prop->GetPropertyFlags(); 1050 | // if property has 'ReturnParm' flag 1051 | if (flags & 0x400) { 1052 | out->CppName = prop->GetType().second + " " + fn.GetName(); 1053 | } 1054 | // if property has 'Parm' flag 1055 | else if (flags & 0x80) { 1056 | if (prop->GetArrayDim() > 1) { 1057 | out->Params += fmt::format("{}* {}, ", prop->GetType().second, prop->GetName()); 1058 | } else { 1059 | if (flags & 0x100) { 1060 | out->Params += fmt::format("{}& {}, ", prop->GetType().second, prop->GetName()); 1061 | } 1062 | else { 1063 | out->Params += fmt::format("{} {}, ", prop->GetType().second, prop->GetName()); 1064 | } 1065 | 1066 | } 1067 | } 1068 | }; 1069 | 1070 | for (auto prop = fn.GetChildProperties().Cast(); prop; prop = prop.GetNext().Cast()) { 1071 | auto propInterface = prop.GetInterface(); 1072 | generateParam(&propInterface); 1073 | } 1074 | for (auto prop = fn.GetChildren().Cast(); prop; prop = prop.GetNext().Cast()) { 1075 | auto propInterface = prop.GetInterface(); 1076 | generateParam(&propInterface); 1077 | } 1078 | if (out->Params.size()) { 1079 | out->Params.erase(out->Params.size() - 2); 1080 | } 1081 | 1082 | if (out->CppName.size() == 0) { 1083 | out->CppName = "void " + fn.GetName(); 1084 | } 1085 | } 1086 | 1087 | void UE_UPackage::GenerateStruct(UE_UStruct object, std::vector& arr, bool findPointers) { 1088 | Struct s; 1089 | s.Size = object.GetSize(); 1090 | if (s.Size == 0) { 1091 | return; 1092 | } 1093 | s.Inherited = 0; 1094 | s.FullName = object.GetFullName(); 1095 | s.CppName = "struct " + object.GetCppName(); 1096 | 1097 | auto super = object.GetSuper(); 1098 | if (super) { 1099 | s.CppName += " : " + super.GetCppName(); 1100 | s.Inherited = super.GetSize(); 1101 | } 1102 | 1103 | uint32 offset = s.Inherited; 1104 | uint8 bitOffset = 0; 1105 | 1106 | auto generateMember = [&](IProperty *prop, Member *m) { 1107 | auto arrDim = prop->GetArrayDim(); 1108 | m->Size = prop->GetSize() * arrDim; 1109 | if (m->Size == 0) { 1110 | return; 1111 | } // this shouldn't be zero 1112 | 1113 | auto type = prop->GetType(); 1114 | m->Type = type.second; 1115 | m->Name = prop->GetName(); 1116 | m->Offset = prop->GetOffset(); 1117 | 1118 | if (m->Offset > offset) { 1119 | UE_UPackage::FillPadding(object, s.Members, offset, bitOffset, m->Offset, findPointers); 1120 | } 1121 | if (type.first == PropertyType::BoolProperty && *(uint32*)type.second.data() != 'loob') { 1122 | auto boolProp = prop; 1123 | auto mask = boolProp->GetFieldMask(); 1124 | uint8 zeros = 0, ones = 0; 1125 | while (mask & ~1) { 1126 | mask >>= 1; 1127 | zeros++; 1128 | } 1129 | while (mask & 1) { 1130 | mask >>= 1; 1131 | ones++; 1132 | } 1133 | if (zeros > bitOffset) { 1134 | UE_UPackage::GenerateBitPadding(s.Members, offset, bitOffset, zeros - bitOffset); 1135 | bitOffset = zeros; 1136 | } 1137 | m->Name += fmt::format(" : {}", ones); 1138 | bitOffset += ones; 1139 | 1140 | if (bitOffset == 8) { 1141 | offset++; 1142 | bitOffset = 0; 1143 | } 1144 | 1145 | } else { 1146 | if (arrDim > 1) { 1147 | m->Name += fmt::format("[{:#0x}]", arrDim); 1148 | } 1149 | 1150 | offset += m->Size; 1151 | } 1152 | }; 1153 | 1154 | for (auto prop = object.GetChildProperties().Cast(); prop; prop = prop.GetNext().Cast()) { 1155 | Member m; 1156 | auto propInterface = prop.GetInterface(); 1157 | generateMember(&propInterface, &m); 1158 | s.Members.push_back(m); 1159 | } 1160 | 1161 | for (auto child = object.GetChildren(); child; child = child.GetNext()) { 1162 | if (child.IsA()) { 1163 | auto fn = child.Cast(); 1164 | Function f; 1165 | GenerateFunction(fn, &f); 1166 | s.Functions.push_back(f); 1167 | } else if (child.IsA()) { 1168 | auto prop = child.Cast(); 1169 | Member m; 1170 | auto propInterface = prop.GetInterface(); 1171 | generateMember(&propInterface, &m); 1172 | s.Members.push_back(m); 1173 | } 1174 | } 1175 | 1176 | if (s.Size > offset) { 1177 | UE_UPackage::FillPadding(object, s.Members, offset, bitOffset, s.Size, findPointers); 1178 | } 1179 | 1180 | arr.push_back(s); 1181 | } 1182 | 1183 | void UE_UPackage::GenerateEnum(UE_UEnum object, std::vector &arr) { 1184 | Enum e; 1185 | e.FullName = object.GetFullName(); 1186 | 1187 | auto names = object.GetNames(); 1188 | 1189 | uint64 max = 0; 1190 | uint64 nameSize = ((offsets.FName.Number + 4) + 7) & ~(7); 1191 | uint64 pairSize = nameSize + 8; 1192 | 1193 | for (uint32 i = 0; i < names.Count; i++) { 1194 | 1195 | auto pair = names.Data + i * pairSize; 1196 | auto name = UE_FName(pair); 1197 | auto str = name.GetName(); 1198 | auto pos = str.find_last_of(':'); 1199 | if (pos != std::string::npos) { 1200 | str = str.substr(pos + 1); 1201 | } 1202 | 1203 | auto value = Read(pair + nameSize); 1204 | if ((uint64)value > max) max = value; 1205 | 1206 | str.append(" = ").append(fmt::format("{}", value)); 1207 | e.Members.push_back(str); 1208 | } 1209 | 1210 | const char* type = nullptr; 1211 | 1212 | // I didn't see int16 yet, so I assume the engine generates only int32 and uint8: 1213 | if (max > 256) { 1214 | type = " : int32"; // I assume if enum has a negative value it is int32 1215 | } 1216 | else { 1217 | type = " : uint8"; 1218 | } 1219 | 1220 | e.CppName = "enum class " + object.GetName() + type; 1221 | 1222 | if (e.Members.size()) { 1223 | arr.push_back(e); 1224 | } 1225 | } 1226 | 1227 | void UE_UPackage::SaveStruct(std::vector &arr, FILE *file) { 1228 | for (auto &s : arr) { 1229 | fmt::print(file, "// {}\n// Size: {:#04x} (Inherited: {:#04x})\n{} {{", s.FullName, s.Size, s.Inherited, s.CppName); 1230 | for (auto &m : s.Members) { 1231 | fmt::print(file, "\n\t{} {}; // {:#04x}({:#04x})", m.Type, m.Name, m.Offset, m.Size); 1232 | } 1233 | if (s.Functions.size()) { 1234 | fwrite("\n", 1, 1, file); 1235 | for (auto &f : s.Functions) { 1236 | fmt::print(file, "\n\t{}({}); // {} // ({}) // @ game+{:#08x}", f.CppName, f.Params, f.FullName, f.Flags, f.Func - Base); 1237 | } 1238 | } 1239 | fmt::print(file, "\n}};\n\n"); 1240 | } 1241 | } 1242 | 1243 | void UE_UPackage::SaveStructSpacing(std::vector &arr, FILE *file) { 1244 | for (auto &s : arr) { 1245 | fmt::print(file, "// {}\n// Size: {:#04x} (Inherited: {:#04x})\n{} {{", s.FullName, s.Size, s.Inherited, s.CppName); 1246 | for (auto &m : s.Members) { 1247 | fmt::print(file, "\n\t{:69} {:60} // {:#04x}({:#04x})", m.Type, m.Name + ";", m.Offset, m.Size); 1248 | } 1249 | if (s.Functions.size()) { 1250 | fwrite("\n", 1, 1, file); 1251 | for (auto &f : s.Functions) { 1252 | fmt::print(file, "\n\t{:130} // {} // ({}) // @ game+{:#08x}", fmt::format("{}({});", f.CppName, f.Params), f.FullName, f.Flags, f.Func - Base); 1253 | } 1254 | } 1255 | 1256 | fmt::print(file, "\n}};\n\n"); 1257 | } 1258 | } 1259 | 1260 | void UE_UPackage::SaveEnum(std::vector &arr, FILE *file) { 1261 | for (auto &e : arr) { 1262 | fmt::print(file, "// {}\n{} {{", e.FullName, e.CppName); 1263 | 1264 | auto lastIdx = e.Members.size() - 1; 1265 | for (auto i = 0; i < lastIdx; i++) { 1266 | auto& m = e.Members.at(i); 1267 | fmt::print(file, "\n\t{},", m); 1268 | } 1269 | 1270 | auto& m = e.Members.at(lastIdx); 1271 | fmt::print(file, "\n\t{}", m); 1272 | 1273 | fmt::print(file, "\n}};\n\n"); 1274 | } 1275 | } 1276 | 1277 | void UE_UPackage::Process() { 1278 | auto &objects = Package->second; 1279 | for (auto &object : objects) { 1280 | if (object.IsA()) { 1281 | GenerateStruct(object.Cast(), Classes, FindPointers); 1282 | } else if (object.IsA()) { 1283 | GenerateStruct(object.Cast(), Structures, false); 1284 | } else if (object.IsA()) { 1285 | GenerateEnum(object.Cast(), Enums); 1286 | } 1287 | } 1288 | } 1289 | 1290 | bool UE_UPackage::Save(const fs::path &dir, bool spacing) { 1291 | if (!(Classes.size() || Structures.size() || Enums.size())) { 1292 | return false; 1293 | } 1294 | 1295 | std::string packageName = GetObject().GetName(); 1296 | 1297 | char chars[] = "/\\:*?\"<>|"; 1298 | for (auto c : chars) { 1299 | auto pos = packageName.find(c); 1300 | if (pos != std::string::npos) { 1301 | packageName[pos] = '_'; 1302 | } 1303 | } 1304 | 1305 | if (Classes.size()) { 1306 | File file(dir / (packageName + "_classes.h"), "w"); 1307 | if (!file) { 1308 | return false; 1309 | } 1310 | if (spacing) { 1311 | UE_UPackage::SaveStructSpacing(Classes, file); 1312 | } else { 1313 | UE_UPackage::SaveStruct(Classes, file); 1314 | } 1315 | } 1316 | 1317 | if (Structures.size() || Enums.size()) { 1318 | File file(dir / (packageName + "_struct.h"), "w"); 1319 | if (!file) { 1320 | return false; 1321 | } 1322 | 1323 | if (Enums.size()) { 1324 | UE_UPackage::SaveEnum(Enums, file); 1325 | } 1326 | 1327 | if (Structures.size()) { 1328 | if (spacing) { 1329 | UE_UPackage::SaveStructSpacing(Structures, file); 1330 | } else { 1331 | UE_UPackage::SaveStruct(Structures, file); 1332 | } 1333 | } 1334 | } 1335 | 1336 | return true; 1337 | } 1338 | 1339 | UE_UObject UE_UPackage::GetObject() const { return UE_UObject(Package->first); } 1340 | 1341 | 1342 | -------------------------------------------------------------------------------- /Dumper/Dumper/wrappers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "generic.h" 3 | #include 4 | #undef GetObject 5 | 6 | namespace fs = std::filesystem; 7 | 8 | // Wrapper for 'FILE*' that closes the file handle when it goes out of scope 9 | class File { 10 | private: 11 | FILE* file; 12 | 13 | public: 14 | File(fs::path path, const char *mode) { 15 | fopen_s(&file, path.string().c_str(), mode); 16 | } 17 | ~File() { 18 | if (file) { 19 | fclose(file); 20 | } 21 | } 22 | operator bool() const { return file != nullptr; } 23 | operator FILE *() { return file; } 24 | }; 25 | 26 | // Wrapper for array unit in global names array 27 | class UE_FNameEntry { 28 | protected: 29 | uint8 *object; 30 | 31 | public: 32 | UE_FNameEntry(uint8 *object) : object(object) {} 33 | UE_FNameEntry() : object(nullptr) {} 34 | operator bool() { return object != nullptr; } 35 | // Gets info about contained string (bool wide, uint16 len) depending on 36 | // 'offsets.FNameEntry' info 37 | std::pair Info() const; 38 | // Gets string out of array unit 39 | std::string String(bool wide, uint16 len) const; 40 | // Gets string out of array unit 41 | void String(char *buf, bool wide, uint16 len) const; 42 | std::string String() const; 43 | // Calculates the unit size depending on 'offsets.FNameEntry' and information 44 | // about string 45 | static uint16 Size(bool wide, uint16 len); 46 | }; 47 | 48 | class UE_FName { 49 | protected: 50 | uint8* object; 51 | 52 | public: 53 | UE_FName(uint8 *object) : object(object) {} 54 | UE_FName() : object(nullptr) {} 55 | std::string GetName() const; 56 | }; 57 | 58 | class UE_UClass; 59 | class UE_FField; 60 | 61 | enum class PropertyType { 62 | Unknown, 63 | StructProperty, 64 | ObjectProperty, 65 | SoftObjectProperty, 66 | FloatProperty, 67 | ByteProperty, 68 | BoolProperty, 69 | IntProperty, 70 | Int8Property, 71 | Int16Property, 72 | Int64Property, 73 | UInt16Property, 74 | UInt32Property, 75 | UInt64Property, 76 | NameProperty, 77 | DelegateProperty, 78 | SetProperty, 79 | ArrayProperty, 80 | WeakObjectProperty, 81 | StrProperty, 82 | TextProperty, 83 | MulticastSparseDelegateProperty, 84 | EnumProperty, 85 | DoubleProperty, 86 | MulticastDelegateProperty, 87 | ClassProperty, 88 | MulticastInlineDelegateProperty, 89 | MapProperty, 90 | InterfaceProperty, 91 | FieldPathProperty, 92 | SoftClassProperty 93 | }; 94 | 95 | class UE_UObject { 96 | protected: 97 | uint8* object; 98 | 99 | public: 100 | UE_UObject(void* object) : object((uint8*)object) {} 101 | UE_UObject() : object(nullptr) {} 102 | bool operator==(const UE_UObject obj) const { return obj.object == object; }; 103 | bool operator!=(const UE_UObject obj) const { return obj.object != object; }; 104 | uint32 GetIndex() const; 105 | UE_UClass GetClass() const; 106 | UE_UObject GetOuter() const; 107 | UE_UObject GetPackageObject() const; 108 | std::string GetName() const; 109 | std::string GetFullName() const; 110 | std::string GetCppName() const; 111 | void* GetAddress() const { return object; } 112 | operator uint8*() const { return object; }; 113 | operator bool() const { return object != nullptr; } 114 | 115 | template Base Cast() const { return Base(object); } 116 | 117 | template bool IsA() const; 118 | 119 | bool IsA(UE_UClass cmp) const; 120 | 121 | static UE_UClass StaticClass(); 122 | }; 123 | 124 | class UE_AActor : public UE_UObject { 125 | public: 126 | static UE_UClass StaticClass(); 127 | }; 128 | 129 | class UE_UField : public UE_UObject { 130 | public: 131 | using UE_UObject::UE_UObject; 132 | UE_UField GetNext() const; 133 | static UE_UClass StaticClass(); 134 | }; 135 | 136 | typedef std::pair type; 137 | 138 | class IProperty { 139 | protected: 140 | const void* prop; 141 | 142 | public: 143 | IProperty(const void *object) : prop(object) {} 144 | virtual std::string GetName() const = 0; 145 | virtual int32 GetArrayDim() const = 0; 146 | virtual int32 GetSize() const = 0; 147 | virtual int32 GetOffset() const = 0; 148 | virtual uint64 GetPropertyFlags() const = 0; 149 | virtual type GetType() const = 0; 150 | virtual uint8 GetFieldMask() const = 0; 151 | }; 152 | 153 | class IUProperty : public IProperty { 154 | public: 155 | using IProperty::IProperty; 156 | IUProperty(const class UE_UProperty *object) : IProperty(object) {} 157 | virtual std::string GetName() const; 158 | virtual int32 GetArrayDim() const; 159 | virtual int32 GetSize() const; 160 | virtual int32 GetOffset() const; 161 | virtual uint64 GetPropertyFlags() const; 162 | virtual type GetType() const; 163 | virtual uint8 GetFieldMask() const; 164 | }; 165 | 166 | class UE_UProperty : public UE_UField { 167 | public: 168 | using UE_UField::UE_UField; 169 | int32 GetArrayDim() const; 170 | int32 GetSize() const; 171 | int32 GetOffset() const; 172 | uint64 GetPropertyFlags() const; 173 | type GetType() const; 174 | 175 | IUProperty GetInterface() const; 176 | static UE_UClass StaticClass(); 177 | }; 178 | 179 | class UE_UStruct : public UE_UField { 180 | public: 181 | using UE_UField::UE_UField; 182 | UE_UStruct GetSuper() const; 183 | UE_FField GetChildProperties() const; 184 | UE_UField GetChildren() const; 185 | int32 GetSize() const; 186 | static UE_UClass StaticClass(); 187 | }; 188 | 189 | enum EFunctionFlags : uint32 190 | { 191 | // Function flags. 192 | FUNC_None = 0x00000000, 193 | FUNC_Final = 0x00000001, // Function is final (prebindable, non-overridable function). 194 | FUNC_RequiredAPI = 0x00000002, // Indicates this function is DLL exported/imported. 195 | FUNC_BlueprintAuthorityOnly = 0x00000004, // Function will only run if the object has network authority 196 | FUNC_BlueprintCosmetic = 0x00000008, // Function is cosmetic in nature and should not be invoked on dedicated servers 197 | // FUNC_ = 0x00000010, // unused. 198 | // FUNC_ = 0x00000020, // unused. 199 | FUNC_Net = 0x00000040, // Function is network-replicated. 200 | FUNC_NetReliable = 0x00000080, // Function should be sent reliably on the network. 201 | FUNC_NetRequest = 0x00000100, // Function is sent to a net service 202 | FUNC_Exec = 0x00000200, // Executable from command line. 203 | FUNC_Native = 0x00000400, // Native function. 204 | FUNC_Event = 0x00000800, // Event function. 205 | FUNC_NetResponse = 0x00001000, // Function response from a net service 206 | FUNC_Static = 0x00002000, // Static function. 207 | FUNC_NetMulticast = 0x00004000, // Function is networked multicast Server -> All Clients 208 | FUNC_UbergraphFunction = 0x00008000, // Function is used as the merge 'ubergraph' for a blueprint, only assigned when using the persistent 'ubergraph' frame 209 | FUNC_MulticastDelegate = 0x00010000, // Function is a multi-cast delegate signature (also requires FUNC_Delegate to be set!) 210 | FUNC_Public = 0x00020000, // Function is accessible in all classes (if overridden, parameters must remain unchanged). 211 | FUNC_Private = 0x00040000, // Function is accessible only in the class it is defined in (cannot be overridden, but function name may be reused in subclasses. IOW: if overridden, parameters don't need to match, and Super.Func() cannot be accessed since it's private.) 212 | FUNC_Protected = 0x00080000, // Function is accessible only in the class it is defined in and subclasses (if overridden, parameters much remain unchanged). 213 | FUNC_Delegate = 0x00100000, // Function is delegate signature (either single-cast or multi-cast, depending on whether FUNC_MulticastDelegate is set.) 214 | FUNC_NetServer = 0x00200000, // Function is executed on servers (set by replication code if passes check) 215 | FUNC_HasOutParms = 0x00400000, // function has out (pass by reference) parameters 216 | FUNC_HasDefaults = 0x00800000, // function has structs that contain defaults 217 | FUNC_NetClient = 0x01000000, // function is executed on clients 218 | FUNC_DLLImport = 0x02000000, // function is imported from a DLL 219 | FUNC_BlueprintCallable = 0x04000000, // function can be called from blueprint code 220 | FUNC_BlueprintEvent = 0x08000000, // function can be overridden/implemented from a blueprint 221 | FUNC_BlueprintPure = 0x10000000, // function can be called from blueprint code, and is also pure (produces no side effects). If you set this, you should set FUNC_BlueprintCallable as well. 222 | FUNC_EditorOnly = 0x20000000, // function can only be called from an editor scrippt. 223 | FUNC_Const = 0x40000000, // function can be called from blueprint code, and only reads state (never writes state) 224 | FUNC_NetValidate = 0x80000000, // function must supply a _Validate implementation 225 | FUNC_AllFlags = 0xFFFFFFFF, 226 | }; 227 | 228 | class UE_UFunction : public UE_UStruct { 229 | public: 230 | using UE_UStruct::UE_UStruct; 231 | uint64 GetFunc() const; 232 | std::string GetFunctionFlags() const; 233 | static UE_UClass StaticClass(); 234 | }; 235 | 236 | class UE_UScriptStruct : public UE_UStruct { 237 | public: 238 | using UE_UStruct::UE_UStruct; 239 | static UE_UClass StaticClass(); 240 | }; 241 | 242 | class UE_UClass : public UE_UStruct { 243 | public: 244 | using UE_UStruct::UE_UStruct; 245 | static UE_UClass StaticClass(); 246 | }; 247 | 248 | class UE_UEnum : public UE_UField { 249 | public: 250 | using UE_UField::UE_UField; 251 | TArray GetNames() const; 252 | static UE_UClass StaticClass(); 253 | }; 254 | 255 | class UE_UDoubleProperty : public UE_UProperty { 256 | public: 257 | using UE_UProperty::UE_UProperty; 258 | std::string GetTypeStr() const; 259 | static UE_UClass StaticClass(); 260 | }; 261 | 262 | class UE_UFloatProperty : public UE_UProperty { 263 | public: 264 | using UE_UProperty::UE_UProperty; 265 | std::string GetTypeStr() const; 266 | static UE_UClass StaticClass(); 267 | }; 268 | 269 | class UE_UIntProperty : public UE_UProperty { 270 | public: 271 | using UE_UProperty::UE_UProperty; 272 | std::string GetTypeStr() const; 273 | static UE_UClass StaticClass(); 274 | }; 275 | 276 | class UE_UInt16Property : public UE_UProperty { 277 | public: 278 | using UE_UProperty::UE_UProperty; 279 | std::string GetTypeStr() const; 280 | static UE_UClass StaticClass(); 281 | }; 282 | 283 | class UE_UInt64Property : public UE_UProperty { 284 | public: 285 | using UE_UProperty::UE_UProperty; 286 | std::string GetTypeStr() const; 287 | static UE_UClass StaticClass(); 288 | }; 289 | 290 | class UE_UInt8Property : public UE_UProperty { 291 | public: 292 | using UE_UProperty::UE_UProperty; 293 | std::string GetTypeStr() const; 294 | static UE_UClass StaticClass(); 295 | }; 296 | 297 | class UE_UUInt16Property : public UE_UProperty { 298 | public: 299 | using UE_UProperty::UE_UProperty; 300 | std::string GetTypeStr() const; 301 | static UE_UClass StaticClass(); 302 | }; 303 | 304 | class UE_UUInt32Property : public UE_UProperty { 305 | public: 306 | using UE_UProperty::UE_UProperty; 307 | std::string GetTypeStr() const; 308 | static UE_UClass StaticClass(); 309 | }; 310 | 311 | class UE_UUInt64Property : public UE_UProperty { 312 | public: 313 | using UE_UProperty::UE_UProperty; 314 | std::string GetTypeStr() const; 315 | static UE_UClass StaticClass(); 316 | }; 317 | 318 | class UE_UTextProperty : public UE_UProperty { 319 | public: 320 | using UE_UProperty::UE_UProperty; 321 | std::string GetTypeStr() const; 322 | static UE_UClass StaticClass(); 323 | }; 324 | 325 | class UE_UStrProperty : public UE_UProperty { 326 | public: 327 | using UE_UProperty::UE_UProperty; 328 | std::string GetTypeStr() const; 329 | static UE_UClass StaticClass(); 330 | }; 331 | 332 | class UE_UStructProperty : public UE_UProperty { 333 | public: 334 | using UE_UProperty::UE_UProperty; 335 | UE_UStruct GetStruct() const; 336 | std::string GetTypeStr() const; 337 | static UE_UClass StaticClass(); 338 | }; 339 | 340 | class UE_UNameProperty : public UE_UProperty { 341 | public: 342 | using UE_UProperty::UE_UProperty; 343 | std::string GetTypeStr() const; 344 | static UE_UClass StaticClass(); 345 | }; 346 | 347 | class UE_UObjectPropertyBase : public UE_UProperty { 348 | public: 349 | using UE_UProperty::UE_UProperty; 350 | UE_UClass GetPropertyClass() const; 351 | std::string GetTypeStr() const; 352 | static UE_UClass StaticClass(); 353 | }; 354 | 355 | class UE_UArrayProperty : public UE_UProperty { 356 | public: 357 | using UE_UProperty::UE_UProperty; 358 | UE_UProperty GetInner() const; 359 | std::string GetTypeStr() const; 360 | static UE_UClass StaticClass(); 361 | }; 362 | 363 | class UE_UByteProperty : public UE_UProperty { 364 | public: 365 | using UE_UProperty::UE_UProperty; 366 | UE_UEnum GetEnum() const; 367 | std::string GetTypeStr() const; 368 | static UE_UClass StaticClass(); 369 | }; 370 | 371 | class UE_UBoolProperty : public UE_UProperty { 372 | public: 373 | using UE_UProperty::UE_UProperty; 374 | uint8 GetFieldMask() const; 375 | std::string GetTypeStr() const; 376 | static UE_UClass StaticClass(); 377 | }; 378 | 379 | class UE_UEnumProperty : public UE_UProperty { 380 | public: 381 | using UE_UProperty::UE_UProperty; 382 | UE_UClass GetEnum() const; 383 | std::string GetTypeStr() const; 384 | static UE_UClass StaticClass(); 385 | }; 386 | 387 | class UE_UClassProperty : public UE_UProperty { 388 | public: 389 | using UE_UProperty::UE_UProperty; 390 | UE_UClass GetMetaClass() const; 391 | std::string GetTypeStr() const; 392 | static UE_UClass StaticClass(); 393 | }; 394 | 395 | class UE_USetProperty : public UE_UProperty { 396 | public: 397 | using UE_UProperty::UE_UProperty; 398 | UE_UProperty GetElementProp() const; 399 | std::string GetTypeStr() const; 400 | static UE_UClass StaticClass(); 401 | }; 402 | 403 | class UE_UMapProperty : public UE_UProperty { 404 | public: 405 | using UE_UProperty::UE_UProperty; 406 | UE_UProperty GetKeyProp() const; 407 | UE_UProperty GetValueProp() const; 408 | std::string GetTypeStr() const; 409 | static UE_UClass StaticClass(); 410 | }; 411 | 412 | class UE_UInterfaceProperty : public UE_UProperty { 413 | public: 414 | using UE_UProperty::UE_UProperty; 415 | UE_UProperty GetInterfaceClass() const; 416 | std::string GetTypeStr() const; 417 | static UE_UClass StaticClass(); 418 | }; 419 | 420 | class UE_UMulticastDelegateProperty : public UE_UProperty { 421 | public: 422 | using UE_UProperty::UE_UProperty; 423 | std::string GetTypeStr() const; 424 | static UE_UClass StaticClass(); 425 | }; 426 | 427 | class UE_UWeakObjectProperty : public UE_UProperty { 428 | public: 429 | using UE_UProperty::UE_UProperty; 430 | std::string GetTypeStr() const; 431 | static UE_UClass StaticClass(); 432 | }; 433 | 434 | class UE_FFieldClass { 435 | protected: 436 | uint8 *object; 437 | 438 | public: 439 | UE_FFieldClass(uint8 *object) : object(object){}; 440 | UE_FFieldClass() : object(nullptr){}; 441 | std::string GetName() const; 442 | }; 443 | 444 | class UE_FField { 445 | protected: 446 | uint8 *object; 447 | 448 | public: 449 | UE_FField(uint8 *object) : object(object) {} 450 | UE_FField() : object(nullptr) {} 451 | operator bool() const { return object != nullptr; } 452 | UE_FField GetNext() const; 453 | std::string GetName() const; 454 | 455 | template Base Cast() const { return Base(object); } 456 | }; 457 | 458 | class IFProperty : public IProperty { 459 | public: 460 | IFProperty(const class UE_FProperty *object) : IProperty(object) {} 461 | virtual std::string GetName() const; 462 | virtual int32 GetArrayDim() const; 463 | virtual int32 GetSize() const; 464 | virtual int32 GetOffset() const; 465 | virtual uint64 GetPropertyFlags() const; 466 | virtual type GetType() const; 467 | virtual uint8 GetFieldMask() const; 468 | }; 469 | 470 | 471 | 472 | class UE_FProperty : public UE_FField { 473 | public: 474 | using UE_FField::UE_FField; 475 | int32 GetArrayDim() const; 476 | int32 GetSize() const; 477 | int32 GetOffset() const; 478 | uint64 GetPropertyFlags() const; 479 | type GetType() const; 480 | IFProperty GetInterface() const; 481 | }; 482 | 483 | class UE_FStructProperty : public UE_FProperty { 484 | public: 485 | using UE_FProperty::UE_FProperty; 486 | UE_UStruct GetStruct() const; 487 | std::string GetTypeStr() const; 488 | }; 489 | 490 | class UE_FObjectPropertyBase : public UE_FProperty { 491 | public: 492 | using UE_FProperty::UE_FProperty; 493 | UE_UClass GetPropertyClass() const; 494 | std::string GetTypeStr() const; 495 | }; 496 | 497 | class UE_FArrayProperty : public UE_FProperty { 498 | public: 499 | using UE_FProperty::UE_FProperty; 500 | UE_FProperty GetInner() const; 501 | std::string GetTypeStr() const; 502 | }; 503 | 504 | class UE_FByteProperty : public UE_FProperty { 505 | public: 506 | using UE_FProperty::UE_FProperty; 507 | UE_UEnum GetEnum() const; 508 | std::string GetTypeStr() const; 509 | }; 510 | 511 | class UE_FBoolProperty : public UE_FProperty { 512 | public: 513 | using UE_FProperty::UE_FProperty; 514 | uint8 GetFieldMask() const; 515 | std::string GetTypeStr() const; 516 | }; 517 | 518 | class UE_FEnumProperty : public UE_FProperty { 519 | public: 520 | using UE_FProperty::UE_FProperty; 521 | UE_UClass GetEnum() const; 522 | std::string GetTypeStr() const; 523 | }; 524 | 525 | class UE_FClassProperty : public UE_FObjectPropertyBase { 526 | public: 527 | using UE_FObjectPropertyBase::UE_FObjectPropertyBase; 528 | UE_UClass GetMetaClass() const; 529 | std::string GetTypeStr() const; 530 | }; 531 | 532 | class UE_FSetProperty : public UE_FProperty { 533 | public: 534 | using UE_FProperty::UE_FProperty; 535 | UE_FProperty GetElementProp() const; 536 | std::string GetTypeStr() const; 537 | }; 538 | 539 | class UE_FMapProperty : public UE_FProperty { 540 | public: 541 | using UE_FProperty::UE_FProperty; 542 | UE_FProperty GetKeyProp() const; 543 | UE_FProperty GetValueProp() const; 544 | std::string GetTypeStr() const; 545 | }; 546 | 547 | class UE_FInterfaceProperty : public UE_FProperty { 548 | public: 549 | using UE_FProperty::UE_FProperty; 550 | UE_UClass GetInterfaceClass() const; 551 | std::string GetTypeStr() const; 552 | }; 553 | 554 | class UE_FFieldPathProperty : public UE_FProperty { 555 | public: 556 | using UE_FProperty::UE_FProperty; 557 | UE_FName GetPropertyName() const; 558 | std::string GetTypeStr() const; 559 | }; 560 | 561 | template bool UE_UObject::IsA() const { 562 | auto cmp = T::StaticClass(); 563 | if (!cmp) { 564 | return false; 565 | } 566 | 567 | return IsA(cmp); 568 | } 569 | 570 | class UE_UPackage { 571 | private: 572 | struct Member { 573 | std::string Type; 574 | std::string Name; 575 | uint32 Offset = 0; 576 | uint32 Size = 0; 577 | }; 578 | struct Function { 579 | std::string FullName; 580 | std::string CppName; 581 | std::string Params; 582 | std::string Flags; 583 | uint64 Func = 0; 584 | }; 585 | struct Struct { 586 | std::string FullName; 587 | std::string CppName; 588 | uint32 Inherited = 0; 589 | uint32 Size = 0; 590 | std::vector Members; 591 | std::vector Functions; 592 | }; 593 | struct Enum { 594 | std::string FullName; 595 | std::string CppName; 596 | std::vector Members; 597 | }; 598 | 599 | private: 600 | std::pair> *Package; 601 | std::vector Classes; 602 | std::vector Structures; 603 | std::vector Enums; 604 | public: 605 | bool FindPointers = false; 606 | 607 | 608 | private: 609 | static void GenerateBitPadding(std::vector& members, uint32 offset, uint8 bitOffset, uint8 size); 610 | static void GeneratePadding(std::vector& members, uint32 offset, uint32 size); 611 | static void FillPadding(UE_UStruct object, std::vector& members, uint32& offset, uint8& bitOffset, uint32 end, bool findPointers); 612 | static void GenerateFunction(UE_UFunction fn, Function* out); 613 | static void GenerateStruct(UE_UStruct object, std::vector& arr, bool findPointers); 614 | static void GenerateEnum(UE_UEnum object, std::vector& arr); 615 | static void SaveStruct(std::vector &arr, FILE *file); 616 | static void SaveStructSpacing(std::vector &arr, FILE* file); // save struct with spacing to members applied 617 | static void SaveEnum(std::vector &arr, FILE* file); 618 | public: 619 | UE_UPackage(std::pair>& package) : Package(&package){}; 620 | void Process(); 621 | bool Save(const fs::path& dir, bool spacing); 622 | UE_UObject GetObject() const; 623 | }; 624 | -------------------------------------------------------------------------------- /Dumper/include/fmt/format.cc: -------------------------------------------------------------------------------- 1 | // Formatting library for C++ 2 | // 3 | // Copyright (c) 2012 - 2016, Victor Zverovich 4 | // All rights reserved. 5 | // 6 | // For the license information refer to format.h. 7 | 8 | #include "fmt/format-inl.h" 9 | 10 | FMT_BEGIN_NAMESPACE 11 | namespace detail { 12 | 13 | template 14 | int format_float(char* buf, std::size_t size, const char* format, int precision, 15 | T value) { 16 | #ifdef FMT_FUZZ 17 | if (precision > 100000) 18 | throw std::runtime_error( 19 | "fuzz mode - avoid large allocation inside snprintf"); 20 | #endif 21 | // Suppress the warning about nonliteral format string. 22 | int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF; 23 | return precision < 0 ? snprintf_ptr(buf, size, format, value) 24 | : snprintf_ptr(buf, size, format, precision, value); 25 | } 26 | 27 | template FMT_API dragonbox::decimal_fp dragonbox::to_decimal(float x) 28 | FMT_NOEXCEPT; 29 | template FMT_API dragonbox::decimal_fp dragonbox::to_decimal(double x) 30 | FMT_NOEXCEPT; 31 | } // namespace detail 32 | 33 | // Workaround a bug in MSVC2013 that prevents instantiation of format_float. 34 | int (*instantiate_format_float)(double, int, detail::float_specs, 35 | detail::buffer&) = detail::format_float; 36 | 37 | #ifndef FMT_STATIC_THOUSANDS_SEPARATOR 38 | template FMT_API detail::locale_ref::locale_ref(const std::locale& loc); 39 | template FMT_API std::locale detail::locale_ref::get() const; 40 | #endif 41 | 42 | // Explicit instantiations for char. 43 | 44 | template FMT_API auto detail::thousands_sep_impl(locale_ref) 45 | -> thousands_sep_result; 46 | template FMT_API char detail::decimal_point_impl(locale_ref); 47 | 48 | template FMT_API void detail::buffer::append(const char*, const char*); 49 | 50 | template FMT_API void detail::vformat_to( 51 | detail::buffer&, string_view, 52 | basic_format_args, detail::locale_ref); 53 | 54 | template FMT_API int detail::snprintf_float(double, int, detail::float_specs, 55 | detail::buffer&); 56 | template FMT_API int detail::snprintf_float(long double, int, 57 | detail::float_specs, 58 | detail::buffer&); 59 | template FMT_API int detail::format_float(double, int, detail::float_specs, 60 | detail::buffer&); 61 | template FMT_API int detail::format_float(long double, int, detail::float_specs, 62 | detail::buffer&); 63 | 64 | // Explicit instantiations for wchar_t. 65 | 66 | template FMT_API auto detail::thousands_sep_impl(locale_ref) 67 | -> thousands_sep_result; 68 | template FMT_API wchar_t detail::decimal_point_impl(locale_ref); 69 | 70 | template FMT_API void detail::buffer::append(const wchar_t*, 71 | const wchar_t*); 72 | 73 | template struct detail::basic_data; 74 | 75 | FMT_END_NAMESPACE 76 | -------------------------------------------------------------------------------- /Dumper/include/hash/hash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | constexpr uint64 Prime = 1099511628211; 5 | constexpr uint64 Basis = 14695981039346656037; 6 | 7 | template< typename Type > 8 | constexpr uint64 HashCompute(uint64 hash, const Type* const data, uint64 size) { 9 | const auto element = (uint64)(data[0]); 10 | return (size == 0) ? hash : HashCompute((hash * Prime) ^ element, data + 1, size - 1); 11 | } 12 | 13 | template< typename Type > 14 | constexpr uint64 Hash(const Type* const data, uint64 size){ 15 | return HashCompute(Basis, data, size); 16 | } 17 | 18 | #define HASH( Data ) \ 19 | [ & ]() \ 20 | { \ 21 | constexpr auto hash = Hash( Data, sizeof(Data) - 1 ); \ 22 | return hash; \ 23 | }() -------------------------------------------------------------------------------- /Dumper/include/types.h: -------------------------------------------------------------------------------- 1 | typedef signed char int8; 2 | typedef short int16; 3 | typedef int int32; 4 | typedef long long int64; 5 | 6 | typedef unsigned char uint8; 7 | typedef unsigned short uint16; 8 | typedef unsigned int uint32; 9 | typedef unsigned long long uint64; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 GoLang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UE4Dumper-Kernel 2 | 3 | Credits: 4 | 5 | Original Snippet: https://github.com/guttir14/UnrealDumper-4.25 && https://github.com/DarthTon/Blackbone for something. 6 | 7 | SerseDioRe for help in getting the information from the peb into the kernel. 8 | -------------------------------------------------------------------------------- /RootKit.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 16 3 | VisualStudioVersion = 16.0.31624.102 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Driver", "Driver\Driver.vcxproj", "{2BC9C890-EE95-4219-AC58-872DDB9D7F5E}" 6 | EndProject 7 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dumper", "Dumper\Dumper\Dumper.vcxproj", "{4E175DB2-CFFD-48F9-888F-AF140E44068D}" 8 | EndProject 9 | Global 10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 11 | Debug|ARM = Debug|ARM 12 | Debug|ARM64 = Debug|ARM64 13 | Debug|x64 = Debug|x64 14 | Debug|x86 = Debug|x86 15 | Release|ARM = Release|ARM 16 | Release|ARM64 = Release|ARM64 17 | Release|x64 = Release|x64 18 | Release|x86 = Release|x86 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|ARM.ActiveCfg = Debug|ARM 22 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|ARM.Build.0 = Debug|ARM 23 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|ARM.Deploy.0 = Debug|ARM 24 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|ARM64.ActiveCfg = Debug|ARM64 25 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|ARM64.Build.0 = Debug|ARM64 26 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|ARM64.Deploy.0 = Debug|ARM64 27 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|x64.ActiveCfg = Debug|x64 28 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|x64.Build.0 = Debug|x64 29 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|x64.Deploy.0 = Debug|x64 30 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|x86.ActiveCfg = Debug|Win32 31 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|x86.Build.0 = Debug|Win32 32 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Debug|x86.Deploy.0 = Debug|Win32 33 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|ARM.ActiveCfg = Release|ARM 34 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|ARM.Build.0 = Release|ARM 35 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|ARM.Deploy.0 = Release|ARM 36 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|ARM64.ActiveCfg = Release|ARM64 37 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|ARM64.Build.0 = Release|ARM64 38 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|ARM64.Deploy.0 = Release|ARM64 39 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|x64.ActiveCfg = Release|x64 40 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|x64.Build.0 = Release|x64 41 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|x64.Deploy.0 = Release|x64 42 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|x86.ActiveCfg = Release|Win32 43 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|x86.Build.0 = Release|Win32 44 | {2BC9C890-EE95-4219-AC58-872DDB9D7F5E}.Release|x86.Deploy.0 = Release|Win32 45 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Debug|ARM.ActiveCfg = Debug|Win32 46 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Debug|ARM64.ActiveCfg = Debug|Win32 47 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Debug|x64.ActiveCfg = Debug|x64 48 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Debug|x64.Build.0 = Debug|x64 49 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Debug|x86.ActiveCfg = Debug|Win32 50 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Debug|x86.Build.0 = Debug|Win32 51 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Release|ARM.ActiveCfg = Release|Win32 52 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Release|ARM64.ActiveCfg = Release|Win32 53 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Release|x64.ActiveCfg = Release|x64 54 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Release|x64.Build.0 = Release|x64 55 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Release|x86.ActiveCfg = Release|Win32 56 | {403CCF71-C4D3-4B5F-ABB1-2B3C2CCC8C45}.Release|x86.Build.0 = Release|Win32 57 | {4E175DB2-CFFD-48F9-888F-AF140E44068D}.Debug|ARM.ActiveCfg = Debug|x64 58 | {4E175DB2-CFFD-48F9-888F-AF140E44068D}.Debug|ARM64.ActiveCfg = Debug|x64 59 | {4E175DB2-CFFD-48F9-888F-AF140E44068D}.Debug|x64.ActiveCfg = Debug|x64 60 | {4E175DB2-CFFD-48F9-888F-AF140E44068D}.Debug|x64.Build.0 = Debug|x64 61 | {4E175DB2-CFFD-48F9-888F-AF140E44068D}.Debug|x86.ActiveCfg = Debug|x64 62 | {4E175DB2-CFFD-48F9-888F-AF140E44068D}.Release|ARM.ActiveCfg = Release|x64 63 | {4E175DB2-CFFD-48F9-888F-AF140E44068D}.Release|ARM64.ActiveCfg = Release|x64 64 | {4E175DB2-CFFD-48F9-888F-AF140E44068D}.Release|x64.ActiveCfg = Release|x64 65 | {4E175DB2-CFFD-48F9-888F-AF140E44068D}.Release|x64.Build.0 = Release|x64 66 | {4E175DB2-CFFD-48F9-888F-AF140E44068D}.Release|x86.ActiveCfg = Release|x64 67 | EndGlobalSection 68 | GlobalSection(SolutionProperties) = preSolution 69 | HideSolutionNode = FALSE 70 | EndGlobalSection 71 | GlobalSection(ExtensibilityGlobals) = postSolution 72 | SolutionGuid = {9CA3F3C4-F47B-4E8B-B25D-96C4ADC57659} 73 | EndGlobalSection 74 | EndGlobal 75 | --------------------------------------------------------------------------------