diff --git a/MemoryModule/MemoryModule.cpp b/MemoryModule/MemoryModule.cpp
index ca95ab3..f975b08 100644
--- a/MemoryModule/MemoryModule.cpp
+++ b/MemoryModule/MemoryModule.cpp
@@ -64,7 +64,8 @@ static SYSTEM_INFO sysInfo = []()->SYSTEM_INFO {
NTSTATUS MemoryLoadLibrary(
_Out_ HMEMORYMODULE* MemoryModuleHandle,
- _In_ LPCVOID data) {
+ _In_ LPCVOID data,
+ _In_ DWORD size) {
PIMAGE_DOS_HEADER dos_header = nullptr;
PIMAGE_NT_HEADERS old_header = nullptr;
@@ -122,7 +123,7 @@ NTSTATUS MemoryLoadLibrary(
__except (EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode();
}
- if (!NT_SUCCESS(status)) return status;
+ if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)return status;
//
// Reserve the address range of image
@@ -178,9 +179,10 @@ NTSTATUS MemoryLoadLibrary(
PMEMORYMODULE hMemoryModule = (PMEMORYMODULE)(base + old_header->OptionalHeader.SizeOfHeaders);
RtlZeroMemory(hMemoryModule, sizeof(MEMORYMODULE));
hMemoryModule->codeBase = base;
- hMemoryModule->pageSize = sysInfo.dwPageSize;
+ hMemoryModule->dwImageFileSize = size;
hMemoryModule->Signature = MEMORY_MODULE_SIGNATURE;
hMemoryModule->SizeofHeaders = old_header->OptionalHeader.SizeOfHeaders;
+ hMemoryModule->lpReserved = (LPVOID)data;
do {
//
diff --git a/MemoryModule/MemoryModule.h b/MemoryModule/MemoryModule.h
index 22716ff..c1d9b4b 100644
--- a/MemoryModule/MemoryModule.h
+++ b/MemoryModule/MemoryModule.h
@@ -52,7 +52,7 @@ typedef struct _MEMORYMODULE {
DWORD dwModulesCount; //number of module handles
DWORD dwReserved;
- DWORD pageSize; //SYSTEM_INFO::dwPageSize
+ DWORD dwImageFileSize;
DWORD headers_align; //headers_align == OptionalHeaders.BaseOfCode;
} MEMORYMODULE, * PMEMORYMODULE;
@@ -66,7 +66,8 @@ extern "C" {
NTSTATUS MemoryLoadLibrary(
_Out_ HMEMORYMODULE* MemoryModuleHandle,
- _In_ LPCVOID data
+ _In_ LPCVOID data,
+ _In_ DWORD size
);
bool MemoryFreeLibrary(HMEMORYMODULE);
diff --git a/MemoryModule/MemoryModule.vcxproj b/MemoryModule/MemoryModule.vcxproj
index 043c7a3..08eed4f 100644
--- a/MemoryModule/MemoryModule.vcxproj
+++ b/MemoryModule/MemoryModule.vcxproj
@@ -31,6 +31,7 @@
+
@@ -45,6 +46,7 @@
+
diff --git a/MemoryModule/MemoryModule.vcxproj.filters b/MemoryModule/MemoryModule.vcxproj.filters
index 6e4fbe6..e8bf299 100644
--- a/MemoryModule/MemoryModule.vcxproj.filters
+++ b/MemoryModule/MemoryModule.vcxproj.filters
@@ -87,6 +87,9 @@
Source Files\3rdparty\Detours
+
+ Source Files
+
@@ -125,6 +128,9 @@
Header Files\3rdparty\Detours
+
+ Header Files
+
diff --git a/MemoryModule/MmpDotNet.cpp b/MemoryModule/MmpDotNet.cpp
new file mode 100644
index 0000000..aef1f91
--- /dev/null
+++ b/MemoryModule/MmpDotNet.cpp
@@ -0,0 +1,357 @@
+#include "stdafx.h"
+#include <3rdparty/Detours/detours.h>
+
+typedef HRESULT (WINAPI* GetFileVersion_T)(
+ LPCWSTR szFilename,
+ LPWSTR szBuffer,
+ DWORD cchBuffer,
+ DWORD* dwLength
+);
+
+typedef struct _MMP_FAKE_HANDLE_LIST_ENTRY {
+ LIST_ENTRY InMmpFakeHandleList;
+ HANDLE hObject;
+ PVOID value;
+}MMP_FAKE_HANDLE_LIST_ENTRY, * PMMP_FAKE_HANDLE_LIST_ENTRY;
+
+static decltype(&CreateFileW) OriginCreateFileW = CreateFileW;
+static decltype(&GetFileInformationByHandle) OriginGetFileInformationByHandle = GetFileInformationByHandle;
+static decltype(&GetFileAttributesExW) OriginGetFileAttributesExW = GetFileAttributesExW;
+static decltype(&CreateFileMappingW) OriginCreateFileMappingW = CreateFileMappingW;
+static decltype(&MapViewOfFileEx) OriginMapViewOfFileEx = MapViewOfFileEx;
+static decltype(&UnmapViewOfFile)OriginUnmapViewOfFile = UnmapViewOfFile;
+static decltype(&CloseHandle)OriginCloseHandle = CloseHandle;
+static GetFileVersion_T OriginGetFileVersion = nullptr;
+
+FILETIME AssemblyTimes;
+
+CRITICAL_SECTION MmpFakeHandleListLock;
+LIST_ENTRY MmpFakeHandleListHead;
+
+static BOOL Initialized = FALSE;
+
+BOOL MmpIsMemoryModuleFileName(
+ _In_ LPCWSTR lpFileName,
+ _Out_opt_ PLDR_DATA_TABLE_ENTRY *LdrEntry) {
+
+ __try {
+ if (LdrEntry)*LdrEntry = nullptr;
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ return FALSE;
+ }
+
+ BOOL result = FALSE;
+
+ EnterCriticalSection(NtCurrentPeb()->LoaderLock);
+ for (auto entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
+ entry != &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
+ entry = entry->Flink) {
+
+ PLDR_DATA_TABLE_ENTRY CurEntry = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, LDR_DATA_TABLE_ENTRY::InLoadOrderLinks);
+ if (!wcsncmp(CurEntry->FullDllName.Buffer, lpFileName, CurEntry->FullDllName.Length) &&
+ wcslen(lpFileName) * 2 == CurEntry->FullDllName.Length) {
+ result = IsValidMemoryModuleHandle((HMODULE)CurEntry->DllBase);
+ if (result) {
+ if (LdrEntry) {
+ __try {
+ *LdrEntry = CurEntry;
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ ;
+ }
+ }
+ }
+
+ break;
+ }
+
+ }
+ LeaveCriticalSection(NtCurrentPeb()->LoaderLock);
+
+ return result;
+}
+
+VOID MmpInsertHandleEntry(
+ _In_ HANDLE hObject,
+ _In_ PVOID value) {
+ auto entry = (PMMP_FAKE_HANDLE_LIST_ENTRY)RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_FAKE_HANDLE_LIST_ENTRY));
+ entry->hObject = hObject;
+ entry->value = value;
+
+ EnterCriticalSection(&MmpFakeHandleListLock);
+ InsertTailList(&MmpFakeHandleListHead, &entry->InMmpFakeHandleList);
+ LeaveCriticalSection(&MmpFakeHandleListLock);
+}
+
+PMMP_FAKE_HANDLE_LIST_ENTRY MmpFindHandleEntry(HANDLE hObject) {
+
+ PMMP_FAKE_HANDLE_LIST_ENTRY result = nullptr;
+ EnterCriticalSection(&MmpFakeHandleListLock);
+
+ for (auto entry = MmpFakeHandleListHead.Flink; entry != &MmpFakeHandleListHead; entry = entry->Flink) {
+ auto CurEntry = CONTAINING_RECORD(entry, MMP_FAKE_HANDLE_LIST_ENTRY, MMP_FAKE_HANDLE_LIST_ENTRY::InMmpFakeHandleList);
+
+ if (CurEntry->hObject == hObject) {
+ result = CurEntry;
+ break;
+ }
+
+ }
+
+ LeaveCriticalSection(&MmpFakeHandleListLock);
+ return result;
+}
+
+VOID MmpFreeHandleEntry(PMMP_FAKE_HANDLE_LIST_ENTRY lpHandleEntry) {
+ EnterCriticalSection(&MmpFakeHandleListLock);
+ RemoveEntryList(&lpHandleEntry->InMmpFakeHandleList);
+ RtlFreeHeap(RtlProcessHeap(), 0, lpHandleEntry);
+ LeaveCriticalSection(&MmpFakeHandleListLock);
+}
+
+HANDLE WINAPI HookCreateFileW(
+ _In_ LPCWSTR lpFileName,
+ _In_ DWORD dwDesiredAccess,
+ _In_ DWORD dwShareMode,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ _In_ DWORD dwCreationDisposition,
+ _In_ DWORD dwFlagsAndAttributes,
+ _In_opt_ HANDLE hTemplateFile) {
+
+ PLDR_DATA_TABLE_ENTRY entry;
+ if (MmpIsMemoryModuleFileName(lpFileName, &entry)) {
+ HANDLE hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr);
+
+ MmpInsertHandleEntry(hEvent, entry);
+ return hEvent;
+ }
+
+ return OriginCreateFileW(
+ lpFileName,
+ dwDesiredAccess,
+ dwShareMode,
+ lpSecurityAttributes,
+ dwCreationDisposition,
+ dwFlagsAndAttributes,
+ hTemplateFile
+ );
+}
+
+BOOL WINAPI HookGetFileInformationByHandle(
+ _In_ HANDLE hFile,
+ _Out_ LPBY_HANDLE_FILE_INFORMATION lpFileInformation) {
+ auto iter = MmpFindHandleEntry(hFile);
+ if (iter) {
+ RtlZeroMemory(lpFileInformation, sizeof(BY_HANDLE_FILE_INFORMATION));
+
+ auto entry = (PLDR_DATA_TABLE_ENTRY)iter->value;
+ auto module = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase);
+
+ lpFileInformation->ftCreationTime = lpFileInformation->ftLastAccessTime = lpFileInformation->ftLastWriteTime = AssemblyTimes;
+ lpFileInformation->nFileSizeLow = module->dwImageFileSize;
+
+ return TRUE;
+ }
+ else {
+ return OriginGetFileInformationByHandle(
+ hFile,
+ lpFileInformation
+ );
+ }
+}
+
+BOOL WINAPI HookGetFileAttributesExW(
+ _In_ LPCWSTR lpFileName,
+ _In_ GET_FILEEX_INFO_LEVELS fInfoLevelId,
+ _Out_writes_bytes_(sizeof(WIN32_FILE_ATTRIBUTE_DATA)) LPVOID lpFileInformation) {
+
+ PLDR_DATA_TABLE_ENTRY entry;
+ if (MmpIsMemoryModuleFileName(lpFileName, &entry)) {
+ __try {
+ RtlZeroMemory(
+ lpFileInformation,
+ sizeof(WIN32_FILE_ATTRIBUTE_DATA)
+ );
+
+ LPWIN32_FILE_ATTRIBUTE_DATA data = (LPWIN32_FILE_ATTRIBUTE_DATA)lpFileInformation;
+ auto module = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase);
+
+ data->ftCreationTime = data->ftLastAccessTime = data->ftLastWriteTime = AssemblyTimes;
+ data->nFileSizeLow = module->dwImageFileSize;
+ return TRUE;
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ return FALSE;
+ }
+ }
+
+ return OriginGetFileAttributesExW(
+ lpFileName,
+ fInfoLevelId,
+ lpFileInformation
+ );
+}
+
+HANDLE WINAPI HookCreateFileMappingW(
+ _In_ HANDLE hFile,
+ _In_opt_ LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
+ _In_ DWORD flProtect,
+ _In_ DWORD dwMaximumSizeHigh,
+ _In_ DWORD dwMaximumSizeLow,
+ _In_opt_ LPCWSTR lpName) {
+
+ auto iter = MmpFindHandleEntry(hFile);
+ if (iter) {
+ HANDLE hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr);
+
+ MmpInsertHandleEntry(hEvent, iter->value);
+ return hEvent;
+ }
+
+ return OriginCreateFileMappingW(
+ hFile,
+ lpFileMappingAttributes,
+ flProtect,
+ dwMaximumSizeHigh,
+ dwMaximumSizeLow,
+ lpName
+ );
+}
+
+LPVOID WINAPI HookMapViewOfFileEx(
+ _In_ HANDLE hFileMappingObject,
+ _In_ DWORD dwDesiredAccess,
+ _In_ DWORD dwFileOffsetHigh,
+ _In_ DWORD dwFileOffsetLow,
+ _In_ SIZE_T dwNumberOfBytesToMap,
+ _In_opt_ LPVOID lpBaseAddress) {
+
+ auto iter = MmpFindHandleEntry(hFileMappingObject);
+ if (iter) {
+ HMEMORYMODULE hModule = nullptr;
+ auto entry = (PLDR_DATA_TABLE_ENTRY)iter->value;
+ auto pModule = MapMemoryModuleHandle((HMEMORYMODULE)entry->DllBase);
+ if (pModule) {
+ MemoryLoadLibrary(&hModule, pModule->lpReserved, pModule->dwImageFileSize);
+
+ if (hModule) MmpInsertHandleEntry(hModule, hModule);
+ }
+
+ return hModule;
+ }
+
+ return OriginMapViewOfFileEx(
+ hFileMappingObject,
+ dwDesiredAccess,
+ dwFileOffsetHigh,
+ dwFileOffsetLow,
+ dwNumberOfBytesToMap,
+ lpBaseAddress
+ );
+}
+
+BOOL WINAPI HookUnmapViewOfFile(_In_ LPCVOID lpBaseAddress) {
+ auto iter = MmpFindHandleEntry((HANDLE)lpBaseAddress);
+ if (iter) {
+ MemoryFreeLibrary((HMEMORYMODULE)lpBaseAddress);
+ MmpFreeHandleEntry(iter);
+ return TRUE;
+ }
+
+ return OriginUnmapViewOfFile(lpBaseAddress);
+}
+
+BOOL WINAPI HookCloseHandle(_In_ _Post_ptr_invalid_ HANDLE hObject) {
+ auto iter = MmpFindHandleEntry(hObject);
+ if (iter)MmpFreeHandleEntry(iter);
+
+ return OriginCloseHandle(hObject);
+}
+
+HRESULT WINAPI HookGetFileVersion(
+ LPCWSTR szFilename,
+ LPWSTR szBuffer,
+ DWORD cchBuffer,
+ DWORD* dwLength) {
+
+ typedef struct _COR20_METADATA {
+ DWORD Signature;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD Reserved;
+ DWORD VersionLength;
+ CHAR VersionString[ANYSIZE_ARRAY];
+ }COR20_METADATA, * PCOR20_METADATA;
+
+ PLDR_DATA_TABLE_ENTRY entry = nullptr;
+
+ if (MmpIsMemoryModuleFileName(szFilename, &entry)) {
+
+ __try {
+ PIMAGE_NT_HEADERS headers = RtlImageNtHeader(entry->DllBase);
+ auto dir = headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
+ if (!dir.Size || !dir.VirtualAddress)__leave;
+
+ PIMAGE_COR20_HEADER cor2 = PIMAGE_COR20_HEADER(LPBYTE(entry->DllBase) + dir.VirtualAddress);
+ if (!cor2->MetaData.Size || !cor2->MetaData.VirtualAddress) __leave;
+
+ PCOR20_METADATA meta = PCOR20_METADATA(LPBYTE(entry->DllBase) + cor2->MetaData.VirtualAddress);
+ if (dwLength)*dwLength = meta->VersionLength;
+ if (cchBuffer < meta->VersionLength)return 0x8007007A;
+
+ MultiByteToWideChar(CP_ACP, 0, meta->VersionString, meta->VersionLength, szBuffer, cchBuffer);
+ return 0;
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {
+ ;
+ }
+
+ }
+
+ return OriginGetFileVersion(
+ szFilename,
+ szBuffer,
+ cchBuffer,
+ dwLength
+ );
+}
+
+BOOL WINAPI MmpInitializeHooksForDotNet() {
+ HMODULE hModule = GetModuleHandleW(L"mscoreei.dll");
+ if (!hModule) {
+ RtlRaiseStatus(STATUS_NOT_SUPPORTED);
+ return FALSE;
+ }
+
+ OriginGetFileVersion = (GetFileVersion_T)GetProcAddress(hModule, "GetFileVersion");
+ if (!OriginGetFileVersion) {
+ RtlRaiseStatus(STATUS_NOT_SUPPORTED);
+ return FALSE;
+ }
+
+ GetSystemTimeAsFileTime(&AssemblyTimes);
+
+ EnterCriticalSection(NtCurrentPeb()->FastPebLock);
+ if (!Initialized) {
+
+ InitializeCriticalSection(&MmpFakeHandleListLock);
+ InitializeListHead(&MmpFakeHandleListHead);
+
+ DetourTransactionBegin();
+ DetourUpdateThread(NtCurrentThread());
+ DetourAttach((PVOID*)&OriginCreateFileW, HookCreateFileW);
+ DetourAttach((PVOID*)&OriginGetFileInformationByHandle, HookGetFileInformationByHandle);
+ DetourAttach((PVOID*)&OriginGetFileAttributesExW, HookGetFileAttributesExW);
+ DetourAttach((PVOID*)&OriginCreateFileMappingW, HookCreateFileMappingW);
+ DetourAttach((PVOID*)&OriginMapViewOfFileEx, HookMapViewOfFileEx);
+ DetourAttach((PVOID*)&OriginUnmapViewOfFile, HookUnmapViewOfFile);
+ DetourAttach((PVOID*)&OriginCloseHandle, HookCloseHandle);
+ DetourAttach((PVOID*)&OriginGetFileVersion, HookGetFileVersion);
+ DetourTransactionCommit();
+ Initialized = TRUE;
+ }
+ LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
+
+ return TRUE;
+}
diff --git a/MemoryModule/MmpDotNet.h b/MemoryModule/MmpDotNet.h
new file mode 100644
index 0000000..d3f463f
--- /dev/null
+++ b/MemoryModule/MmpDotNet.h
@@ -0,0 +1,2 @@
+#pragma once
+BOOL WINAPI MmpInitializeHooksForDotNet();
\ No newline at end of file
diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp
index 5bbb7ab..ea69900 100644
--- a/MemoryModule/MmpTls.cpp
+++ b/MemoryModule/MmpTls.cpp
@@ -9,9 +9,15 @@
// [MMP_START_TLS_INDEX, MMP_MAXIMUM_TLS_INDEX) Reserved for MemoryModule
//
-#define MMP_START_TLS_INDEX 0x80 //128
+#define MMP_START_TLS_INDEX 0x80 //128
-#define MMP_MAXIMUM_TLS_INDEX 0x100 //256
+#define MMP_MAXIMUM_TLS_INDEX 0x100 //256
+
+#define MMP_TLSP_INDEX_BUFFER_SIZE (MMP_MAXIMUM_TLS_INDEX / 8) //32
+
+#if (((MMP_START_TLS_INDEX | MMP_MAXIMUM_TLS_INDEX) & 7) || (MMP_START_TLS_INDEX >= MMP_MAXIMUM_TLS_INDEX))
+#error "MMP_START_TLS_INDEX must be smaller than MMP_MAXIMUM_TLS_INDEX, and both are 8-bit aligned."
+#endif
#define MmpAllocateTlsp() (RtlAllocateHeap(\
RtlProcessHeap(),\
@@ -137,26 +143,18 @@ PVOID NTAPI MmpQuerySystemInformation(
return buffer;
}
-PSYSTEM_PROCESS_INFORMATION NTAPI MmpGetProcessInformation() {
+DWORD NTAPI MmpGetThreadCount() {
+ DWORD result = 0;
auto pid = NtCurrentProcessId();
auto spi = PSYSTEM_PROCESS_INFORMATION(MmpQuerySystemInformation(SystemProcessInformation, nullptr));
- PSYSTEM_PROCESS_INFORMATION result = nullptr;
if (spi) {
auto p = spi;
while (true) {
if (p->UniqueProcessId == pid) {
- result = PSYSTEM_PROCESS_INFORMATION(RtlAllocateHeap(RtlProcessHeap(), 0, p->NextEntryOffset));
- if (!result)break;
-
- RtlCopyMemory(
- result,
- p,
- p->NextEntryOffset
- );
-
+ result = p->NumberOfThreads;
break;
}
@@ -170,18 +168,6 @@ PSYSTEM_PROCESS_INFORMATION NTAPI MmpGetProcessInformation() {
return result;
}
-DWORD NTAPI MmpGetThreadCount() {
- DWORD result = 0;
- auto p = MmpGetProcessInformation();
-
- if (p) {
- result = p->NumberOfThreads;
- RtlFreeHeap(RtlProcessHeap(), 0, p);
- }
-
- return result;
-}
-
DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
THREAD_CONTEXT Context;
@@ -838,6 +824,12 @@ NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) {
BOOL NTAPI MmpInitialize() {
+ auto tls = CONTAINING_RECORD(NtCurrentTeb()->ThreadLocalStoragePointer, TLS_VECTOR, TLS_VECTOR::ModuleTlsData);
+ if (tls && tls->Length > MMP_START_TLS_INDEX) {
+ RtlRaiseStatus(STATUS_NOT_SUPPORTED);
+ return FALSE;
+ }
+
//
// Capture thread count
//
@@ -855,13 +847,13 @@ BOOL NTAPI MmpInitialize() {
InitializeListHead(&MmpTlsList);
RtlInitializeSRWLock(&MmpTlsListLock);
- PULONG buffer = PULONG(RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ULONG) * 8));
+ PULONG buffer = PULONG(RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, MMP_TLSP_INDEX_BUFFER_SIZE));
if (!buffer) {
RtlRaiseStatus(STATUS_NO_MEMORY);
}
- RtlFillMemory(buffer, sizeof(ULONG) * 4, -1);
- RtlInitializeBitMap(&MmpTlsBitmap, buffer, 0x100);
+ RtlFillMemory(buffer, MMP_START_TLS_INDEX / 8, -1);
+ RtlInitializeBitMap(&MmpTlsBitmap, buffer, MMP_MAXIMUM_TLS_INDEX);
if (NtCurrentTeb()->ThreadLocalStoragePointer) {
if (!PreHookNtSetInformationProcess()) {
diff --git a/MemoryModule/NativeFunctionsInternal.cpp b/MemoryModule/NativeFunctionsInternal.cpp
index ba44c0f..bcecb66 100644
--- a/MemoryModule/NativeFunctionsInternal.cpp
+++ b/MemoryModule/NativeFunctionsInternal.cpp
@@ -1,17 +1,6 @@
#include "stdafx.h"
#include
-#define InsertTailList(ListHead,Entry) {\
- PLIST_ENTRY _EX_Blink;\
- PLIST_ENTRY _EX_ListHead;\
- _EX_ListHead = (ListHead);\
- _EX_Blink = _EX_ListHead->Blink;\
- (Entry)->Flink = _EX_ListHead;\
- (Entry)->Blink = _EX_Blink;\
- _EX_Blink->Flink = (Entry);\
- _EX_ListHead->Blink = (Entry);\
-}
-
typedef BOOL(WINAPI* PDLL_STARTUP_ROUTINE)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
static PRTL_RB_TREE NTAPI RtlFindLdrpModuleBaseAddressIndex() {
@@ -491,10 +480,15 @@ BOOLEAN __forceinline WINAPI CheckSumBufferedFile(LPVOID BaseAddress, DWORD Buff
return HdrSum == CalcSum;
}
#endif
-BOOLEAN NTAPI RtlIsValidImageBuffer(PVOID Buffer) {
+BOOLEAN NTAPI RtlIsValidImageBuffer(
+ _In_ PVOID Buffer,
+ _Out_opt_ size_t* Size) {
BOOLEAN result = FALSE;
__try {
+
+ if (Size)*Size = 0;
+
union {
PIMAGE_NT_HEADERS32 nt32;
PIMAGE_NT_HEADERS64 nt64;
@@ -532,6 +526,7 @@ BOOLEAN NTAPI RtlIsValidImageBuffer(PVOID Buffer) {
}
IMAGE_FIRST_SECTION(headers.nt32);
ProbeForRead(Buffer, SizeofImage);
+ if (Size)*Size = SizeofImage;
result = CheckSumBufferedFile(Buffer, SizeofImage);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
@@ -602,7 +597,7 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW(
__try {
*BaseAddress = nullptr;
if (LdrEntry)*LdrEntry = nullptr;
- if (!(dwFlags & LOAD_FLAGS_PASS_IMAGE_CHECK) && !RtlIsValidImageBuffer(BufferAddress))status = STATUS_INVALID_IMAGE_FORMAT;
+ if (!(dwFlags & LOAD_FLAGS_PASS_IMAGE_CHECK) && !RtlIsValidImageBuffer(BufferAddress, &BufferSize))status = STATUS_INVALID_IMAGE_FORMAT;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode();
@@ -645,8 +640,8 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW(
}
}
- status = MemoryLoadLibrary(BaseAddress, BufferAddress);
- if (!NT_SUCCESS(status))return status;
+ status = MemoryLoadLibrary(BaseAddress, BufferAddress, BufferSize);
+ if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)return status;
if (!(module = MapMemoryModuleHandle(*BaseAddress))) {
__fastfail(FAST_FAIL_FATAL_APP_EXIT);
@@ -714,6 +709,10 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW(
LdrUnloadDllMemory(*BaseAddress);
}
+ if (dwFlags & LOAD_FLAGS_HOOK_DOT_NET) {
+ MmpInitializeHooksForDotNet();
+ }
+
return status;
}
@@ -827,8 +826,8 @@ NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(OUT PDWORD pFeatures) {
if (RtlFindLdrpHeap())features |= MEMORY_FEATURE_LDRP_HEAP;
if (RtlFindLdrpHashTable())features |= MEMORY_FEATURE_LDRP_HASH_TABLE;
if (RtlFindLdrpInvertedFunctionTable())features |= MEMORY_FEATURE_INVERTED_FUNCTION_TABLE;
- if (NT_SUCCESS(RtlFindLdrpHandleTlsData(&pfn, &value)) && pfn)features |= MEMORY_FEATURE_LDRP_HANDLE_TLS_DATA;
- if (NT_SUCCESS(RtlFindLdrpReleaseTlsEntry(&pfn, &value) && pfn))features |= MEMORY_FEATURE_LDRP_RELEASE_TLS_ENTRY;
+ features |= MEMORY_FEATURE_LDRP_HANDLE_TLS_DATA | MEMORY_FEATURE_LDRP_RELEASE_TLS_ENTRY;
+
if (features)features |= MEMORY_FEATURE_SUPPORT_VERSION;
*pFeatures = features;
}
diff --git a/MemoryModule/NativeFunctionsInternal.h b/MemoryModule/NativeFunctionsInternal.h
index a01620a..b171318 100644
--- a/MemoryModule/NativeFunctionsInternal.h
+++ b/MemoryModule/NativeFunctionsInternal.h
@@ -51,6 +51,9 @@ NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(OUT PDWORD pFeatures);
//Dont call LdrpHandleTlsData routine if this flag is specified.
#define LOAD_FLAGS_NOT_HANDLE_TLS 0x00000008
+//Hook for dotnet dlls
+#define LOAD_FLAGS_HOOK_DOT_NET 0x00000010
+
NTSTATUS NTAPI LdrLoadDllMemoryExW(
OUT HMEMORYMODULE* BaseAddress, // Output module base address
diff --git a/MemoryModule/rtltls.cpp b/MemoryModule/rtltls.cpp
index cd23461..6f76371 100644
--- a/MemoryModule/rtltls.cpp
+++ b/MemoryModule/rtltls.cpp
@@ -6,265 +6,10 @@ NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry);
// MmpTls.cpp
NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry);
-
-static NTSTATUS NTAPI LdrpHandleTlsDataXp(PLDR_DATA_TABLE_ENTRY LdrEntry) {
- return STATUS_NOT_SUPPORTED;
-}
-
-NTSTATUS NTAPI RtlFindLdrpHandleTlsData(PVOID* _LdrpHandleTlsData, bool* stdcall) {
- *_LdrpHandleTlsData = MmpHandleTlsData;
- *stdcall = true;
- return STATUS_SUCCESS;
-
-
- static PVOID _LdrpHandleTlsData_ = (PVOID)~0;
- NTSTATUS status = STATUS_SUCCESS;
-
- __try {
- if (_LdrpHandleTlsData_ != (PVOID)~0) {
- *_LdrpHandleTlsData = _LdrpHandleTlsData_;
- if (_LdrpHandleTlsData_ == nullptr)status = STATUS_NOT_SUPPORTED;
- }
- else {
- *_LdrpHandleTlsData = _LdrpHandleTlsData_ = nullptr;
- if (stdcall) {
- *stdcall = false;
- }
- }
- }
- __except (EXCEPTION_EXECUTE_HANDLER) {
- status = GetExceptionCode();
- }
- if (!NT_SUCCESS(status))return status;
-
- DWORD Versions[3]{};
- LPCVOID Feature = nullptr;
- BYTE Size = 0;
- WORD OffsetOfFunctionBegin = 0;
- RtlGetNtVersionNumbers(Versions, Versions + 1, Versions + 2);
- switch (Versions[0]) {
- case 10: {
- if (Versions[1])return STATUS_NOT_SUPPORTED;
-
- //RS3
- if (Versions[2] >= 16299) {
- Size = 7;
- //19H2
- if (Versions[2] >= 18363)Feature = "\x74\x33\x44\x8D\x43\x09";
- //RS5
- else if (Versions[2] >= 17763) Feature = "\x8b\xc1\x8d\x4d\xbc\x51";
- //RS4
- else if (Versions[2] >= 17134) Feature = "\x33\xf6\x85\xc0\x79\x03";
- //RS3
- else Feature = "\x8b\xc1\x8d\x4d\xac\x51";
-#ifdef _WIN64
- //RS6(19H1)
- if (Versions[2] >= 18362) OffsetOfFunctionBegin = 0x46;
- //RS4
- else if (Versions[2] >= 17134) OffsetOfFunctionBegin = 0x44;
- //RS3
- else OffsetOfFunctionBegin = 0x43;
-#else
- //19H2
- if (Versions[2] == 18363) {
- Feature = "\x74\x25\x8b\xc1\x8d\x4d\xbc";
- OffsetOfFunctionBegin = 0x16;
- }
- //RS6(19H1)
- else if (Versions[2] == 18362) OffsetOfFunctionBegin = 0x2E;
- //RS5
- else if (Versions[2] >= 17763) OffsetOfFunctionBegin = 0x2C;
- //RS3,4
- else OffsetOfFunctionBegin = 0x18;
-#endif
- break;
- }
- //RS2
- else if (Versions[2] >= 15063) {
- Size = 7;
-#ifdef _WIN64
- OffsetOfFunctionBegin = 0x43;
- Feature = "\x74\x33\x44\x8d\x43\x09";
-#else
- OffsetOfFunctionBegin = 0x18;
- Feature = "\x8b\xc1\x8d\x4d\xbc\x51";
-#endif
- break;
- }
-
- // NO BREAK
- }
- case 6: {
- switch (Versions[1]) {
- //8.1
- case 3: {
-#ifdef _WIN64
- Size = 10;
- OffsetOfFunctionBegin = 0x43;
- Feature = "\x44\x8d\x43\x09\x4c\x8d\x4c\x24\x38";
-#else
- Size = 8;
- OffsetOfFunctionBegin = 0x1B;
- Feature = "\x50\x6a\x09\x6a\x01\x8b\xc1";
-#endif
- break;
- }
- //8
- case 2: {
-#ifdef _WIN64
- Size = 9;
- OffsetOfFunctionBegin = 0x49;
- Feature = "\x48\x8b\x79\x30\x45\x8d\x66\x01";
-#else
- Size = 7;
- OffsetOfFunctionBegin = 0xC;
- Feature = "\x8b\x45\x08\x89\x45\xa0";
-#endif
- break;
- }
- //7
- case 1: {
-#ifdef _WIN64
- Size = 12;
- OffsetOfFunctionBegin = 0x27;
- Feature = "\x41\xb8\x09\x00\x00\x00\x48\x8d\x44\x24\x38";
-#else
- Size = 9;
- OffsetOfFunctionBegin = 0x14;
- Feature = "\x74\x20\x8d\x45\xd4\x50\x6a\x09";
-#endif
- break;
- }
- default:return STATUS_NOT_SUPPORTED;
- }
- break;
- }
-
- default: {
- *_LdrpHandleTlsData = LdrpHandleTlsDataXp;
- *stdcall = true;
- return status;
- }
- }
-
- SEARCH_CONTEXT SearchContext{ SearchContext.MemoryBuffer = const_cast(Feature),SearchContext.BufferLength = Size - 1 };
- if (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(RtlFindNtdllLdrEntry()->DllBase), ".text", &SearchContext)))
- SearchContext.OutBufferPtr -= OffsetOfFunctionBegin;
- if (!(*_LdrpHandleTlsData = _LdrpHandleTlsData_ = SearchContext.MemoryBlockInSection))return STATUS_NOT_SUPPORTED;
- if (stdcall) *stdcall = !RtlIsWindowsVersionOrGreater(6, 3, 0);
- return status;
-}
-
-NTSTATUS NTAPI RtlFindLdrpReleaseTlsEntry(PVOID* _LdrpReleaseTlsEntry, bool* stdcall) {
- *_LdrpReleaseTlsEntry = MmpReleaseTlsEntry;
- *stdcall = true;
- return STATUS_SUCCESS;
-
- static PVOID _LdrpReleaseTlsEntry_ = (PVOID)~0;
- NTSTATUS status = STATUS_SUCCESS;
-
- __try {
- if (_LdrpReleaseTlsEntry_ != (PVOID)~0) {
- *_LdrpReleaseTlsEntry = _LdrpReleaseTlsEntry_;
- if (!_LdrpReleaseTlsEntry_)status = STATUS_NOT_SUPPORTED;
- }
- else {
- *_LdrpReleaseTlsEntry = _LdrpReleaseTlsEntry_ = nullptr;
- if (stdcall) {
- *stdcall = false;
- }
- }
- }
- __except (EXCEPTION_EXECUTE_HANDLER) {
- status = GetExceptionCode();
- }
- if (!NT_SUCCESS(status))return status;
-
- DWORD Versions[3]{};
- LPCVOID Feature = nullptr;
- BYTE Size = 0;
- WORD OffsetOfFunctionBegin = 0;
- RtlGetNtVersionNumbers(Versions, Versions + 1, Versions + 2);
- switch (Versions[0]) {
- case 10: {
- if (Versions[1]) {
- status = STATUS_NOT_SUPPORTED;
- break;
- }
- if (Versions[2] >= 18362) {
- Size = 0x10;
- OffsetOfFunctionBegin = 0x2F;
- Feature = "\x74\x26\x48\x8B\x00\x48\x39\x58\x08\x75\x5D\x48\x8B\x4B\x08";
- break;
- }
- }
- default:
- status = STATUS_NOT_SUPPORTED;
- }
-
- if (!NT_SUCCESS(status)) {
- return status;
- }
-
- SEARCH_CONTEXT SearchContext{ SearchContext.MemoryBuffer = const_cast(Feature),SearchContext.BufferLength = Size - 1 };
- if (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(RtlFindNtdllLdrEntry()->DllBase), ".text", &SearchContext)))
- SearchContext.OutBufferPtr -= OffsetOfFunctionBegin;
- if (!(*_LdrpReleaseTlsEntry = _LdrpReleaseTlsEntry_ = SearchContext.MemoryBlockInSection))return STATUS_NOT_SUPPORTED;
- if (stdcall)*stdcall = !RtlIsWindowsVersionOrGreater(6, 3, 0);
- return status;
-}
-
-static NTSTATUS NTAPI RtlInvokeTlsHandler(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN BOOLEAN Release) {
- return STATUS_NOT_SUPPORTED;
-
- struct _FUNCTION_SET {
- bool stdcall;
-
- union {
- struct {
- NTSTATUS(__stdcall* LdrpHandleTlsData)(PLDR_DATA_TABLE_ENTRY LdrEntry);
- NTSTATUS(__stdcall* LdrpReleaseTlsEntry)(PLDR_DATA_TABLE_ENTRY LdrEntry, DWORD);
- }Default;
-
- struct {
- NTSTATUS(__thiscall* LdrpHandleTlsData)(PLDR_DATA_TABLE_ENTRY LdrEntry);
- NTSTATUS(__thiscall* LdrpReleaseTlsEntry)(PLDR_DATA_TABLE_ENTRY LdrEntry, DWORD);
- }WinBlue;
- };
-
- _FUNCTION_SET() {
- if (!NT_SUCCESS(RtlFindLdrpHandleTlsData((PVOID*)(&this->Default.LdrpHandleTlsData), &this->stdcall)) ||
- !NT_SUCCESS(RtlFindLdrpReleaseTlsEntry((PVOID*)(&this->Default.LdrpReleaseTlsEntry), nullptr))) {
- this->Default = {};
- OutputDebugString(L"Can`t find both LdrpHandleTlsData and LdrpReleaseTlsEntry.\n");
- }
- }
-
- NTSTATUS operator()(PLDR_DATA_TABLE_ENTRY LdrEntry) {
- if (!Default.LdrpHandleTlsData) {
- return STATUS_NOT_SUPPORTED;
- }
- return stdcall ? Default.LdrpHandleTlsData(LdrEntry) : WinBlue.LdrpHandleTlsData(LdrEntry);
- }
-
- NTSTATUS operator()(PLDR_DATA_TABLE_ENTRY LdrEntry, DWORD dwFlags) {
- if (!Default.LdrpReleaseTlsEntry) {
- return STATUS_NOT_SUPPORTED;
- }
- return stdcall ? Default.LdrpReleaseTlsEntry(LdrEntry,dwFlags) : WinBlue.LdrpReleaseTlsEntry(LdrEntry, dwFlags);
- }
-
- }static InvokeHandler;
-
- return Release ? InvokeHandler(LdrEntry, 0) : InvokeHandler(LdrEntry);
-}
-
NTSTATUS NTAPI LdrpHandleTlsData(IN PLDR_DATA_TABLE_ENTRY LdrEntry) {
return MmpHandleTlsData(LdrEntry);
- //return RtlInvokeTlsHandler(LdrEntry, FALSE);
}
NTSTATUS NTAPI LdrpReleaseTlsEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) {
return MmpReleaseTlsEntry(LdrEntry);
- //return RtlInvokeTlsHandler(LdrEntry, TRUE);
}
diff --git a/MemoryModule/rtltls.h b/MemoryModule/rtltls.h
index 83930d2..859d586 100644
--- a/MemoryModule/rtltls.h
+++ b/MemoryModule/rtltls.h
@@ -1,9 +1,5 @@
#pragma once
-NTSTATUS NTAPI RtlFindLdrpHandleTlsData(PVOID* _LdrpHandleTlsData, bool* stdcall);
-
-NTSTATUS NTAPI RtlFindLdrpReleaseTlsEntry(PVOID* _LdrpReleaseTlsEntry, bool* stdcall);
-
NTSTATUS NTAPI LdrpHandleTlsData(IN PLDR_DATA_TABLE_ENTRY LdrEntry);
NTSTATUS NTAPI LdrpReleaseTlsEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry);
diff --git a/MemoryModule/stdafx.h b/MemoryModule/stdafx.h
index 08f8722..47f99b8 100644
--- a/MemoryModule/stdafx.h
+++ b/MemoryModule/stdafx.h
@@ -30,6 +30,9 @@
//tls support
#include "rtltls.h"
+//DotNet support
+#include "MmpDotNet.h"
+
//MemoryModulePP api interface
#include "NativeFunctionsInternal.h"
diff --git a/test/test.cpp b/test/test.cpp
index 879dd29..2c06461 100644
--- a/test/test.cpp
+++ b/test/test.cpp
@@ -1,4 +1,4 @@
-#include "../MemoryModule/LoadDllMemoryApi.h"
+#include "../MemoryModule/stdafx.h"
#include
#pragma warning(disable:4996)
@@ -21,22 +21,28 @@ static PVOID ReadDllFile(LPCSTR FileName) {
int main() {
HMEMORYMODULE hModule;
NTSTATUS status;
- PVOID buffer = ReadDllFile("System.Data.dll");
+ PVOID buffer = ReadDllFile("lib.dll");
if (!buffer) {
return 0;
}
status = LdrLoadDllMemoryExW(
- &hModule, // ModuleHandle
- nullptr, // LdrEntry
- 0, // Flags
- buffer, // Buffer
- 0, // Reserved
- nullptr, // DllBaseName
- nullptr // DllFullName
+ &hModule, // ModuleHandle
+ nullptr, // LdrEntry
+ LOAD_FLAGS_HOOK_DOT_NET, // Flags
+ buffer, // Buffer
+ 0, // Reserved
+ nullptr, // DllBaseName
+ nullptr // DllFullName
);
- if (NT_SUCCESS(status)) {
+ if (NT_SUCCESS(status) && status != STATUS_IMAGE_MACHINE_TYPE_MISMATCH) {
+ int result = 0;
+ typedef int(WINAPI* func)(int, int);
+
+ func f = (func)GetProcAddress(hModule, "Add");
+ if (f)result = f(128, 256);
+
LdrUnloadDllMemory(hModule);
}