refactor syscall ABI and FAT32 driver to use request structs and string views natively, enforce handle access rights on object lookup, add scheduler statistics tracking, fix KiSchedule to prevent 50% idle throttling on CPU-bound threads, better document x64 initial user stack alignment, fix process teardown to properly signal exit events and manage thread counts, optimize doom file I/O with a custom handle struct to internally track position and size, add SubsystemData to TEB for generic thread-local state, apply PAGE_NX to non-executable PE sections in the loader, update native apps, tests, and shells to match new APIs, update kernel32 directory retrieval.
This commit is contained in:
1 parent
603fbdfab1
commit
e1248f4afe
43 files changed
+2892
-1857
No files matched your search
+52
-6
@@ -107,6 +107,10 @@ typedef struct {
|
||||
#pragma pack(pop)
|
||||
|
||||
#define IMAGE_REL_BASED_DIR64 10
|
||||
#define IMAGE_SCN_CNT_CODE 0x00000020u
|
||||
#define IMAGE_SCN_MEM_EXECUTE 0x20000000u
|
||||
#define IMAGE_SCN_MEM_READ 0x40000000u
|
||||
#define IMAGE_SCN_MEM_WRITE 0x80000000u
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Module registry
|
||||
@@ -248,6 +252,40 @@ size_t LdrGetImageSize(uintptr_t base) {
|
||||
return (size_t)pe->OptionalHeader.SizeOfImage;
|
||||
}
|
||||
|
||||
|
||||
static void KiFreeLoadedImage(uintptr_t imageBase, bool user) {
|
||||
if (!imageBase) return;
|
||||
size_t imageSize = LdrGetImageSize(imageBase);
|
||||
if (user) MmFreeUserImage((void*)imageBase, imageSize);
|
||||
else MmFreePool((void*)imageBase);
|
||||
}
|
||||
|
||||
|
||||
KSTATUS LdrProtectImage(uintptr_t imageBase, bool user) {
|
||||
if (!imageBase) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
uint32_t peOffset = *(uint32_t *)(imageBase + 0x3C);
|
||||
PE_HEADER* pe = (PE_HEADER *)(imageBase + peOffset);
|
||||
if (pe->Signature != PE_SIGNATURE) return STATUS_FAILURE;
|
||||
|
||||
SECTION_HEADER* sec = (SECTION_HEADER *)((uint8_t *)&pe->OptionalHeader + pe->SizeOfOptionalHeader);
|
||||
for (int i = 0; i < pe->NumberOfSections; i++) {
|
||||
size_t protectSize = sec[i].VirtualSize ? sec[i].VirtualSize : sec[i].SizeOfRawData;
|
||||
if (!protectSize) continue;
|
||||
|
||||
uint64_t prot = PAGE_PRESENT | (user ? PAGE_USER : 0);
|
||||
if (sec[i].Characteristics & IMAGE_SCN_MEM_WRITE)
|
||||
prot |= PAGE_WRITE;
|
||||
if (!((sec[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) ||
|
||||
(sec[i].Characteristics & IMAGE_SCN_CNT_CODE)))
|
||||
prot |= PAGE_NX;
|
||||
|
||||
KSTATUS s = MmSetPageProtect(imageBase + sec[i].VirtualAddress, protectSize, prot);
|
||||
if (!KSUCCESS(s)) return s;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Entry point lookup
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -470,13 +508,13 @@ KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uintptr_
|
||||
}
|
||||
|
||||
FILE_OBJECT* f;
|
||||
KSTATUS s = IoOpenFile(filename, &f);
|
||||
KSTATUS s = IoOpenFile(SysSvFromCstr(filename), &f);
|
||||
if (!KSUCCESS(s)) {
|
||||
char path[260];
|
||||
memcpy(path, "0:/system/", 10);
|
||||
memcpy(path + 10, filename, strnlen(filename, 248) + 1);
|
||||
path[259] = '\0';
|
||||
s = IoOpenFile(path, &f);
|
||||
s = IoOpenFile(SysSvFromCstr(path), &f);
|
||||
if (!KSUCCESS(s)) {
|
||||
DbgPrint("LdrLoadModuleForProcess: Failed to open %s (%d)\n", filename, s);
|
||||
return s;
|
||||
@@ -509,7 +547,13 @@ KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uintptr_
|
||||
|
||||
s = LdrResolveImportsForProcess(process, imageBase);
|
||||
if (!KSUCCESS(s)) {
|
||||
MmFreeUserMemory((void*)imageBase);
|
||||
KiFreeLoadedImage(imageBase, true);
|
||||
return s;
|
||||
}
|
||||
|
||||
s = LdrProtectImage(imageBase, true);
|
||||
if (!KSUCCESS(s)) {
|
||||
KiFreeLoadedImage(imageBase, true);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -517,7 +561,7 @@ KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uintptr_
|
||||
|
||||
s = LdrRegisterProcessModule(process, filename, imageBase);
|
||||
if (!KSUCCESS(s)) {
|
||||
MmFreeUserMemory((void*)imageBase);
|
||||
KiFreeLoadedImage(imageBase, true);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -561,7 +605,7 @@ KSTATUS LdrLoadImage(const void* buffer, size_t size, uintptr_t* baseOut, bool u
|
||||
OPT_HEADER64* opt = &pe->OptionalHeader;
|
||||
size_t imageSize = opt->SizeOfImage;
|
||||
|
||||
void* mem = user ? MmAllocateUserMemory(imageSize) : MmAllocatePool(imageSize);
|
||||
void* mem = user ? MmAllocateUserImage(imageSize) : MmAllocatePool(imageSize);
|
||||
if (!mem) return STATUS_NO_MEMORY;
|
||||
memset(mem, 0, imageSize);
|
||||
|
||||
@@ -575,7 +619,9 @@ KSTATUS LdrLoadImage(const void* buffer, size_t size, uintptr_t* baseOut, bool u
|
||||
}
|
||||
|
||||
uint64_t prot = PAGE_PRESENT | PAGE_WRITE | (user ? PAGE_USER : 0);
|
||||
MmSetPageProtect((uintptr_t)mem + sec[i].VirtualAddress, sec[i].VirtualSize, prot);
|
||||
MmSetPageProtect((uintptr_t)mem + sec[i].VirtualAddress,
|
||||
sec[i].VirtualSize ? sec[i].VirtualSize : sec[i].SizeOfRawData,
|
||||
prot);
|
||||
}
|
||||
|
||||
uintptr_t delta = (uintptr_t)mem - opt->ImageBase;
|
||||
|
||||
Reference in new issue
Block a user