revolutionary crash dump, msvcrt.dll redirect, text editor, some win32 functions

This commit is contained in:
maksw committed 2026-05-24 09:49:01 +02:00
1 parent 923e8792b4
commit 603fbdfab1
9 files changed
+1432 -160

No files matched your search

+86 -14
View File
@@ -8,11 +8,16 @@
#include <mm_virt.h>
#include <ke_debug.h>
int _stricmp(const char* a, const char* b);
// ---------------------------------------------------------------------------
// PE32+ structures (just what we need)
// ---------------------------------------------------------------------------
#define PE_SIGNATURE 0x00004550UL // 'PE\0\0'
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
#pragma pack(push, 1)
typedef struct {
@@ -117,6 +122,25 @@ typedef struct {
static MODULE_ENTRY gModules[MAX_MODULES];
static uint32_t gModuleCount = 0;
static const char* KiCanonicalModuleName(const char* name) {
if (!name) return name;
if (!_stricmp(name, "kernel32.dll") ||
!_stricmp(name, "user32.dll") ||
!_stricmp(name, "gdi32.dll") ||
!_stricmp(name, "ole32.dll") ||
!_stricmp(name, "winmm.dll")) {
return "win32.dll";
}
if (!_stricmp(name, "msvcrt.dll")) {
return "posix.dll";
}
return name;
}
static uintptr_t KiFindModuleBaseInTable(const MODULE_ENTRY* modules, uint32_t count, const char* name) {
for (uint32_t i = 0; i < count; i++) {
if (_stricmp(modules[i].Name, name) == 0) return modules[i].Base;
@@ -152,7 +176,7 @@ void LdrRegisterModule(const char* name, uintptr_t base) {
}
static uintptr_t KiFindGlobalModuleBase(const char* name) {
return KiFindModuleBaseInTable(gModules, gModuleCount, name);
return KiFindModuleBaseInTable(gModules, gModuleCount, KiCanonicalModuleName(name));
}
static uintptr_t KiFindProcessModuleBaseInTable(
@@ -161,7 +185,7 @@ static uintptr_t KiFindProcessModuleBaseInTable(
const char* name
) {
for (uint32_t i = 0; i < count; i++) {
if (_stricmp(modules[i].Name, name) == 0) {
if (_stricmp(modules[i].Name, KiCanonicalModuleName(name)) == 0) {
return modules[i].Base;
}
}
@@ -208,12 +232,12 @@ static void* KiGetExportAtBase(uintptr_t base, const char* functionName) {
// Export lookup
// ---------------------------------------------------------------------------
void* LdrGetExport(const char* moduleName, const char* functionName) {
uintptr_t base = KiFindGlobalModuleBase(moduleName);
uintptr_t base = KiFindGlobalModuleBase(KiCanonicalModuleName(moduleName));
return KiGetExportAtBase(base, functionName);
}
void* LdrGetExportForProcess(PROCESS* process, const char* moduleName, const char* functionName) {
uintptr_t base = KiFindProcessOrGlobalModuleBase(process, moduleName);
uintptr_t base = KiFindProcessOrGlobalModuleBase(process, KiCanonicalModuleName(moduleName));
return KiGetExportAtBase(base, functionName);
}
@@ -304,13 +328,8 @@ static KSTATUS LdrResolveImportsCommon(
while (imp->Name) {
const char* dllName = (const char *)(imageBase + imp->Name);
// Win32 compatibility remap
if (!_stricmp(dllName, "kernel32.dll") ||
!_stricmp(dllName, "user32.dll") ||
!_stricmp(dllName, "ole32.dll") ||
!_stricmp(dllName, "winmm.dll")) {
dllName = "win32.dll";
}
//Compatibility remap.
dllName = KiCanonicalModuleName(dllName);
//
// Ensure dependency is loaded into the process
@@ -397,6 +416,28 @@ KSTATUS LdrResolveImportsForProcess(PROCESS* process, uintptr_t imageBase) {
);
}
static void KiDebugLibtccAllocatorSlot(const char* phase, const char* filename, uintptr_t imageBase) {
if (!filename || !imageBase) return;
if (_stricmp(filename, "libtcc.dll") != 0) return;
uint64_t slot = *(uint64_t*)(imageBase + 0x4A010);
uint64_t expectedDefault = (uint64_t)(imageBase + 0x25F0);
DbgPrint("LDR libtcc %s: base=%p slot[+4A010]=%p expected-default=%p\n",
phase,
(void*)imageBase,
(void*)(uintptr_t)slot,
(void*)(uintptr_t)expectedDefault);
DbgPrint("LDR libtcc data[+4A000..+4A028]: %016llx %016llx %016llx %016llx %016llx %016llx\n",
(unsigned long long)*(uint64_t*)(imageBase + 0x4A000),
(unsigned long long)*(uint64_t*)(imageBase + 0x4A008),
(unsigned long long)*(uint64_t*)(imageBase + 0x4A010),
(unsigned long long)*(uint64_t*)(imageBase + 0x4A018),
(unsigned long long)*(uint64_t*)(imageBase + 0x4A020),
(unsigned long long)*(uint64_t*)(imageBase + 0x4A028));
}
static KSTATUS LdrRegisterProcessModule(PROCESS* process, const char* name, uintptr_t base) {
if (!process || !name || !base) return STATUS_INVALID_PARAMETER;
@@ -419,6 +460,8 @@ static KSTATUS LdrRegisterProcessModule(PROCESS* process, const char* name, uint
KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uintptr_t* baseOut) {
if (!process || !filename) return STATUS_INVALID_PARAMETER;
filename = KiCanonicalModuleName(filename);
for (uint32_t i = 0; i < process->ModuleCount; i++) {
if (_stricmp(process->Modules[i].Name, filename) == 0) {
if (baseOut) *baseOut = process->Modules[i].Base;
@@ -462,12 +505,16 @@ KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uintptr_
return s;
}
KiDebugLibtccAllocatorSlot("after load/reloc before imports", filename, imageBase);
s = LdrResolveImportsForProcess(process, imageBase);
if (!KSUCCESS(s)) {
MmFreeUserMemory((void*)imageBase);
return s;
}
KiDebugLibtccAllocatorSlot("after imports", filename, imageBase);
s = LdrRegisterProcessModule(process, filename, imageBase);
if (!KSUCCESS(s)) {
MmFreeUserMemory((void*)imageBase);
@@ -481,11 +528,36 @@ KSTATUS LdrLoadModuleForProcess(PROCESS* process, const char* filename, uintptr_
// LdrLoadImage - load a PE from a raw buffer into virtual space.
KSTATUS LdrLoadImage(const void* buffer, size_t size, uintptr_t* baseOut, bool user) {
if (!buffer || !size || !baseOut) return STATUS_INVALID_PARAMETER;
if (size < 0x40) return STATUS_FAILURE;
uint32_t peOffset = *(uint32_t *)((uint8_t *)buffer + 0x3C);
PE_HEADER* pe = (PE_HEADER *)((uint8_t *)buffer + peOffset);
if (pe->Signature != PE_SIGNATURE) return STATUS_FAILURE;
const uint8_t* bytes = (const uint8_t*)buffer;
uint32_t peOffset = *(const uint32_t *)(bytes + 0x3C);
if ((size_t)peOffset > size || size - (size_t)peOffset < 24) return STATUS_FAILURE;
uint32_t signature = *(const uint32_t *)(bytes + peOffset);
if (signature != PE_SIGNATURE) return STATUS_FAILURE;
uint16_t machine = *(const uint16_t *)(bytes + peOffset + 4);
uint16_t optionalSize = *(const uint16_t *)(bytes + peOffset + 20);
if (optionalSize < sizeof(OPT_HEADER64) ||
(size_t)peOffset + 24 + optionalSize > size) {
return STATUS_FAILURE;
}
uint16_t optionalMagic = *(const uint16_t *)(bytes + peOffset + 24);
if (machine == IMAGE_FILE_MACHINE_I386 || optionalMagic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
DbgPrint("LdrLoadImage: hard error: 32-bit PE images are not supported (machine=0x%X magic=0x%X)\n",
machine, optionalMagic);
return STATUS_NOT_SUPPORTED;
}
if (machine != IMAGE_FILE_MACHINE_AMD64 || optionalMagic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
DbgPrint("LdrLoadImage: unsupported PE image (machine=0x%X magic=0x%X)\n",
machine, optionalMagic);
return STATUS_NOT_SUPPORTED;
}
PE_HEADER* pe = (PE_HEADER *)(bytes + peOffset);
OPT_HEADER64* opt = &pe->OptionalHeader;
size_t imageSize = opt->SizeOfImage;