diff --git a/MemoryModule/MemoryModule.cpp b/MemoryModule/MemoryModule.cpp index 6676887..ca95ab3 100644 --- a/MemoryModule/MemoryModule.cpp +++ b/MemoryModule/MemoryModule.cpp @@ -68,6 +68,7 @@ NTSTATUS MemoryLoadLibrary( PIMAGE_DOS_HEADER dos_header = nullptr; PIMAGE_NT_HEADERS old_header = nullptr; + BOOLEAN CorImage = FALSE; NTSTATUS status = STATUS_SUCCESS; // @@ -91,12 +92,25 @@ NTSTATUS MemoryLoadLibrary( // old_header = (PIMAGE_NT_HEADERS)((size_t)data + dos_header->e_lfanew); if (old_header->Signature != IMAGE_NT_SIGNATURE || - old_header->FileHeader.Machine != HOST_MACHINE || old_header->OptionalHeader.SectionAlignment & 1) { status = STATUS_INVALID_IMAGE_FORMAT; __leave; } + // + // Determine whether it is a .NET assembly + // + auto& com = old_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]; + CorImage = com.Size && com.VirtualAddress; + + // + // Match machine type + // + if (old_header->FileHeader.Machine != HOST_MACHINE) { + status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; + __leave; + } + // // Only dll image support // @@ -228,12 +242,7 @@ NTSTATUS MemoryLoadLibrary( PIMAGE_DATA_DIRECTORY dir = GET_HEADER_DICTIONARY(new_header, IMAGE_DIRECTORY_ENTRY_BASERELOC); PIMAGE_BASE_RELOCATION_HEADER relocation = (PIMAGE_BASE_RELOCATION_HEADER)(LPBYTE(base) + dir->VirtualAddress); - if (dir->Size == 0 || dir->VirtualAddress == 0) { - if (!locationDelta) { - status = STATUS_INVALID_IMAGE_FORMAT; - } - } - else { + if (dir->Size && dir->VirtualAddress) { while (relocation->VirtualAddress > 0) { auto relInfo = (_REBASE_INFO*)&relocation->TypeOffset; for (DWORD i = 0; i < relocation->TypeOffsetCount(); ++i, ++relInfo) { @@ -343,7 +352,10 @@ NTSTATUS MemoryLoadLibrary( LPVOID address = LPBYTE(base) + section->VirtualAddress; SIZE_T size = AlignValueUp(section->Misc.VirtualSize, new_header->OptionalHeader.SectionAlignment); - if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) { + if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE && !CorImage) { + // + // If it is a .NET assembly, we cannot release this memory block + // #pragma warning(disable:6250) VirtualFree(address, size, MEM_DECOMMIT); #pragma warning(default:6250) diff --git a/MemoryModule/NativeFunctionsInternal.cpp b/MemoryModule/NativeFunctionsInternal.cpp index c3b51e5..ba44c0f 100644 --- a/MemoryModule/NativeFunctionsInternal.cpp +++ b/MemoryModule/NativeFunctionsInternal.cpp @@ -167,6 +167,17 @@ static bool NTAPI RtlInitializeLdrDataTableEntry( if (!headers)return false; bool FlagsProcessed = false; + bool CorImage = false, CorIL = false; + auto& com = headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]; + if (com.Size && com.VirtualAddress) { + CorImage = true; + + auto cor = PIMAGE_COR20_HEADER(LPBYTE(BaseAddress) + com.VirtualAddress); + if (cor->Flags & ReplacesCorHdrNumericDefines::COMIMAGE_FLAGS_ILONLY) { + CorIL = true; + } + } + switch (NtWindowsVersion()) { case win10: case win10_1: @@ -198,6 +209,9 @@ static bool NTAPI RtlInitializeLdrDataTableEntry( entry->ImageDll = entry->LoadNotificationsSent = entry->EntryProcessed = entry->InLegacyLists = entry->InIndexes = entry->ProcessAttachCalled = true; entry->InExceptionTable = !(dwFlags & LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION); + entry->CorImage = CorImage; + entry->CorILOnly = CorIL; + FlagsProcessed = true; } @@ -225,7 +239,10 @@ static bool NTAPI RtlInitializeLdrDataTableEntry( LdrEntry->FullDllName = DllFullName; LdrEntry->EntryPoint = (PVOID)((size_t)BaseAddress + headers->OptionalHeader.AddressOfEntryPoint); LdrEntry->LoadCount = 1; - if (!FlagsProcessed) LdrEntry->Flags = LDRP_IMAGE_DLL | LDRP_ENTRY_INSERTED | LDRP_ENTRY_PROCESSED | LDRP_PROCESS_ATTACH_CALLED; + if (!FlagsProcessed) { + LdrEntry->Flags = LDRP_IMAGE_DLL | LDRP_ENTRY_INSERTED | LDRP_ENTRY_PROCESSED | LDRP_PROCESS_ATTACH_CALLED; + if (CorImage)LdrEntry->Flags |= LDRP_COR_IMAGE; + } RtlInitializeListEntry(&LdrEntry->HashLinks); return true; } diff --git a/test/test.cpp b/test/test.cpp index 4bf4cad..879dd29 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -21,7 +21,7 @@ static PVOID ReadDllFile(LPCSTR FileName) { int main() { HMEMORYMODULE hModule; NTSTATUS status; - PVOID buffer = ReadDllFile("a.dll"); + PVOID buffer = ReadDllFile("System.Data.dll"); if (!buffer) { return 0; @@ -37,13 +37,6 @@ int main() { nullptr // DllFullName ); if (NT_SUCCESS(status)) { - auto thread = GetProcAddress(MemoryModuleToModule(hModule), "thread"); - if (thread) { - if (thread() != 0) { - printf("tls failed\n"); - } - } - LdrUnloadDllMemory(hModule); }