vxug-VXAPI/VX-API/MpfExecutePeBinaryInMemoryF...

118 lines
4.4 KiB
C++

#include "Win32Helper.h"
BOOL UnusedSubroutineRepair64bitImportAddressTable(PBYTE ExecutableMemoryBaseAddress)
{
PIMAGE_DOS_HEADER DosHeader = NULL;
PIMAGE_NT_HEADERS NtHeader = NULL;
PIMAGE_FILE_HEADER FileHeader = NULL;
PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
PIMAGE_DATA_DIRECTORY ImportAddressTable = NULL;
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor = NULL;
if (!RtlLoadPeHeaders(&DosHeader, &NtHeader, &FileHeader, &OptionalHeader, &ExecutableMemoryBaseAddress))
return FALSE;
ImportAddressTable = &OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
if (ImportAddressTable == NULL)
return FALSE;
for (ULONGLONG Size = 0; Size < ImportAddressTable->Size; Size += sizeof(IMAGE_IMPORT_DESCRIPTOR))
{
LPSTR LibraryString = NULL;
HMODULE hModule = NULL;
ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(ImportAddressTable->VirtualAddress + Size + (ULONG_PTR)ExecutableMemoryBaseAddress);
if (ImportDescriptor->OriginalFirstThunk == NULL && ImportDescriptor->FirstThunk == NULL)
break;
LibraryString = (LPSTR)((ULONGLONG)ExecutableMemoryBaseAddress + ImportDescriptor->Name);
hModule = LoadLibraryA(LibraryString);
for(ULONGLONG OffsetField = ERROR_SUCCESS, OffsetThunk = ERROR_SUCCESS;;)
{
PIMAGE_THUNK_DATA FieldThunk = (PIMAGE_THUNK_DATA)(ULONGLONG(ExecutableMemoryBaseAddress) + OffsetField + ImportDescriptor->FirstThunk);
PIMAGE_THUNK_DATA OriginalThunk = (PIMAGE_THUNK_DATA)(ULONGLONG(ExecutableMemoryBaseAddress) + OffsetThunk + (ImportDescriptor->OriginalFirstThunk == NULL ? ImportDescriptor->FirstThunk : ImportDescriptor->OriginalFirstThunk));
if (OriginalThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32 || OriginalThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
{
if (hModule != NULL)
FieldThunk->u1.Function = (ULONGLONG)GetProcAddressA((DWORD64)hModule, (PCHAR)(OriginalThunk->u1.Ordinal & 0xFFFF));
}
if (FieldThunk->u1.Function == NULL)
{
if (hModule != NULL)
FreeLibrary(hModule);
break;
}
if (FieldThunk->u1.Function == OriginalThunk->u1.Function)
{
PIMAGE_IMPORT_BY_NAME ImportNameString = (PIMAGE_IMPORT_BY_NAME)(ULONGLONG(ExecutableMemoryBaseAddress) + OriginalThunk->u1.AddressOfData);
if (ImportNameString != NULL)
{
if(hModule != NULL)
FieldThunk->u1.Function = (ULONGLONG)GetProcAddress(hModule, ImportNameString->Name); //GetProcAddressA has fatal error...
}
}
OffsetField += sizeof(IMAGE_THUNK_DATA);
OffsetThunk += sizeof(IMAGE_THUNK_DATA);
}
if (hModule != NULL)
FreeLibrary(hModule);
}
return TRUE;
}
DWORD MpfExecute64bitPeBinaryInMemoryFromByteArrayNoReloc(_In_ PBYTE BinaryImage)
{
PIMAGE_DOS_HEADER DosHeader = NULL;
PIMAGE_NT_HEADERS NtHeader = NULL;
PIMAGE_FILE_HEADER FileHeader = NULL;
PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
PIMAGE_DATA_DIRECTORY RelocationDirectory = NULL;
PIMAGE_SECTION_HEADER SectionHeaderArray = NULL;
PBYTE ExecutableMemoryBaseAddress = NULL;
DWORD dwError = ERROR_SUCCESS;
BOOL bFlag = FALSE;
ULONGLONG ExecutionPointer = ERROR_SUCCESS;
if (!RtlLoadPeHeaders(&DosHeader, &NtHeader, &FileHeader, &OptionalHeader, &BinaryImage))
return -1;
ExecutableMemoryBaseAddress = (PBYTE)VirtualAlloc((LPVOID)OptionalHeader->ImageBase, OptionalHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!ExecutableMemoryBaseAddress)
{
ExecutableMemoryBaseAddress = (PBYTE)VirtualAlloc(NULL, OptionalHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!ExecutableMemoryBaseAddress)
return -1;
}
OptionalHeader->ImageBase = (ULONGLONG)ExecutableMemoryBaseAddress;
CopyMemoryEx(ExecutableMemoryBaseAddress, BinaryImage, OptionalHeader->SizeOfHeaders);
SectionHeaderArray = (PIMAGE_SECTION_HEADER)(ULONGLONG(NtHeader) + sizeof(IMAGE_NT_HEADERS));
for (DWORD dwX = 0; dwX < FileHeader->NumberOfSections; dwX++)
{
CopyMemoryEx(LPVOID(ULONGLONG(ExecutableMemoryBaseAddress) + SectionHeaderArray[dwX].VirtualAddress), LPVOID(ULONGLONG(BinaryImage) + SectionHeaderArray[dwX].PointerToRawData), SectionHeaderArray[dwX].SizeOfRawData);
}
if (!UnusedSubroutineRepair64bitImportAddressTable(ExecutableMemoryBaseAddress))
goto EXIT_ROUTINE;
ExecutionPointer = (ULONGLONG)(ExecutableMemoryBaseAddress) + OptionalHeader->AddressOfEntryPoint;
((VOID(*)())ExecutionPointer)();
bFlag = TRUE;
EXIT_ROUTINE:
if (!bFlag)
VirtualFree(ExecutableMemoryBaseAddress, 0, MEM_RELEASE);
return dwError;
}