HyperDbg/hyperdbg/hyperhv/header/memory/MemoryMapper.h

210 lines
7 KiB
C

/**
* @file MemoryMapper.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief This file shows the header functions to map memory to reserved system ranges
*
* also some of the functions derived from hvpp
* - https://github.com/wbenny/hvpp
*
* @version 0.1
* @date 2020-05-3
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#pragma once
//////////////////////////////////////////////////
// Definitions //
//////////////////////////////////////////////////
#define PAGE_4KB_OFFSET ((UINT64)(1 << 12) - 1)
#define PAGE_2MB_OFFSET ((UINT64)(1 << 21) - 1)
#define PAGE_4MB_OFFSET ((UINT64)(1 << 22) - 1)
#define PAGE_1GB_OFFSET ((UINT64)(1 << 30) - 1)
//////////////////////////////////////////////////
// Enums //
//////////////////////////////////////////////////
/**
* @brief Memory wrapper for reading safe from the memory
*
*/
typedef enum _MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ
{
MEMORY_MAPPER_WRAPPER_READ_PHYSICAL_MEMORY,
MEMORY_MAPPER_WRAPPER_READ_VIRTUAL_MEMORY,
MEMORY_MAPPER_WRAPPER_READ_VIRTUAL_MEMORY_UNSAFE
} MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ;
/**
* @brief Memory wrapper for writing safe into the memory
*
*/
typedef enum _MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE
{
MEMORY_MAPPER_WRAPPER_WRITE_PHYSICAL_MEMORY,
MEMORY_MAPPER_WRAPPER_WRITE_VIRTUAL_MEMORY_SAFE,
MEMORY_MAPPER_WRAPPER_WRITE_VIRTUAL_MEMORY_UNSAFE
} MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE;
//////////////////////////////////////////////////
// Structures //
//////////////////////////////////////////////////
/**
* @brief Page Entries
*
*/
typedef struct _PAGE_ENTRY
{
union
{
UINT64 Flags;
PML4E_64 Pml4;
PDPTE_1GB_64 PdptLarge; // 1GB
PDPTE_64 Pdpt;
PDE_2MB_64 PdLarge; // 2MB
PDE_64 Pd;
PTE_64 Pt;
//
// Common fields.
//
struct
{
UINT64 Present : 1;
UINT64 Write : 1;
UINT64 Supervisor : 1;
UINT64 PageLevelWriteThrough : 1;
UINT64 PageLevelCacheDisable : 1;
UINT64 Accessed : 1;
UINT64 Dirty : 1;
UINT64 LargePage : 1;
UINT64 Global : 1;
UINT64 Ignored1 : 3;
UINT64 PageFrameNumber : 36;
UINT64 Reserved1 : 4;
UINT64 Ignored2 : 7;
UINT64 ProtectionKey : 4;
UINT64 ExecuteDisable : 1;
} Fields;
};
} PAGE_ENTRY, *PPAGE_ENTRY;
/**
* @brief Memory mapper PTE and reserved virtual address
* @details Memory mapper details for each core, contains PTE Virtual Address, Actual Kernel Virtual Address
*/
typedef struct _MEMORY_MAPPER_ADDRESSES
{
UINT64 PteVirtualAddressForRead; // The virtual address of PTE for read operations
UINT64 VirualAddressForRead; // The actual kernel virtual address to read
UINT64 PteVirtualAddressForWrite; // The virtual address of PTE for write operations
UINT64 VirualAddressForWrite; // The actual kernel virtual address to write
} MEMORY_MAPPER_ADDRESSES, *PMEMORY_MAPPER_ADDRESSES;
//////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// Private Interfaces
//
static UINT64
MemoryMapperGetIndex(_In_ PAGING_LEVEL Level,
_In_ UINT64 Va);
static UINT32
MemoryMapperGetOffset(_In_ PAGING_LEVEL Level,
_In_ UINT64 Va);
static BOOLEAN
MemoryMapperCheckIfPageIsNxBitSetByCr3(_In_ PVOID Va,
_In_ CR3_TYPE TargetCr3);
static PVOID
MemoryMapperMapReservedPageRange(_In_ SIZE_T Size);
static VOID
MemoryMapperUnmapReservedPageRange(_In_ PVOID VirtualAddress);
static PVOID
MemoryMapperGetPte(_In_ PVOID VirtualAddress);
static PVOID
MemoryMapperGetPteByCr3(_In_ PVOID VirtualAddress,
_In_ CR3_TYPE TargetCr3);
static PVOID
MemoryMapperMapPageAndGetPte(_Out_ PUINT64 PteAddress);
static BOOLEAN
MemoryMapperReadMemorySafeByPte(_In_ PHYSICAL_ADDRESS PaAddressToRead,
_Inout_ PVOID BufferToSaveMemory,
_In_ SIZE_T SizeToRead,
_In_ UINT64 PteVaAddress,
_In_ UINT64 MappingVa,
_In_ BOOLEAN InvalidateVpids);
static BOOLEAN
MemoryMapperWriteMemorySafeByPte(_In_ PVOID SourceVA,
_In_ PHYSICAL_ADDRESS PaAddressToWrite,
_In_ SIZE_T SizeToWrite,
_Inout_ UINT64 PteVaAddress,
_Inout_ UINT64 MappingVa,
_In_ BOOLEAN InvalidateVpids);
static UINT64
MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker(
_In_ MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead,
_In_ UINT64 AddressToRead,
_In_ UINT32 TargetProcessId);
static BOOLEAN
MemoryMapperReadMemorySafeWrapper(
_In_ MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead,
_In_ UINT64 AddressToRead,
_Inout_ UINT64 BufferToSaveMemory,
_In_ SIZE_T SizeToRead,
_In_ UINT32 TargetProcessId);
static UINT64
MemoryMapperWriteMemorySafeWrapperAddressMaker(_In_ MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE TypeOfWrite,
_In_ UINT64 DestinationAddr,
_In_opt_ PCR3_TYPE TargetProcessCr3,
_In_opt_ UINT32 TargetProcessId);
static BOOLEAN
MemoryMapperWriteMemorySafeWrapper(_In_ MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE TypeOfWrite,
_Inout_ UINT64 DestinationAddr,
_In_ UINT64 Source,
_In_ SIZE_T SizeToWrite,
_In_opt_ PCR3_TYPE TargetProcessCr3,
_In_opt_ UINT32 TargetProcessId);
// ----------------------------------------------------------------------------
// Public Interfaces
//
VOID
MemoryMapperInitialize();
VOID
MemoryMapperUninitialize();
BOOLEAN
MemoryMapperCheckIfPageIsPresentByCr3(_In_ PVOID Va,
_In_ CR3_TYPE TargetCr3);
VOID
MemoryMapperMapPhysicalAddressToPte(_In_ PHYSICAL_ADDRESS PhysicalAddress,
_In_ PVOID TargetProcessVirtualAddress,
_In_ CR3_TYPE TargetProcessKernelCr3);