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