18#define MAX_PID 0xFFFFFFFCUL
20#define MAX_FREE_POOL 1024u
22#define PML4_INDEX(addr) (((addr) >> 39) & 0x1FFULL)
23#define KERNEL_PML4_START ((size_t)PML4_INDEX(KernelVaStart))
24#define USER_INITIAL_STACK_TOP USER_VA_END
26#define MTDLL_TARGET_ENTRY "LdrInitializeProcess"
27#define MTDLL_PATH "mtdll.mtdll"
28#define MAX_EXPORTED_FUNC_NAME 256
38GetBaseName(
const char* fullpath,
char* out,
size_t outsz) {
39 const char* ext =
".mtexe";
41 if (!fullpath || !out || outsz == 0)
return false;
44 const char* p = fullpath + len;
45 while (p > fullpath && *(p - 1) !=
'/') --p;
48 if (name_len < ext_len ||
kstrcmp(p + name_len - ext_len, ext) != 0)
return false;
50 if (name_len + 1 > outsz)
return false;
57ReadStringFromFile(
PFILE_OBJECT FileObject, uint64_t off,
char* buf,
size_t buf_len)
62 if (buf_len == 0)
return -1;
65 st =
FsReadFile(FileObject, off, buf, buf_len - 1, &got);
69 buf[got >= (buf_len - 1) ? (buf_len - 1) : got] =
'\0';
72 if (kmemchr(buf,
'\0', got) == NULL)
return -1;
89 st =
FsReadFile(MtdllObject, 0, &hdr,
sizeof(hdr), &br);
90 if (
MT_FAILURE(st) || br <
sizeof(hdr))
return NULL;
100 if (max_entries == 0)
return NULL;
105 for (
size_t i = 0; i < max_entries; ++i) {
109 st =
FsReadFile(MtdllObject, entry_off, &entry,
sizeof(entry), &br);
116 uint64_t name_rva_calculated = entry.
name_rva;
118 if (name_rva_calculated == 0)
continue;
121 if (name_rva_calculated >= MtdllObject->FileSize)
continue;
124 if (ReadStringFromFile(MtdllObject, name_rva_calculated, namebuf,
sizeof(namebuf)) != 0) {
131 return (
void*)(uintptr_t)(entry.
func_rva);
146 int64_t delta = (uintptr_t)ImageBase - (uintptr_t)Header->PreferredImageBase;
152 if (Header->reloc_rva == 0 || Header->reloc_size == 0) {
159 Rela* reloc_table = (
Rela*)((uintptr_t)ImageBase + Header->reloc_rva);
160 size_t count = Header->reloc_size /
sizeof(
Rela);
163 for (
size_t i = 0; i < count; i++) {
164 Rela* entry = &reloc_table[i];
170 uintptr_t* target_ptr = (uintptr_t*)((uintptr_t)ImageBase + entry->
r_offset);
173 *target_ptr = (uintptr_t)ImageBase + entry->
r_addend;
182 IN const char* ExecutablePath,
244 GetBaseName(ExecutablePath, filename,
sizeof(filename));
245 if (filename[0] ==
'\0')
goto CleanupWithRef;
252 void* DirectoryTablePhysical = NULL;
260 if (!HandleTable)
goto CleanupWithRef;
274 void* MtdllInitializeProcessRva = PspFindMtdllEntry(MtdllObject);
275 if (!MtdllInitializeProcessRva) {
302 if (LoadedHeader->
Magic[0] ==
'M' && LoadedHeader->
Magic[1] ==
'T' && LoadedHeader->
Magic[2] ==
'E') {
305 PspRelocateImage(MtdllBase, LoadedHeader);
317 void* MtdllInitializeProcess = (
void*)((uintptr_t)MtdllBase + (uintptr_t)MtdllInitializeProcessRva);
352 void* StartAddress = NULL;
354 void* FileBaseAddress = NULL;
361 Status =
MmCreatePeb(Process, (
void**)&Process->
Peb, (
void**)&BasicTypes);
416 if (ProcessHandle) *ProcessHandle = hProcess;
422 assert(
false,
"Something went wrong.");
462 bool SeenOurselves =
false;
469 (
void*)(uintptr_t)Process,
470 (
void*)(uintptr_t)ExitCode,
492 if (Thread == current) {
493 SeenOurselves =
true;
523 IN void* ProcessObject
577 Entry = LastThread->ThreadListEntry.
Flink;
578 if (Entry == &LastThread->ThreadListEntry) {
586 Entry = ListHead->
Flink;
594 while (ListHead != Entry) {
602 Entry = Entry->
Flink;
FORCEINLINE int32_t InterlockedOr32(volatile int32_t *target, int32_t value)
void MeDetachProcess(IN PAPC_STATE ApcState)
void MeAttachProcess(IN PIPROCESS Process, OUT PAPC_STATE ApcState)
NORETURN void MeBugCheckEx(IN enum _BUGCHECK_CODES BugCheckCode, IN void *BugCheckParameter1, IN void *BugCheckParameter2, IN void *BugCheckParameter3, IN void *BugCheckParameter4)
HANDLE PsAllocateProcessId(IN PEPROCESS Process)
void PsFreeCid(IN HANDLE Cid)
struct _EPROCESS EPROCESS
struct _DOUBLY_LINKED_LIST * PDOUBLY_LINKED_LIST
#define MT_FILE_ALL_ACCESS
struct _FILE_OBJECT * PFILE_OBJECT
size_t kstrlen(const char *str)
void gop_printf(uint32_t color, const char *fmt,...)
char * kstrncpy(char *dst, const char *src, size_t n)
int kstrcmp(const char *s1, const char *s2)
PHANDLE_TABLE HtCreateHandleTable(IN PEPROCESS Process)
MTSTATUS HtClose(IN HANDLE Handle)
void HtDeleteHandleTable(IN PHANDLE_TABLE Table)
struct _HANDLE_TABLE * PHANDLE_TABLE
FORCEINLINE void __stac(void)
FORCEINLINE void __clac(void)
#define CONTAINING_RECORD(ptr, type, member)
struct _APC_STATE APC_STATE
@ DEFAULT_TIMESLICE_TICKS
#define COLOR_RED
Colors definitions for easier access.
#define PhysicalMemoryOffset
#define R_X86_64_RELATIVE
MTSTATUS MmCreateProcessAddressSpace(OUT void **DirectoryTable)
MTSTATUS MmDeleteProcessAddressSpace(IN PEPROCESS Process, IN uintptr_t PageDirectoryPhysical)
MTSTATUS MmCreatePeb(IN PEPROCESS Process, OUT void **OutPeb, OUT void **OutBasicMtdllTypes)
FORCEINLINE void InitializeListHead(PDOUBLY_LINKED_LIST Head)
#define MT_PROCESS_IS_TERMINATING
#define MT_GENERAL_FAILURE
#define MT_NOTHING_TO_TERMINATE
#define MT_FAILURE(Status)
#define MT_SUCCEEDED(Status)
Macros to test status.
MTSTATUS ObCreateHandleForObject(IN void *Object, IN ACCESS_MASK DesiredAccess, OUT PHANDLE ReturnedHandle)
MTSTATUS ObReferenceObjectByHandle(IN HANDLE Handle, IN uint32_t DesiredAccess, IN POBJECT_TYPE DesiredType, OUT void **Object, _Out_Opt PHANDLE_TABLE_ENTRY HandleInformation)
MTSTATUS ObReferenceObjectByPointer(IN void *Object, IN POBJECT_TYPE DesiredType)
void ObDereferenceObject(IN void *Object)
MTSTATUS ObCreateObject(IN POBJECT_TYPE ObjectType, IN uint32_t ObjectSize, OUT void **ObjectCreated)
uintptr_t MmSystemRangeStart
PETHREAD PsGetNextProcessThread(IN PEPROCESS Process, _In_Opt PETHREAD LastThread)
uintptr_t MmUserProbeAddress
MTSTATUS PsTerminateProcess(IN PEPROCESS Process, IN MTSTATUS ExitCode)
void PsDeleteProcess(IN void *ProcessObject)
#define MAX_EXPORTED_FUNC_NAME
#define USER_INITIAL_STACK_TOP
#define MTDLL_TARGET_ENTRY
uintptr_t MmUserStartAddress
MTSTATUS PsCreateProcess(IN const char *ExecutablePath, OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, _In_Opt HANDLE ParentProcess)
uintptr_t MmHighestUserAddress
FORCEINLINE MTSTATUS GetExceptionCode(void)
struct _MTDLL_BASIC_TYPES * PMTDLL_BASIC_TYPES
void(* ThreadEntry)(THREAD_PARAMETER)
enum _PROCESS_FLAGS PROCESS_FLAGS
@ ProcessBreakOnTermination
#define MT_PROCESS_CREATE_PROCESS
POBJECT_TYPE PsThreadType
POBJECT_TYPE PsProcessType
void MsAcquirePushLockShared(IN PUSH_LOCK *Lock)
void MsReleasePushLockShared(IN PUSH_LOCK *Lock)
void MsWaitForRundownProtectionRelease(IN PRUNDOWN_REF rundown)
MTSTATUS MmMapViewOfSection(IN HANDLE SectionHandle, IN PEPROCESS Process, OUT void **EntryPointAddress, OUT void **BaseAddress)
MTSTATUS MmCreateSection(OUT PHANDLE SectionHandle, IN struct _FILE_OBJECT *FileObject)
struct _DOUBLY_LINKED_LIST * Flink
PHANDLE_TABLE ObjectTable
enum _PROCESS_FLAGS Flags
struct _IPROCESS InternalProcess
DOUBLY_LINKED_LIST AllThreads
uintptr_t PageDirectoryPhysical
MT_MODULE_INFO PrimaryExecutable
uint64_t PreferredImageBase
NORETURN void PspExitThread(IN MTSTATUS ExitStatus)
MTSTATUS PsTerminateThread(IN PETHREAD Thread, IN MTSTATUS ExitStatus)
MTSTATUS PsCreateThread(HANDLE ProcessHandle, PHANDLE ThreadHandle, ThreadEntry EntryPoint, THREAD_PARAMETER ThreadParameter, TimeSliceTicks TimeSlice, ThreadEntry MtdllEntrypoint)
PETHREAD PsGetCurrentThread(void)
MTSTATUS FsReadFile(IN PFILE_OBJECT FileObject, IN uint64_t FileOffset, OUT void *Buffer, IN size_t BufferSize, _Out_Opt size_t *BytesRead)
MTSTATUS FsCreateFile(IN const char *path, IN ACCESS_MASK DesiredAccess, OUT PHANDLE FileHandleOut)