|
|
|
#include "Hvax64.h"
|
|
|
|
|
|
|
|
VOID* MapModule(PVOYAGER_T VoyagerData, UINT8* ImageBase)
|
|
|
|
{
|
|
|
|
if (!VoyagerData || !ImageBase)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
EFI_IMAGE_DOS_HEADER* dosHeaders = (EFI_IMAGE_DOS_HEADER*)ImageBase;
|
|
|
|
if (dosHeaders->e_magic != EFI_IMAGE_DOS_SIGNATURE)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
EFI_IMAGE_NT_HEADERS64* ntHeaders = (EFI_IMAGE_NT_HEADERS64*)(ImageBase + dosHeaders->e_lfanew);
|
|
|
|
if (ntHeaders->Signature != EFI_IMAGE_NT_SIGNATURE)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
// Map headers (no reason not too here, memory is unaccessable from guest lol)
|
|
|
|
MemCopy(VoyagerData->ModuleBase, ImageBase, ntHeaders->OptionalHeader.SizeOfHeaders);
|
|
|
|
|
|
|
|
// Map sections
|
|
|
|
EFI_IMAGE_SECTION_HEADER* sections = (EFI_IMAGE_SECTION_HEADER*)((UINT8*)&ntHeaders->OptionalHeader + ntHeaders->FileHeader.SizeOfOptionalHeader);
|
|
|
|
for (UINT32 i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i)
|
|
|
|
{
|
|
|
|
EFI_IMAGE_SECTION_HEADER* section = §ions[i];
|
|
|
|
if (section->SizeOfRawData)
|
|
|
|
{
|
|
|
|
MemCopy
|
|
|
|
(
|
|
|
|
VoyagerData->ModuleBase + section->VirtualAddress,
|
|
|
|
ImageBase + section->PointerToRawData,
|
|
|
|
section->SizeOfRawData
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set exported pointer to voyager context...
|
|
|
|
EFI_IMAGE_EXPORT_DIRECTORY* ExportDir = (EFI_IMAGE_EXPORT_DIRECTORY*)(
|
|
|
|
VoyagerData->ModuleBase + ntHeaders->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
|
|
|
|
|
|
|
UINT32* Address = (UINT32*)(VoyagerData->ModuleBase + ExportDir->AddressOfFunctions);
|
|
|
|
UINT32* Name = (UINT32*)(VoyagerData->ModuleBase + ExportDir->AddressOfNames);
|
|
|
|
UINT16* Ordinal = (UINT16*)(VoyagerData->ModuleBase + ExportDir->AddressOfNameOrdinals);
|
|
|
|
|
|
|
|
for (UINT16 i = 0; i < ExportDir->AddressOfFunctions; i++)
|
|
|
|
{
|
|
|
|
if (AsciiStrStr(VoyagerData->ModuleBase + Name[i], "voyager_context"))
|
|
|
|
{
|
|
|
|
*(VOYAGER_T*)(VoyagerData->ModuleBase + Address[Ordinal[i]]) = *VoyagerData;
|
|
|
|
break; // DO NOT REMOVE? #Stink Code 2020...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Resolve relocations
|
|
|
|
EFI_IMAGE_DATA_DIRECTORY* baseRelocDir = &ntHeaders->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
|
|
|
if (baseRelocDir->VirtualAddress)
|
|
|
|
{
|
|
|
|
EFI_IMAGE_BASE_RELOCATION* reloc = (EFI_IMAGE_BASE_RELOCATION*)(VoyagerData->ModuleBase + baseRelocDir->VirtualAddress);
|
|
|
|
for (UINT32 currentSize = 0; currentSize < baseRelocDir->Size; )
|
|
|
|
{
|
|
|
|
UINT32 relocCount = (reloc->SizeOfBlock - sizeof(EFI_IMAGE_BASE_RELOCATION)) / sizeof(UINT16);
|
|
|
|
UINT16* relocData = (UINT16*)((UINT8*)reloc + sizeof(EFI_IMAGE_BASE_RELOCATION));
|
|
|
|
UINT8* relocBase = VoyagerData->ModuleBase + reloc->VirtualAddress;
|
|
|
|
|
|
|
|
for (UINT32 i = 0; i < relocCount; ++i, ++relocData)
|
|
|
|
{
|
|
|
|
UINT16 data = *relocData;
|
|
|
|
UINT16 type = data >> 12;
|
|
|
|
UINT16 offset = data & 0xFFF;
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
|
|
|
break;
|
|
|
|
case EFI_IMAGE_REL_BASED_DIR64:
|
|
|
|
{
|
|
|
|
UINT64* rva = (UINT64*)(relocBase + offset);
|
|
|
|
*rva = (UINT64)(VoyagerData->ModuleBase + (*rva - ntHeaders->OptionalHeader.ImageBase));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
currentSize += reloc->SizeOfBlock;
|
|
|
|
reloc = (EFI_IMAGE_BASE_RELOCATION*)relocData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return VoyagerData->ModuleBase + ntHeaders->OptionalHeader.AddressOfEntryPoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID MakeVoyagerData
|
|
|
|
(
|
|
|
|
PVOYAGER_T VoyagerData,
|
|
|
|
VOID* HypervAlloc,
|
|
|
|
UINT64 HypervAllocSize,
|
|
|
|
VOID* PayLoadBase,
|
|
|
|
UINT64 PayLoadSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
VoyagerData->HypervModuleBase = HypervAlloc;
|
|
|
|
VoyagerData->HypervModuleSize = HypervAllocSize;
|
|
|
|
VoyagerData->ModuleBase = PayLoadBase;
|
|
|
|
VoyagerData->ModuleSize = PayLoadSize;
|
|
|
|
|
|
|
|
VOID* VCpuRunCall =
|
|
|
|
FindPattern(
|
|
|
|
HypervAlloc,
|
|
|
|
HypervAllocSize,
|
|
|
|
VCPU_RUN_HANDLER_SIG,
|
|
|
|
VCPU_RUN_HANDLER_MASK
|
|
|
|
);
|
|
|
|
|
|
|
|
UINT64 VCpuRunCallRip = (UINT64)VCpuRunCall + 5; // + 5 bytes because "call vmexit_c_handler" is 5 bytes
|
|
|
|
UINT64 VCpuRunFunction = VCpuRunCallRip + *(INT32*)((UINT64)VCpuRunCall + 1); // + 1 to skip E8 (call) and read 4 bytes (RVA)
|
|
|
|
VoyagerData->VCpuRunHandlerRVA = ((UINT64)PayLoadEntry(PayLoadBase)) - VCpuRunFunction;
|
|
|
|
|
|
|
|
DBG_PRINT("VCpuRunCall -> 0x%p\n", VCpuRunCall);
|
|
|
|
DBG_PRINT("VCpuRunCallRip -> 0x%p\n", VCpuRunCallRip);
|
|
|
|
DBG_PRINT("VCpuRunFunction -> 0x%p\n", VCpuRunFunction);
|
|
|
|
DBG_PRINT("VoyagerData->VCpuRunHandlerRVA -> 0x%p\n", VoyagerData->VCpuRunHandlerRVA);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID* HookVCpuRun(VOID* HypervBase, VOID* HypervSize, VOID* VCpuRunHook)
|
|
|
|
{
|
|
|
|
VOID* VCpuRunCall =
|
|
|
|
FindPattern(
|
|
|
|
HypervBase,
|
|
|
|
HypervSize,
|
|
|
|
VCPU_RUN_HANDLER_SIG,
|
|
|
|
VCPU_RUN_HANDLER_MASK
|
|
|
|
);
|
|
|
|
|
|
|
|
UINT64 VCpuRunCallRip = ((UINT64)VCpuRunCall) + 5; // + 5 bytes to next instructions address...
|
|
|
|
UINT64 VCpuRunFunction = VCpuRunCallRip + *(INT32*)(((UINT64)VCpuRunCall) + 1); // + 1 to skip E8 (call) and read 4 bytes (RVA)
|
|
|
|
INT32 NewVCpuRunRVA = ((INT64)VCpuRunHook) - VCpuRunCallRip;
|
|
|
|
*(INT32*)((UINT64)VCpuRunCall + 1) = NewVCpuRunRVA;
|
|
|
|
|
|
|
|
DBG_PRINT("VCpuRunCall -> 0x%p\n", VCpuRunCall);
|
|
|
|
DBG_PRINT("VCpuRunCallRip -> 0x%p\n", VCpuRunCallRip);
|
|
|
|
DBG_PRINT("VCpuRunFunction -> 0x%p\n", VCpuRunFunction);
|
|
|
|
DBG_PRINT("NewVCpuRunRVA -> 0x%p\n", NewVCpuRunRVA);
|
|
|
|
return VCpuRunFunction;
|
|
|
|
}
|