revolutionary crash dump, msvcrt.dll redirect, text editor, some win32 functions
This commit is contained in:
1 parent
923e8792b4
commit
603fbdfab1
9 files changed
+1432
-160
No files matched your search
+86
-14
@@ -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;
|
||||
|
||||
|
||||
Reference in new issue
Block a user