1. Add Win10 forward export support

2. Fixed some bugs
This commit is contained in:
Boring
2020-02-22 14:53:26 +08:00
parent ea135ac392
commit ed550ae6c7
15 changed files with 764 additions and 175 deletions
+61 -55
View File
@@ -4,6 +4,7 @@
#include <tchar.h>
#include "rtltype.h"
#include "ntstatus.h"
#include "Native.h"
#include <algorithm>
#if _MSC_VER
@@ -134,7 +135,7 @@ static BOOL CheckSize(size_t size, size_t expected) {
return TRUE;
}
static BOOL CopySections(const unsigned char* data, size_t size, PMEMORYMODULE module) {
static BOOL CopySections(const unsigned char* data, PMEMORYMODULE module) {
LPBYTE codeBase = module->codeBase;
LPVOID dest;
PIMAGE_NT_HEADERS headers = GetImageNtHeaders(module);
@@ -145,7 +146,12 @@ static BOOL CopySections(const unsigned char* data, size_t size, PMEMORYMODULE m
alloc_size = headers->OptionalHeader.SectionAlignment;
cp = false;
if (section->SizeOfRawData) {
if (!CheckSize(size, static_cast<size_t>(section->PointerToRawData) + section->SizeOfRawData)) return FALSE;
__try {
ProbeForRead(data, static_cast<size_t>(section->PointerToRawData) + section->SizeOfRawData);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return FALSE;
}
alloc_size = section->SizeOfRawData;
cp = true;
}
@@ -354,15 +360,23 @@ static BOOL BuildImportTable(PMEMORYMODULE module) {
return result;
}
HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
//static BOOL PerformForwardExport(PMEMORYMODULE module) {
// PIMAGE_EXPORT_DIRECTORY exports;
// PIMAGE_NT_HEADERS headers = GetImageNtHeaders(module);
// PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(headers, IMAGE_DIRECTORY_ENTRY_EXPORT);
// if (!directory->Size)return TRUE;
// return FALSE;
//
//}
HMEMORYMODULE MemoryLoadLibrary(const void* data) {
PMEMORYMODULE hMemoryModule = nullptr;
PIMAGE_DOS_HEADER dos_header, new_dos_header;
PIMAGE_NT_HEADERS old_header, new_header;
unsigned char* code;
unsigned char* base;
ptrdiff_t locationDelta;
SYSTEM_INFO sysInfo;
static SYSTEM_INFO sysInfo{};
PIMAGE_SECTION_HEADER section;
DWORD i;
size_t optionalSectionSize;
size_t lastSectionEnd = 0;
size_t alignedImageSize;
@@ -371,40 +385,36 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
POINTER_LIST* blockedMemory = nullptr;
#endif
if (!CheckSize(size, sizeof(IMAGE_DOS_HEADER))) return nullptr;
dos_header = (PIMAGE_DOS_HEADER)data;
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
SetLastError(ERROR_BAD_EXE_FORMAT);
__try {
ProbeForRead(data, sizeof(IMAGE_DOS_HEADER));
dos_header = (PIMAGE_DOS_HEADER)data;
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return nullptr;
}
ProbeForRead(data, dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS));
old_header = (PIMAGE_NT_HEADERS)((size_t)data + dos_header->e_lfanew);
if (old_header->Signature != IMAGE_NT_SIGNATURE ||
!ProbeForRead(data, old_header->OptionalHeader.SizeOfHeaders) ||
old_header->FileHeader.Machine != HOST_MACHINE ||
old_header->OptionalHeader.SectionAlignment & 1) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return nullptr;
}
//only dll image support
if (!(old_header->FileHeader.Characteristics & IMAGE_FILE_DLL)) {
SetLastError(ERROR_NOT_SUPPORTED);
return nullptr;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError(ERROR_INVALID_DATA);
return nullptr;
}
if (!CheckSize(size, dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS))) return nullptr;
old_header = (PIMAGE_NT_HEADERS) & ((const unsigned char*)(data))[dos_header->e_lfanew];
if (old_header->Signature != IMAGE_NT_SIGNATURE) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return nullptr;
}
if (old_header->FileHeader.Machine != HOST_MACHINE) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return nullptr;
}
if (old_header->OptionalHeader.SectionAlignment & 1) {
// Only support section alignments that are a multiple of 2
SetLastError(ERROR_BAD_EXE_FORMAT);
return nullptr;
}
//only dll image support
if (!(old_header->FileHeader.Characteristics & IMAGE_FILE_DLL)) {
SetLastError(ERROR_NOT_SUPPORTED);
return nullptr;
}
section = IMAGE_FIRST_SECTION(old_header);
optionalSectionSize = old_header->OptionalHeader.SectionAlignment;
for (i = 0; i < old_header->FileHeader.NumberOfSections; i++, section++) {
for (DWORD i = 0; i < old_header->FileHeader.NumberOfSections; i++, section++) {
size_t endOfSection;
if (section->SizeOfRawData == 0) {
// Section without data in the DLL
@@ -419,7 +429,7 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
}
}
GetNativeSystemInfo(&sysInfo);
if (!sysInfo.dwPageSize)GetNativeSystemInfo(&sysInfo);
alignedImageSize = AlignValueUp(old_header->OptionalHeader.SizeOfImage, sysInfo.dwPageSize);
if (alignedImageSize != AlignValueUp(lastSectionEnd, sysInfo.dwPageSize)) {
SetLastError(ERROR_BAD_EXE_FORMAT);
@@ -430,12 +440,12 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
// reserve memory for image of library
// XXX: is it correct to commit the complete memory region at once?
// calling DllEntry raises an exception if we don't...
if (!(code = (LPBYTE)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase), alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
if (!(base = (LPBYTE)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase), alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
if (!(old_header->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE)) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return nullptr;
}
if (!(code = (LPBYTE)VirtualAlloc(nullptr, alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
if (!(base = (LPBYTE)VirtualAlloc(nullptr, alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
SetLastError(ERROR_OUTOFMEMORY);
return nullptr;
}
@@ -443,20 +453,20 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
#ifdef _WIN64
// Memory block may not span 4 GB boundaries.
while ((((uintptr_t)code) >> 32) < (((uintptr_t)(code + alignedImageSize)) >> 32)) {
while ((((uintptr_t)base) >> 32) < (((uintptr_t)(base + alignedImageSize)) >> 32)) {
POINTER_LIST* node = new POINTER_LIST;
if (!node) {
VirtualFree(code, 0, MEM_RELEASE);
VirtualFree(base, 0, MEM_RELEASE);
FreePointerList(blockedMemory);
SetLastError(ERROR_OUTOFMEMORY);
return nullptr;
}
node->next = blockedMemory;
node->address = code;
node->address = base;
blockedMemory = node;
if (!(code = (LPBYTE)VirtualAlloc(nullptr, alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
if (!(base = (LPBYTE)VirtualAlloc(nullptr, alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
FreePointerList(blockedMemory);
SetLastError(ERROR_OUTOFMEMORY);
return nullptr;
@@ -464,11 +474,11 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
}
#endif
new_dos_header = (PIMAGE_DOS_HEADER)code;
new_header = (PIMAGE_NT_HEADERS)(code + dos_header->e_lfanew);
hMemoryModule = (PMEMORYMODULE)(code + old_header->OptionalHeader.SizeOfHeaders);
new_dos_header = (PIMAGE_DOS_HEADER)base;
new_header = (PIMAGE_NT_HEADERS)(base + dos_header->e_lfanew);
hMemoryModule = (PMEMORYMODULE)(base + old_header->OptionalHeader.SizeOfHeaders);
RtlZeroMemory(hMemoryModule, sizeof(MEMORYMODULE));
hMemoryModule->codeBase = code;
hMemoryModule->codeBase = base;
hMemoryModule->pageSize = sysInfo.dwPageSize;
hMemoryModule->Signature = MEMORY_MODULE_SIGNATURE;
hMemoryModule->SizeofHeaders = old_header->OptionalHeader.SizeOfHeaders;
@@ -477,18 +487,14 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
hMemoryModule->blockedMemory = blockedMemory;
#endif
if (!CheckSize(size, old_header->OptionalHeader.SizeOfHeaders)) {
goto error;
}
// copy PE header to code
memcpy(new_dos_header, dos_header, old_header->OptionalHeader.SizeOfHeaders);
new_header->OptionalHeader.SizeOfImage = (DWORD)(alignedImageSize);
new_header->OptionalHeader.ImageBase = (size_t)code;
new_header->OptionalHeader.ImageBase = (size_t)base;
new_header->OptionalHeader.BaseOfCode = headers_align;
// copy sections from DLL file block to new memory location
if (!CopySections((LPBYTE)data, size, hMemoryModule)) goto error;
if (!CopySections((LPBYTE)data, hMemoryModule)) goto error;
// adjust base address of imported data
locationDelta = (ptrdiff_t)(hMemoryModule->codeBase - old_header->OptionalHeader.ImageBase);
@@ -509,7 +515,7 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
if (new_header->OptionalHeader.AddressOfEntryPoint) {
__try {
// notify library about attaching to process
if (!((DllEntryProc)(code + new_header->OptionalHeader.AddressOfEntryPoint))((HINSTANCE)code, DLL_PROCESS_ATTACH, 0)) {
if (!((DllEntryProc)(base + new_header->OptionalHeader.AddressOfEntryPoint))((HINSTANCE)base, DLL_PROCESS_ATTACH, 0)) {
SetLastError(ERROR_DLL_INIT_FAILED);
goto error;
}
@@ -521,7 +527,7 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
hMemoryModule->initialized = TRUE;
}
return code;
return base;
error:
// cleanup
MemoryFreeLibrary(hMemoryModule);
+1 -1
View File
@@ -101,7 +101,7 @@ extern "C" {
* All dependencies are resolved using default LoadLibrary/GetProcAddress
* calls through the Windows API.
*/
HMEMORYMODULE MemoryLoadLibrary(const void*, size_t);
HMEMORYMODULE MemoryLoadLibrary(const void*);
/**
* Get address of exported method. Supports loading both by name and by
+21
View File
@@ -364,3 +364,24 @@ PVOID NTAPI RtlEncodeSystemPointer(PVOID Pointer) {
PVOID NTAPI RtlDecodeSystemPointer(PVOID Pointer) {
return decltype(&RtlDecodeSystemPointer)(RtlGetNtProcAddress("RtlDecodeSystemPointer"))(Pointer);
}
BOOLEAN NTAPI VirtualAccessCheck(LPCVOID pBuffer, size_t size, ACCESS_MASK protect) {
MEMORY_BASIC_INFORMATION mbi{};
SIZE_T len = 0;
if (!NT_SUCCESS(NtQueryVirtualMemory(NtCurrentProcess(), const_cast<PVOID>(pBuffer), MemoryBasicInformation, &mbi, sizeof(mbi), &len)) ||
!(mbi.Protect & protect)) {
RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, nullptr);
return FALSE;
}
return TRUE;
}
NTSTATUS NTAPI LdrLockLoaderLock(size_t Flags, size_t* State, size_t* Cookie) {
return (decltype(&LdrLockLoaderLock)(RtlGetNtProcAddress("LdrLockLoaderLock")))(Flags, State, Cookie);
}
NTSTATUS NTAPI LdrUnlockLoaderLock(size_t Flags, size_t Cookie) {
return (decltype(&LdrUnlockLoaderLock)(RtlGetNtProcAddress("LdrUnlockLoaderLock")))(Flags, Cookie);
}
NTSTATUS NTAPI LdrUnloadDll(IN HANDLE ModuleHandle) {
return (decltype(&LdrUnloadDll)(RtlGetNtProcAddress("LdrUnloadDll")))(ModuleHandle);
}
+81
View File
@@ -372,6 +372,60 @@ typedef enum _PROCESSINFOCLASS {
ProcessLeapSecondInformation, // PROCESS_LEAP_SECOND_INFORMATION
MaxProcessInfoClass
} PROCESSINFOCLASS;
typedef enum _THREADINFOCLASS {
ThreadBasicInformation, // q: THREAD_BASIC_INFORMATION
ThreadTimes, // q: KERNEL_USER_TIMES
ThreadPriority, // s: KPRIORITY
ThreadBasePriority, // s: LONG
ThreadAffinityMask, // s: KAFFINITY
ThreadImpersonationToken, // s: HANDLE
ThreadDescriptorTableEntry, // q: DESCRIPTOR_TABLE_ENTRY (or WOW64_DESCRIPTOR_TABLE_ENTRY)
ThreadEnableAlignmentFaultFixup, // s: BOOLEAN
ThreadEventPair,
ThreadQuerySetWin32StartAddress, // q: PVOID
ThreadZeroTlsCell, // 10
ThreadPerformanceCount, // q: LARGE_INTEGER
ThreadAmILastThread, // q: ULONG
ThreadIdealProcessor, // s: ULONG
ThreadPriorityBoost, // qs: ULONG
ThreadSetTlsArrayAddress,
ThreadIsIoPending, // q: ULONG
ThreadHideFromDebugger, // s: void
ThreadBreakOnTermination, // qs: ULONG
ThreadSwitchLegacyState,
ThreadIsTerminated, // q: ULONG // 20
ThreadLastSystemCall, // q: THREAD_LAST_SYSCALL_INFORMATION
ThreadIoPriority, // qs: IO_PRIORITY_HINT
ThreadCycleTime, // q: THREAD_CYCLE_TIME_INFORMATION
ThreadPagePriority, // q: ULONG
ThreadActualBasePriority,
ThreadTebInformation, // q: THREAD_TEB_INFORMATION (requires THREAD_GET_CONTEXT + THREAD_SET_CONTEXT)
ThreadCSwitchMon,
ThreadCSwitchPmu,
ThreadWow64Context, // q: WOW64_CONTEXT
ThreadGroupInformation, // q: GROUP_AFFINITY // 30
ThreadUmsInformation, // q: THREAD_UMS_INFORMATION
ThreadCounterProfiling,
ThreadIdealProcessorEx, // q: PROCESSOR_NUMBER
ThreadCpuAccountingInformation, // since WIN8
ThreadSuspendCount, // since WINBLUE
ThreadHeterogeneousCpuPolicy, // q: KHETERO_CPU_POLICY // since THRESHOLD
ThreadContainerId, // q: GUID
ThreadNameInformation, // qs: THREAD_NAME_INFORMATION
ThreadSelectedCpuSets,
ThreadSystemThreadInformation, // q: SYSTEM_THREAD_INFORMATION // 40
ThreadActualGroupAffinity, // since THRESHOLD2
ThreadDynamicCodePolicyInfo,
ThreadExplicitCaseSensitivity, // qs: ULONG; s: 0 disables, otherwise enables
ThreadWorkOnBehalfTicket,
ThreadSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
ThreadDbgkWerReportActive,
ThreadAttachContainer,
ThreadManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
ThreadPowerThrottlingState, // THREAD_POWER_THROTTLING_STATE
ThreadWorkloadClass, // THREAD_WORKLOAD_CLASS // since REDSTONE5 // 50
MaxThreadInfoClass
} THREADINFOCLASS;
typedef struct _SYSTEM_PROCESS {
ULONG NextEntryOffset;//relative offset
ULONG ThreadCount;
@@ -998,6 +1052,13 @@ typedef struct _SECURITY__LOGON_SESSION_DATA {
LARGE_INTEGER PasswordMustChange;
}SECURITY_LOGON_SESSION_DATA, *PSECURITY_LOGON_SESSION_DATA,
LOGON_SESSION_DATA, *PLOGON_SESSION_DATA;
typedef struct _INITIAL_TEB {
PVOID StackBase;
PVOID StackLimit;
PVOID StackCommit;
PVOID StackCommitMax;
PVOID StackReserved;
} INITIAL_TEB, * PINITIAL_TEB;
NTSTATUS NTAPI NtQueryObject(
IN HANDLE ObjectHandle,
@@ -1340,3 +1401,23 @@ typedef struct _UNWIND_INFO {
NTSTATUS NTAPI NtQuerySystemTime(PLARGE_INTEGER SystemTime);
PVOID NTAPI RtlEncodeSystemPointer(PVOID Pointer);
PVOID NTAPI RtlDecodeSystemPointer(PVOID Pointer);
#define NtCurrentProcess() (HANDLE)-1
#define NtCurrentThread() (HANDLE)-2
BOOLEAN NTAPI VirtualAccessCheck(LPCVOID pBuffer, size_t size, ACCESS_MASK protect);
#define ProbeForRead(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE)
#define ProbeForWrite(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE)
#define ProbeForReadWrite(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_EXECUTE_READWRITE | PAGE_READWRITE)
#define ProbeForExecute(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)
//Flags
#define LOCK_RAISE_EXCEPTION 1
#define LOCK_NO_WAIT_IF_BUSY 2
//State
#define LOCK_STATE_NO_ENTER 0
#define LOCK_STATE_ENTERED 1
#define LOCK_STATE_LOCK_BUSY 2
NTSTATUS NTAPI LdrLockLoaderLock(size_t Flags, size_t* State, size_t* Cookie);
NTSTATUS NTAPI LdrUnlockLoaderLock(size_t Flags, size_t Cookie);
NTSTATUS NTAPI LdrUnloadDll(IN HANDLE ModuleHandle);
+131 -54
View File
@@ -51,26 +51,16 @@ static ULONG NTAPI LdrHashEntry(IN const UNICODE_STRING& str, IN bool _xor = tru
static HANDLE NTAPI RtlFindtLdrpHeap() {
PLIST_ENTRY ListHead, ListEntry;
PLDR_DATA_TABLE_ENTRY CurEntry;
MEMORY_BASIC_INFORMATION mbi{};
static HANDLE result = nullptr;
DWORD dwHeaps = 0;
HANDLE* hHeaps = nullptr;
if (result)return result;
dwHeaps = GetProcessHeaps(dwHeaps, hHeaps);
hHeaps = new HANDLE[dwHeaps];
ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
ListEntry = ListHead->Flink;
if (ListHead == ListEntry)return nullptr;
if (ListHead == ListEntry)return result;
CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
GetProcessHeaps(dwHeaps, hHeaps);
for (DWORD i = 0; i < dwHeaps; ++i) {
if (HeapValidate(hHeaps[i], 0, CurEntry)) {
result = hHeaps[i];
break;
}
}
delete[]hHeaps;
return result;
NtQueryVirtualMemory(NtCurrentProcess(), CurEntry, MemoryBasicInformation, &mbi, sizeof(mbi), (PSIZE_T)&ListHead);
return result = mbi.AllocationBase;
}
static PLDR_DATA_TABLE_ENTRY NTAPI RtlFindNtdllLdrEntry() {
PLIST_ENTRY ListHead, ListEntry;
@@ -242,7 +232,7 @@ static PRTL_BALANCED_NODE NTAPI RtlFindLdrpModuleBaseAddressIndex() {
return LdrpModuleBaseAddressIndex;
}
static NTSTATUS NTAPI NtInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry, IN PVOID BaseAddress) {
auto LdrpModuleBaseAddressIndex = RtlFindLdrpModuleBaseAddressIndex();
static auto LdrpModuleBaseAddressIndex = RtlFindLdrpModuleBaseAddressIndex();
if (!LdrpModuleBaseAddressIndex)return STATUS_UNSUCCESSFUL;
PLDR_DATA_TABLE_ENTRY_WIN8 LdrNode = decltype(LdrNode)((size_t)LdrpModuleBaseAddressIndex - offsetof(LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode));
@@ -274,20 +264,82 @@ static NTSTATUS NTAPI NtInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTR
return STATUS_SUCCESS;
}
static NTSTATUS NTAPI NtRemoveModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry) {
RTL_RB_TREE tree{ RtlFindLdrpModuleBaseAddressIndex() };
static RTL_RB_TREE tree{ RtlFindLdrpModuleBaseAddressIndex() };
if (!tree.Root)return STATUS_UNSUCCESSFUL;
RtlRbRemoveNode(&tree, &PLDR_DATA_TABLE_ENTRY_WIN8(DataTableEntry)->BaseAddressIndexNode);
return STATUS_SUCCESS;
}
static NTSTATUS NTAPI NtFreeDependencies(IN PLDR_DATA_TABLE_ENTRY_WIN8 LdrEntry) {
_LDR_DDAG_NODE* DependentDdgeNode = nullptr;
PLDR_DATA_TABLE_ENTRY_WIN8 ModuleEntry = nullptr;
_LDRP_CSLIST* head = (decltype(head))LdrEntry->DdagNode->Dependencies, *entry = head;
if (!LdrEntry->DdagNode->Dependencies)return STATUS_SUCCESS;
//find all dependencies and free
do {
DependentDdgeNode = entry->Dependent.DependentDdagNode;
if (DependentDdgeNode->Modules.Flink->Flink != &DependentDdgeNode->Modules) RaiseException(-1, EXCEPTION_NONCONTINUABLE, 0, nullptr);
ModuleEntry = decltype(ModuleEntry)((size_t)DependentDdgeNode->Modules.Flink - offsetof(_LDR_DATA_TABLE_ENTRY_WIN8, NodeModuleLink));
if (ModuleEntry->DdagNode != DependentDdgeNode) RaiseException(-1, EXCEPTION_NONCONTINUABLE, 0, nullptr);
if (!DependentDdgeNode->IncomingDependencies) RaiseException(-1, EXCEPTION_NONCONTINUABLE, 0, nullptr);
_LDRP_CSLIST::_LDRP_CSLIST_INCOMMING* _last = DependentDdgeNode->IncomingDependencies, *_entry = _last;
_LDR_DDAG_NODE* CurrentDdagNode;
size_t State = 0, Cookies;
//Acquire LoaderLock
do {
if (!NT_SUCCESS(LdrLockLoaderLock(LOCK_NO_WAIT_IF_BUSY, &State, &Cookies)))
RaiseException(-1, EXCEPTION_NONCONTINUABLE, 0, nullptr);
} while (State != LOCK_STATE_ENTERED);
do {
CurrentDdagNode = (decltype(CurrentDdagNode))((size_t)_entry->IncommingDdagNode & ~1);
if (CurrentDdagNode == LdrEntry->DdagNode) {
//node is head
if (_entry == DependentDdgeNode->IncomingDependencies) {
//only one node in list
if (_entry->NextIncommingEntry == (PSINGLE_LIST_ENTRY)DependentDdgeNode->IncomingDependencies) {
DependentDdgeNode->IncomingDependencies = nullptr;
}
else {
//find the last node in the list
PSINGLE_LIST_ENTRY i = _entry->NextIncommingEntry;
while (i->Next != (PSINGLE_LIST_ENTRY)_entry)i = i->Next;
i->Next = _entry->NextIncommingEntry;
DependentDdgeNode->IncomingDependencies = (_LDRP_CSLIST::_LDRP_CSLIST_INCOMMING*)_entry->NextIncommingEntry;
}
}
//node is not head
else {
_last->NextIncommingEntry = _entry->NextIncommingEntry;
}
break;
}
//save the last entry
if (_last != _entry)_last = (decltype(_last))_last->NextIncommingEntry;
_entry = (decltype(_entry))_entry->NextIncommingEntry;
} while (_entry != _last);
//free LoaderLock
LdrUnlockLoaderLock(0, Cookies);
//free it
LdrUnloadDll(ModuleEntry->DllBase);
NtFreeLdrpHeap(LdrEntry->DdagNode->Dependencies);
//lookup next dependent.
entry = (decltype(entry))entry->Dependent.NextDependentEntry;
LdrEntry->DdagNode->Dependencies = (_LDRP_CSLIST::_LDRP_CSLIST_DEPENDENT*)(entry == head ? nullptr : entry);
} while (entry != head);
return STATUS_SUCCESS;
}
static bool NTAPI NtInitializeLdrDataTableEntry(
OUT PLDR_DATA_TABLE_ENTRY LdrEntry,
IN DWORD dwFlags,
IN PVOID BaseAddress,
IN UNICODE_STRING &DllBaseName,
IN UNICODE_STRING &DllFullName) {
UNREFERENCED_PARAMETER(dwFlags);
RtlZeroMemory(LdrEntry, NtLdrDataTableEntrySize());
PIMAGE_NT_HEADERS headers = RtlImageNtHeader(BaseAddress);
if (!headers)return false;
@@ -303,7 +355,7 @@ static bool NTAPI NtInitializeLdrDataTableEntry(
case win8:
case win8_1: {
auto entry = (PLDR_DATA_TABLE_ENTRY_WIN8)LdrEntry;
NtQuerySystemTime(&entry->LoadTime);
entry->OriginalBase = headers->OptionalHeader.ImageBase;
entry->BaseNameHashValue = LdrHashEntry(DllBaseName, false);
entry->LoadReason = LoadReasonDynamicLoad;
@@ -311,14 +363,17 @@ static bool NTAPI NtInitializeLdrDataTableEntry(
if (!(entry->DdagNode = (decltype(entry->DdagNode))NtAllocateLdrpHeap(sizeof(_LDR_DDAG_NODE))))return false;
//NtInitializeListEntry(&entry->NodeModuleLink);
//NtInitializeListEntry(&entry->DdagNode->Modules);
//NtInitializeSingleEntry(&entry->DdagNode->CondenseLink);
entry->NodeModuleLink.Flink = &entry->DdagNode->Modules;
entry->NodeModuleLink.Blink = &entry->DdagNode->Modules;
entry->DdagNode->Modules.Flink = &entry->NodeModuleLink;
entry->DdagNode->Modules.Blink = &entry->NodeModuleLink;
entry->DdagNode->State = LdrModulesReadyToRun;
entry->DdagNode->LoadCount = 0;
NtInitializeSingleEntry(&entry->DdagNode->CondenseLink);
entry->DdagNode->LoadCount = 1;
entry->ImageDll = entry->LoadNotificationsSent = entry->EntryProcessed =
entry->InLegacyLists = entry->InIndexes = entry->ProcessAttachCalled = true;
entry->InExceptionTable = !(dwFlags & LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION);
FlagsProcessed = true;
}
case win7: {
@@ -344,6 +399,7 @@ static bool NTAPI NtInitializeLdrDataTableEntry(
LdrEntry->BaseDllName = DllBaseName;
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;
NtInitializeListEntry(&LdrEntry->HashLinks);
return true;
@@ -355,12 +411,12 @@ static bool NTAPI NtFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) {
switch (NtWindowsVersion()) {
case win10:
case win10_1:
case win10_2: {
auto entry = (PLDR_DATA_TABLE_ENTRY_WIN10)LdrEntry;
NtFreeLdrpHeap(entry->DdagNode);
}
case win10_2:
case win8:
case win8_1: {
auto entry = (PLDR_DATA_TABLE_ENTRY_WIN8)LdrEntry;
NtFreeDependencies(entry);
NtFreeLdrpHeap(entry->DdagNode);
NtRemoveModuleBaseAddressIndexNode(LdrEntry);
}
case win7:
@@ -556,7 +612,7 @@ static NTSTATUS NTAPI NtMapDllMemory(IN HMEMORYMODULE ViewBase, IN DWORD dwFlags
}
NTSTATUS NTAPI NtLoadDllMemory(OUT HMEMORYMODULE* BaseAddress, IN LPVOID BufferAddress, IN size_t BufferSize) {
return NtLoadDllMemoryExW(BaseAddress, nullptr, 0, BufferAddress, BufferSize, nullptr, nullptr);
return NtLoadDllMemoryExW(BaseAddress, nullptr, LOAD_FLAGS_NOT_FAIL_IF_HANDLE_TLS, BufferAddress, BufferSize, nullptr, nullptr);
}
NTSTATUS NTAPI NtLoadDllMemoryExW(
@@ -570,6 +626,8 @@ NTSTATUS NTAPI NtLoadDllMemoryExW(
PMEMORYMODULE module = nullptr;
NTSTATUS status = STATUS_SUCCESS;
PLDR_DATA_TABLE_ENTRY ModuleEntry = nullptr;
PIMAGE_NT_HEADERS headers = nullptr;
UNREFERENCED_PARAMETER(BufferSize);
__try {
if (IsBadReadPtr(BufferAddress, BufferSize))status = STATUS_ACCESS_VIOLATION;
@@ -616,7 +674,7 @@ NTSTATUS NTAPI NtLoadDllMemoryExW(
}
}
if (!(*BaseAddress = MemoryLoadLibrary(BufferAddress, BufferSize))) {
if (!(*BaseAddress = MemoryLoadLibrary(BufferAddress))) {
switch (GetLastError()) {
case ERROR_BAD_EXE_FORMAT:
return STATUS_INVALID_IMAGE_FORMAT;
@@ -633,7 +691,9 @@ NTSTATUS NTAPI NtLoadDllMemoryExW(
return STATUS_INVALID_ADDRESS;
}
module->loadFromNtLoadDllMemory = true;
if (dwFlags & LOAD_FLAGS_NOT_MAP_DLL) return STATUS_SUCCESS;
headers = RtlImageNtHeader(*BaseAddress);
if (headers->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_SEH)dwFlags |= LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION;
if (dwFlags & LOAD_FLAGS_NOT_MAP_DLL) return status;
status = NtMapDllMemory(*BaseAddress, dwFlags, DllName, DllFullName, &ModuleEntry);
if (!NT_SUCCESS(status)) {
@@ -647,26 +707,34 @@ NTSTATUS NTAPI NtLoadDllMemoryExW(
if (!(dwFlags & LOAD_FLAGS_NOT_USE_REFERENCE_COUNT))module->UseReferenceCount = true;
if (dwFlags & LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION)return STATUS_SUCCESS;
status = RtlInsertInvertedFunctionTable((PVOID)module->codeBase, RtlImageNtHeader(*BaseAddress)->OptionalHeader.SizeOfImage);
if (!NT_SUCCESS(status)) {
NtUnloadDllMemory(*BaseAddress);
*BaseAddress = nullptr;
if (LdrEntry)*LdrEntry = nullptr;
return status;
}
module->InsertInvertedFunctionTableEntry = true;
if (dwFlags & LOAD_FLAGS_NOT_HANDLE_TLS)return STATUS_SUCCESS;
status = LdrpHandleTlsData(ModuleEntry);
if (!NT_SUCCESS(status)) {
NtUnloadDllMemory(*BaseAddress);
*BaseAddress = nullptr;
if (LdrEntry)*LdrEntry = nullptr;
return status;
if (!(dwFlags & LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION)) {
status = RtlInsertInvertedFunctionTable((PVOID)module->codeBase, headers->OptionalHeader.SizeOfImage);
if (!NT_SUCCESS(status)) {
NtUnloadDllMemory(*BaseAddress);
*BaseAddress = nullptr;
if (LdrEntry)*LdrEntry = nullptr;
return status;
}
module->InsertInvertedFunctionTableEntry = true;
}
return STATUS_SUCCESS;
if (!(dwFlags & LOAD_FLAGS_NOT_HANDLE_TLS)) {
status = LdrpHandleTlsData(ModuleEntry);
if (!NT_SUCCESS(status)) {
do {
if (dwFlags & LOAD_FLAGS_NOT_FAIL_IF_HANDLE_TLS) {
status = 0x7fffffff;
break;
}
NtUnloadDllMemory(*BaseAddress);
*BaseAddress = nullptr;
if (LdrEntry)*LdrEntry = nullptr;
return status;
} while (false);
}
}
return status;
}
NTSTATUS NTAPI NtLoadDllMemoryExA(
@@ -705,22 +773,28 @@ NTSTATUS NTAPI NtUnloadDllMemory(IN HMEMORYMODULE BaseAddress) {
NTSTATUS status = STATUS_SUCCESS;
PMEMORYMODULE module = MapMemoryModuleHandle(BaseAddress);
//Not a memory module loaded via NtLoadDllMemory
if (!module || !module->loadFromNtLoadDllMemory)return STATUS_INVALID_HANDLE;
//Mapping dll failed
if (module->loadFromNtLoadDllMemory && !module->MappedDll) {
module->underUnload = true;
MemoryFreeLibrary(BaseAddress);
return STATUS_SUCCESS;
}
ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
ListEntry = ListHead->Flink;
while (ListEntry != ListHead) {
CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
ListEntry = ListEntry->Flink;
/* Check if it's being unloaded */
if (!CurEntry->InMemoryOrderLinks.Flink) continue;
/* Check if name matches */
if (CurEntry->DllBase == BaseAddress) {
if (RtlImageNtHeader(BaseAddress)->OptionalHeader.SizeOfImage == CurEntry->SizeOfImage) {
if (module->UseReferenceCount) {
status = NtGetReferenceCount(CurEntry, &count);
if (!NT_SUCCESS(status))return status;
}
if (!count) {
if (!(count & ~1)) {
module->underUnload = true;
if (module->MappedDll) {
if (module->InsertInvertedFunctionTableEntry) {
@@ -774,7 +848,10 @@ static VOID NTAPI RtlpInsertInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABL
if (CurrentSize != InvertedTable->MaxCount) {
//if (need)_InterlockedIncrement(&InvertedTable->Epoch);
if (CurrentSize != 0) {
while (Index < CurrentSize)if (ImageBase < InvertedTable->Entries[Index].ImageBase)break;
while (Index < CurrentSize) {
if (ImageBase < InvertedTable->Entries[Index].ImageBase)break;
++Index;
}
if (Index != CurrentSize) {
RtlMoveMemory(&InvertedTable->Entries[Index + 1],
@@ -873,13 +950,13 @@ static VOID NTAPI RtlpRemoveInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABL
#else
if (IsWin10) {
RtlMoveMemory(&InvertedTable->Entries[Index], &InvertedTable->Entries[Index + 1],
(CurrentSize - Index) * sizeof(PRTL_INVERTED_FUNCTION_TABLE_ENTRY));
(CurrentSize - Index) * sizeof(RTL_INVERTED_FUNCTION_TABLE_ENTRY));
}
else {
RtlMoveMemory(
Index ? &InvertedTable->Entries[Index - 1].NextEntrySEHandlerTableEncoded : (PVOID)&InvertedTable->NextEntrySEHandlerTableEncoded,
&InvertedTable->Entries[Index].NextEntrySEHandlerTableEncoded,
(CurrentSize - Index) * sizeof(PRTL_INVERTED_FUNCTION_TABLE_ENTRY));
(CurrentSize - Index) * sizeof(RTL_INVERTED_FUNCTION_TABLE_ENTRY));
}
#endif
}
+13 -3
View File
@@ -81,7 +81,14 @@ struct _LDR_SERVICE_TAG_RECORD {
};
//0x8 bytes (sizeof)
struct _LDRP_CSLIST {
_SINGLE_LIST_ENTRY* Tail; //0x0
struct _LDRP_CSLIST_DEPENDENT {
_SINGLE_LIST_ENTRY* NextDependentEntry; //0x0
struct _LDR_DDAG_NODE* DependentDdagNode;
}Dependent;
struct _LDRP_CSLIST_INCOMMING {
_SINGLE_LIST_ENTRY* NextIncommingEntry;
struct _LDR_DDAG_NODE* IncommingDdagNode;
}Incomming;
};
//0x4 bytes (sizeof)
enum _LDR_DDAG_STATE {
@@ -108,8 +115,8 @@ struct _LDR_DDAG_NODE {
ULONG LoadCount; //0x18
ULONG LoadWhileUnloadingCount; //0x1c
ULONG LowestLink; //0x20
_LDRP_CSLIST Dependencies; //0x28
_LDRP_CSLIST IncomingDependencies; //0x30
_LDRP_CSLIST::_LDRP_CSLIST_DEPENDENT* Dependencies; //0x28
_LDRP_CSLIST::_LDRP_CSLIST_INCOMMING* IncomingDependencies; //0x30
_LDR_DDAG_STATE State; //0x38
_SINGLE_LIST_ENTRY CondenseLink; //0x40
ULONG PreorderNumber; //0x48
@@ -398,6 +405,9 @@ NTSTATUS NTAPI NtLoadDllMemory(
//Also, will be incompatible with Win32 API.
#define LOAD_FLAGS_NOT_MAP_DLL 0x10000000
//If this flag is specified, this routine will not fail even if the call to LdrpTlsData fails.
#define LOAD_FLAGS_NOT_FAIL_IF_HANDLE_TLS 0x20000000
//If this flag is specified, exception handling will not be supported.
#define LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION 0x00000001
+10
View File
@@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MemoryModule", "MemoryModul
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcxproj", "{5B3131BA-178A-4A28-BD54-315A45C97ED1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "a", "a\a.vcxproj", "{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -33,6 +35,14 @@ Global
{5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x64.Build.0 = Release|x64
{5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x86.ActiveCfg = Release|Win32
{5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x86.Build.0 = Release|Win32
{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x64.ActiveCfg = Debug|x64
{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x64.Build.0 = Debug|x64
{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x86.ActiveCfg = Debug|Win32
{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x86.Build.0 = Debug|Win32
{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x64.ActiveCfg = Release|x64
{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x64.Build.0 = Release|x64
{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x86.ActiveCfg = Release|Win32
{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+3 -3
View File
@@ -9,12 +9,12 @@ MemoryModulePP, used to load a DLL from memory. MemoryModulePP is compatible wit
**This repository is under development.**
## New Features
- Compatible with Win7(x86)
- Support Win10 forward export
## Features
- Compatible with Win32 API (GetModuleHandleA/W/Ex GetModuleFileNameA/W/Ex GetProcAddress and any Resource API)
- Support for C ++ exceptions and SEH
- Compatible with Win7(x64) and Win10(x64)
- Support for C++ exceptions and SEH
- Compatible with Win7 and Win10
- Optimized MEMORYMODULE structure
- Use reference counting, repeated loading of the same module will update the reference counting, please refer to NtLoadDllMemoryExW
- The above features can be turned off through the dwFlags parameter of NtLoadDllMemoryExW
+72
View File
@@ -0,0 +1,72 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Chinese (Simplified, PRC) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_STRING101 "aabbccdd"
END
#endif // Chinese (Simplified, PRC) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
+186
View File
@@ -0,0 +1,186 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>a</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;A_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeaderOutputFile />
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>m.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;A_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile />
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>m.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;A_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeaderOutputFile />
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>m.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;A_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ExceptionHandling>Sync</ExceptionHandling>
<PrecompiledHeaderOutputFile />
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>m.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\MemoryModule\Native.cpp" />
<ClCompile Include="dllmain.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="a.rc" />
</ItemGroup>
<ItemGroup>
<None Include="m.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+40
View File
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<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">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="a.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="m.def">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
</Project>
+101
View File
@@ -0,0 +1,101 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include <cstdio>
#include <exception>
#include "../MemoryModule/Native.h"
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"wintrust.lib")
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
printf("DLL_PROCESS_ATTACH\n"); break;
case DLL_THREAD_ATTACH:
printf("DLL_THREAD_ATTACH\n"); break;
case DLL_THREAD_DETACH:
printf("DLL_THREAD_DETACH\n"); break;
case DLL_PROCESS_DETACH:
printf("DLL_PROCESS_DETACH\n"); break;
}
return TRUE;
}
/*
exception type
0 int
1 char
2 std::exception
... DWORD64
*/
int exception(int exception_type) {
//int a = 0;
//__try {
// *(PDWORD)(nullptr) = -1;
// a = 2;
//}
//__except (EXCEPTION_EXECUTE_HANDLER) {
// printf("-----------\n");
// getchar();
// a = 1;
//}
try {
switch (exception_type) {
case 0:
throw 0;
case 1:
throw '1';
case 2:
throw std::exception("2");
default:
throw (DWORD64)-1;
}
return 0;
}
catch (int val) {
printf("exception code = %d\n", val);
return val;
}
catch (char val) {
printf("exception code = %c\n", val);
return val - '0';
}
catch (std::exception val) {
printf("exception code = %s\n", val.what());
return 2;
}
catch (...) {
printf("exception catched!!\n");
return 0;
}
//return a;
}
int __test__() {
printf("HelloWorld!\n");
return 0;
}
static thread_local int x = 0xffccffdd;
DWORD WINAPI Thread(PVOID) {
printf("[1] ThreadLocalStoragePointer = %p\n", NtCurrentTeb()->ThreadLocalStoragePointer);
return x == 0xffccffdd ? 0 : 1; const auto i = offsetof(CONTEXT, Dr0);
}
int thread() {
x = 2;
printf("[0] ThreadLocalStoragePointer = %p\n", NtCurrentTeb()->ThreadLocalStoragePointer);
HANDLE hThread = CreateThread(nullptr, 0, Thread, nullptr, 0, nullptr);
DWORD ret = -1;
if (hThread) {
WaitForSingleObject(hThread, 0xffffffff);
GetExitCodeThread(hThread, &ret);
CloseHandle(hThread);
return ret;
}
return -1;
}
+6
View File
@@ -0,0 +1,6 @@
EXPORTS
exception
test = __test__
thread
Socket = ws2_32.WSASocketW
VerifyTruse = wintrust.WinVerifyTrust
+16
View File
@@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by a.rc
//
#define IDS_STRING101 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
+22 -59
View File
@@ -5,7 +5,16 @@
#endif
#include <cstdio>
#pragma warning(disable:4996)
PLDR_DATA_TABLE_ENTRY_WIN10_2 RtlFindDllLdrEntry(LPCWSTR DllName) {
PLIST_ENTRY head = &NtCurrentPeb()->Ldr->InMemoryOrderModuleList, entry = head->Flink;
PLDR_DATA_TABLE_ENTRY_WIN10_2 cur = nullptr;
while (entry != head) {
cur = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY_WIN10_2, InMemoryOrderLinks);
entry = entry->Flink;
if (!wcsicmp(DllName, cur->BaseDllName.Buffer))return cur;
}
return nullptr;
}
int main() {
LPVOID buffer;
size_t size;
@@ -19,71 +28,25 @@ int main() {
_fseeki64(f, 0, SEEK_SET);
fread(buffer = new char[size], 1, size, f);
fclose(f);
HMEMORYMODULE m1 = nullptr, m2 = m1, _m1 = m1;
char name[MAX_PATH]{};
HMEMORYMODULE m1 = nullptr, m2 = m1;
HMODULE hModule = nullptr;
FARPROC test = nullptr;
typedef int(*_exception)(int type);
_exception exception = nullptr;
PWSTR t;
DWORD tableSize;
DWORD offset = 0, index = 0;
HRSRC res;
HGLOBAL hRes;
PWSTR str;
FARPROC pfn = nullptr;
if (!NT_SUCCESS(NtLoadDllMemoryExW(&m1, nullptr, 0, buffer, size, L"kernel64", nullptr))) goto end;
//if (!NT_SUCCESS(NtLoadDllMemoryExW(&_m1, nullptr, 0, buffer, size, L"kernel64.dll", nullptr))) goto end;
//if (!NT_SUCCESS(NtLoadDllMemoryExW(&m2, nullptr, 0, buffer, size, L"kernel128.dll", L"\\?\\kernel512.dll"))) goto end;
//Load string using FindResource
if (!NT_SUCCESS(NtLoadDllMemoryExW(&m2, nullptr, 0, buffer, size, L"kernel128", nullptr))) goto end;
hModule = (HMODULE)m1;
//if (!(res = FindResourceW(hModule, MAKEINTRESOURCEW((101 >> 4) + 1), MAKEINTRESOURCEW(6))))goto end;
//if (!(hRes = LoadResource(hModule, res)))goto end;
//if (!(t = (PWSTR)LockResource(hRes)))goto end;
//tableSize = SizeofResource(hModule, res);
//while (offset < tableSize) {
// if (index == 101 % 0x10) {
// if (t[offset] != 0x0000) {
// str = &t[offset + 1];
// wprintf(L"Size = %d, String = %s\n", t[offset], str);
// }
// break;
// }
// offset += t[offset] + 1;
// index++;
//}
//
//hModule = GetModuleHandleA("kernel64.dll");
//GetModuleFileNameA(hModule, name, MAX_PATH);
//if (hModule)test = GetProcAddress(hModule, "thread");
//printf("m1:\n\tHMEMORYMODULE\t= 0x%p\n\tHMODULE\t\t= 0x%p\n\tModuleFileName\t= %s\n\ttest\t\t= 0x%p\n\n", m1, hModule, name, test);
//if (test) test();
//GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)test, &hModule);
//GetModuleFileNameA(hModule, name, MAX_PATH);
//test = GetProcAddress(hModule, "test");
//printf("_m1:\n\tHMEMORYMODULE\t= 0x%p\n\tHMODULE\t\t= 0x%p\n\tModuleFileName\t= %s\n\ttest\t\t= 0x%p\n\n", _m1, hModule, name, test);
//if (test)test();
//hModule = GetModuleHandleA("kernel128");
//GetModuleFileNameA(hModule, name, MAX_PATH);
if (hModule)exception = (_exception)GetProcAddress(hModule, "exception");
//printf("m2:\n\tHMEMORYMODULE\t= 0x%p\n\tHMODULE\t\t= 0x%p\n\tModuleFileName\t= %s\n\ttest\t\t= 0x%p\n\n", m2, hModule, name, test);
if (exception) {
DebugBreak();
exception(0);
exception(1);
exception(2);
exception(3);
}
pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); //ws2_32.WSASocketW
pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse")); //wintrust.WinVerifyTrust
hModule = (HMODULE)m2;
pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket"));
pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse"));
printf("pfn = %p\n", pfn);
end:
delete[]buffer;
if (m1)NtUnloadDllMemory(m1);
//if (_m1)NtUnloadDllMemory(_m1);
//if (m2)NtUnloadDllMemory(m2);
if (m2)NtUnloadDllMemory(m2);
return 0;
}