mirror of
https://github.com/bb107/MemoryModulePP
synced 2026-06-08 13:15:33 +00:00
Reimplemented pe loader
This commit is contained in:
+282
-724
File diff suppressed because it is too large
Load Diff
+28
-100
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -171,7 +171,6 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\MemoryModule\Native.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -18,9 +18,6 @@
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\MemoryModule\Native.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h">
|
||||
|
||||
+16
-3
@@ -2,13 +2,26 @@
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#include <Windows.h>
|
||||
#include "../MemoryModule/Native.h"
|
||||
|
||||
#pragma comment(lib,"ws2_32.lib")
|
||||
#pragma comment(lib,"wintrust.lib")
|
||||
#pragma comment(lib,"ntdll.lib")
|
||||
|
||||
typedef NTSTATUS(NTAPI* PUSER_THREAD_START_ROUTINE)(_In_ PVOID ThreadParameter);
|
||||
|
||||
#define NtCurrentProcess() (HANDLE)-1
|
||||
|
||||
#ifdef _WIN64
|
||||
#define NtCurrentThreadLocalStoragePointer() *(LPVOID*)(LPBYTE(NtCurrentTeb()) + 0x58)
|
||||
#else
|
||||
#define NtCurrentThreadLocalStoragePointer() *(LPVOID*)(LPBYTE(NtCurrentTeb()) + 0x2C)
|
||||
#endif
|
||||
|
||||
typedef struct _CLIENT_ID {
|
||||
VOID* UniqueProcess;
|
||||
VOID* UniqueThread;
|
||||
}CLIENT_ID, * PCLIENT_ID;
|
||||
|
||||
extern "C"
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
@@ -103,13 +116,13 @@ int __test__() {
|
||||
|
||||
static thread_local int x = 0xffccffdd;
|
||||
NTSTATUS WINAPI Thread(PVOID) {
|
||||
printf("[1] ThreadLocalStoragePointer = %p\n", NtCurrentTeb()->ThreadLocalStoragePointer);
|
||||
printf("[1] ThreadLocalStoragePointer = %p\n", NtCurrentThreadLocalStoragePointer());
|
||||
return x == 0xffccffdd ? 0 : 1;
|
||||
}
|
||||
|
||||
int thread() {
|
||||
x = 2;
|
||||
printf("[0] ThreadLocalStoragePointer = %p\n", NtCurrentTeb()->ThreadLocalStoragePointer);
|
||||
printf("[0] ThreadLocalStoragePointer = %p\n", NtCurrentThreadLocalStoragePointer());
|
||||
HANDLE hThread;// = CreateThread(nullptr, 0, Thread, nullptr, 0, nullptr);
|
||||
RtlCreateUserThread(NtCurrentProcess(), nullptr, FALSE, 0, 0, 0, Thread, nullptr, &hThread, nullptr);
|
||||
DWORD ret = -1;
|
||||
|
||||
Reference in New Issue
Block a user