Reimplemented pe loader

This commit is contained in:
Boring
2021-10-25 17:15:15 +08:00
parent 78b3d1d707
commit 1966d4bd41
7 changed files with 338 additions and 850 deletions
File diff suppressed because it is too large Load Diff
+28 -100
View File
@@ -1,29 +1,11 @@
#pragma once
#pragma warning(disable:4996)
#ifndef __MEMORY_MODULE_HEADER
#define __MEMORY_MODULE_HEADER
#pragma warning(disable:4996)
struct ExportNameEntry {
LPCSTR name;
WORD idx;
};
typedef struct {
LPVOID address;
LPVOID alignedAddress;
SIZE_T size;
DWORD characteristics;
BOOL last;
} SECTIONFINALIZEDATA, * PSECTIONFINALIZEDATA;
typedef BOOL(WINAPI* DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
#ifdef _WIN64
typedef struct POINTER_LIST {
struct POINTER_LIST* next;
void* address;
} POINTER_LIST;
#endif
typedef HMODULE HMEMORYMODULE;
typedef void* HMEMORYRSRC;
typedef struct _MEMORYMODULE {
/*
---------------------------
@@ -40,51 +22,39 @@ typedef struct _MEMORYMODULE {
codes
*/
ULONG64 Signature;
__declspec(align(sizeof(size_t))) struct {
DWORD SizeofHeaders;
union {
struct {
//Status Flags
BYTE initialized : 1;
BYTE loadFromNtLoadDllMemory : 1;
BYTE underUnload : 1;
BYTE reservedStatusFlags : 5;
BYTE cbFlagsReserved;
DWORD SizeofHeaders;
union {
struct {
//Status Flags
BYTE initialized : 1;
BYTE loadFromNtLoadDllMemory : 1;
BYTE underUnload : 1;
BYTE reservedStatusFlags : 5;
//Load Flags
WORD MappedDll : 1;
WORD InsertInvertedFunctionTableEntry : 1;
WORD TlsHandled : 1;
WORD UseReferenceCount : 1;
WORD reservedLoadFlags : 12;
BYTE cbFlagsReserved;
//Load Flags
WORD MappedDll : 1;
WORD InsertInvertedFunctionTableEntry : 1;
WORD TlsHandled : 1;
WORD UseReferenceCount : 1;
WORD reservedLoadFlags : 12;
};
DWORD dwFlags;
};
DWORD dwFlags;
};
LPBYTE codeBase; //codeBase == ImageBase
__declspec(align(sizeof(size_t))) struct {
PVOID lpReserved;
};
PVOID lpReserved;
HMODULE* hModulesList; //Import module handles
__declspec(align(sizeof(size_t))) struct {
DWORD dwModulesCount; //number of module handles
DWORD dwReserved;
};
DWORD dwModulesCount; //number of module handles
DWORD dwReserved;
ExportNameEntry* nameExportsTable;
__declspec(align(sizeof(size_t))) struct {
DWORD pageSize; //SYSTEM_INFO::dwPageSize
DWORD headers_align; //headers_align == OptionalHeaders.BaseOfCode;
};
DWORD pageSize; //SYSTEM_INFO::dwPageSize
DWORD headers_align; //headers_align == OptionalHeaders.BaseOfCode;
#ifdef _WIN64
POINTER_LIST* blockedMemory;
PVOID lpReserved2;
#endif
} MEMORYMODULE, * PMEMORYMODULE;
@@ -94,55 +64,13 @@ typedef struct _MEMORYMODULE {
extern "C" {
#endif
/**
* Load DLL from memory location with the given size.
*
* All dependencies are resolved using default LoadLibrary/GetProcAddress
* calls through the Windows API.
*/
HMEMORYMODULE MemoryLoadLibrary(const void*);
NTSTATUS MemoryLoadLibrary(
_Out_ HMEMORYMODULE* MemoryModuleHandle,
_In_ LPCVOID data
);
/**
* Get address of exported method. Supports loading both by name and by
* ordinal value.
*/
FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR);
/**
* Free previously loaded DLL.
*/
bool MemoryFreeLibrary(HMEMORYMODULE);
/**
* Find the location of a resource with the specified type and name.
*/
HMEMORYRSRC MemoryFindResource(HMEMORYMODULE, LPCTSTR, LPCTSTR);
/**
* Find the location of a resource with the specified type, name and language.
*/
HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE, LPCTSTR, LPCTSTR, WORD);
/**
* Get the size of the resource in bytes.
*/
DWORD MemorySizeofResource(HMEMORYMODULE, HMEMORYRSRC);
/**
* Get a pointer to the contents of the resource.
*/
LPVOID MemoryLoadResource(HMEMORYMODULE, HMEMORYRSRC);
/**
* Load a string resource.
*/
int MemoryLoadString(HMEMORYMODULE, UINT, LPTSTR, int);
/**
* Load a string resource with a given language.
*/
int MemoryLoadStringEx(HMEMORYMODULE, UINT, LPTSTR, int, WORD);
bool WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule);
PMEMORYMODULE WINAPI MapMemoryModuleHandle(HMEMORYMODULE hModule);
+1 -4
View File
@@ -732,8 +732,6 @@ NTSTATUS NTAPI MmpAllocateTlsEntry(
NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) {
NTSTATUS status = STATUS_NOT_FOUND;
RtlAcquireSRWLockExclusive(&MmpTlsListLock);
for (auto entry = MmpTlsList.Flink; entry != &MmpTlsList; entry = entry->Flink) {
@@ -743,14 +741,13 @@ NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) {
RtlClearBit(&MmpTlsBitmap, p->TlsDirectory.Characteristics);
RtlFreeHeap(RtlProcessHeap(), 0, p);
status = STATUS_SUCCESS;
break;
}
}
RtlReleaseSRWLockExclusive(&MmpTlsListLock);
return status;
return STATUS_SUCCESS;
}
NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) {
+11 -15
View File
@@ -12,6 +12,8 @@
_EX_ListHead->Blink = (Entry);\
}
typedef BOOL(WINAPI* PDLL_STARTUP_ROUTINE)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
static PRTL_RB_TREE NTAPI RtlFindLdrpModuleBaseAddressIndex() {
static PRTL_RB_TREE LdrpModuleBaseAddressIndex = nullptr;
if (LdrpModuleBaseAddressIndex)return LdrpModuleBaseAddressIndex;
@@ -546,7 +548,7 @@ BOOL NTAPI LdrpCallInitializers(PMEMORYMODULE module, DWORD dwReason) {
if (headers->OptionalHeader.AddressOfEntryPoint) {
__try {
// notify library about attaching to process
if (((DllEntryProc)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))((HINSTANCE)module->codeBase, dwReason, 0)) {
if (((PDLL_STARTUP_ROUTINE)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))((HINSTANCE)module->codeBase, dwReason, 0)) {
module->initialized = TRUE;
return TRUE;
}
@@ -626,18 +628,9 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW(
}
}
if (!(*BaseAddress = MemoryLoadLibrary(BufferAddress))) {
switch (GetLastError()) {
case ERROR_BAD_EXE_FORMAT:
return STATUS_INVALID_IMAGE_FORMAT;
case ERROR_OUTOFMEMORY:
return STATUS_NO_MEMORY;
case ERROR_DLL_INIT_FAILED:
return STATUS_DLL_INIT_FAILED;
default:
return STATUS_UNSUCCESSFUL;
}
}
status = MemoryLoadLibrary(BaseAddress, BufferAddress);
if (!NT_SUCCESS(status))return status;
if (!(module = MapMemoryModuleHandle(*BaseAddress))) {
__fastfail(FAST_FAIL_FATAL_APP_EXIT);
DebugBreak();
@@ -766,8 +759,11 @@ NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress) {
if (!(count & ~1)) {
module->underUnload = true;
if (module->initialized) {
DllEntryProc DllEntry = (DllEntryProc)(LPVOID)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint);
(*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0);
PDLL_STARTUP_ROUTINE((LPVOID)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))(
(HINSTANCE)module->codeBase,
DLL_PROCESS_DETACH,
0
);
}
if (module->MappedDll) {
if (module->InsertInvertedFunctionTableEntry) {