HyperDbg/hyperdbg/hyperhv/code/memory/Conversion.c
2024-06-24 18:05:54 +09:00

293 lines
6.8 KiB
C

/**
* @file Conversion.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Functions for memory conversions
*
* @version 0.2
* @date 2023-04-27
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
/**
* @brief Converts Physical Address to Virtual Address
*
* @param PhysicalAddress The target physical address
* @return UINT64 Returns the virtual address
*/
_Use_decl_annotations_
UINT64
PhysicalAddressToVirtualAddress(UINT64 PhysicalAddress)
{
PHYSICAL_ADDRESS PhysicalAddr;
PhysicalAddr.QuadPart = PhysicalAddress;
return (UINT64)MmGetVirtualForPhysical(PhysicalAddr);
}
/**
* @brief Converts Physical Address to Virtual Address based
* on a specific process id
*
* @details this function should NOT be called from vmx-root mode
*
* @param PhysicalAddress The target physical address
* @param ProcessId The target's process id
* @return UINT64 Returns the virtual address
*/
_Use_decl_annotations_
UINT64
PhysicalAddressToVirtualAddressByProcessId(PVOID PhysicalAddress, UINT32 ProcessId)
{
CR3_TYPE CurrentProcessCr3;
UINT64 VirtualAddress;
PHYSICAL_ADDRESS PhysicalAddr;
//
// Switch to new process's memory layout
//
CurrentProcessCr3 = SwitchToProcessMemoryLayout(ProcessId);
//
// Validate if process id is valid
//
if (CurrentProcessCr3.Flags == NULL64_ZERO)
{
//
// Pid is invalid
//
return NULL64_ZERO;
}
//
// Read the virtual address based on new cr3
//
PhysicalAddr.QuadPart = (LONGLONG)PhysicalAddress;
VirtualAddress = (UINT64)MmGetVirtualForPhysical(PhysicalAddr);
//
// Restore the original process
//
SwitchToPreviousProcess(CurrentProcessCr3);
return VirtualAddress;
}
/**
* @brief Converts Physical Address to Virtual Address based
* on a specific process's kernel cr3
*
* @details this function should NOT be called from vmx-root mode
*
* @param PhysicalAddress The target physical address
* @param TargetCr3 The target's process cr3
* @return UINT64 Returns the virtual address
*/
_Use_decl_annotations_
UINT64
PhysicalAddressToVirtualAddressByCr3(PVOID PhysicalAddress, CR3_TYPE TargetCr3)
{
CR3_TYPE CurrentProcessCr3;
UINT64 VirtualAddress;
PHYSICAL_ADDRESS PhysicalAddr;
//
// Switch to new process's memory layout
//
CurrentProcessCr3 = SwitchToProcessMemoryLayoutByCr3(TargetCr3);
//
// Validate if process id is valid
//
if (CurrentProcessCr3.Flags == NULL64_ZERO)
{
//
// Pid is invalid
//
return NULL64_ZERO;
}
//
// Read the virtual address based on new cr3
//
PhysicalAddr.QuadPart = (LONGLONG)PhysicalAddress;
VirtualAddress = (UINT64)MmGetVirtualForPhysical(PhysicalAddr);
//
// Restore the original process
//
SwitchToPreviousProcess(CurrentProcessCr3);
return VirtualAddress;
}
/**
* @brief Converts Physical Address to Virtual Address based
* on current process's kernel cr3
*
* @details this function should NOT be called from vmx-root mode
*
* @param PhysicalAddress The target physical address
* @return UINT64 Returns the virtual address
*/
_Use_decl_annotations_
UINT64
PhysicalAddressToVirtualAddressOnTargetProcess(PVOID PhysicalAddress)
{
CR3_TYPE GuestCr3;
GuestCr3.Flags = LayoutGetCurrentProcessCr3().Flags;
return PhysicalAddressToVirtualAddressByCr3(PhysicalAddress, GuestCr3);
}
/**
* @brief Converts Virtual Address to Physical Address
*
* @param VirtualAddress The target virtual address
* @return UINT64 Returns the physical address
*/
_Use_decl_annotations_
UINT64
VirtualAddressToPhysicalAddress(_In_ PVOID VirtualAddress)
{
return MmGetPhysicalAddress(VirtualAddress).QuadPart;
}
/**
* @brief Converts Virtual Address to Physical Address based
* on a specific process id's kernel cr3
*
* @details this function should NOT be called from vmx-root mode
*
* @param VirtualAddress The target virtual address
* @param ProcessId The target's process id
* @return UINT64 Returns the physical address
*/
_Use_decl_annotations_
UINT64
VirtualAddressToPhysicalAddressByProcessId(PVOID VirtualAddress, UINT32 ProcessId)
{
CR3_TYPE CurrentProcessCr3;
UINT64 PhysicalAddress;
//
// Switch to new process's memory layout
//
CurrentProcessCr3 = SwitchToProcessMemoryLayout(ProcessId);
//
// Validate if process id is valid
//
if (CurrentProcessCr3.Flags == NULL64_ZERO)
{
//
// Pid is invalid
//
return NULL64_ZERO;
}
//
// Read the physical address based on new cr3
//
PhysicalAddress = MmGetPhysicalAddress(VirtualAddress).QuadPart;
//
// Restore the original process
//
SwitchToPreviousProcess(CurrentProcessCr3);
return PhysicalAddress;
}
/**
* @brief Converts Virtual Address to Physical Address based
* on a specific process's kernel cr3
*
* @param VirtualAddress The target virtual address
* @param TargetCr3 The target's process cr3
* @return UINT64 Returns the physical address
*/
_Use_decl_annotations_
UINT64
VirtualAddressToPhysicalAddressByProcessCr3(PVOID VirtualAddress, CR3_TYPE TargetCr3)
{
CR3_TYPE CurrentProcessCr3;
UINT64 PhysicalAddress;
//
// Switch to new process's memory layout
//
CurrentProcessCr3 = SwitchToProcessMemoryLayoutByCr3(TargetCr3);
//
// Validate if process id is valid
//
if (CurrentProcessCr3.Flags == NULL64_ZERO)
{
//
// Pid is invalid
//
return NULL64_ZERO;
}
//
// Read the physical address based on new cr3
//
PhysicalAddress = MmGetPhysicalAddress(VirtualAddress).QuadPart;
//
// Restore the original process
//
SwitchToPreviousProcess(CurrentProcessCr3);
return PhysicalAddress;
}
/**
* @brief Converts Virtual Address to Physical Address based
* on the current process's kernel cr3
*
* @param VirtualAddress The target virtual address
* @return UINT64 Returns the physical address
*/
_Use_decl_annotations_
UINT64
VirtualAddressToPhysicalAddressOnTargetProcess(PVOID VirtualAddress)
{
CR3_TYPE CurrentCr3;
CR3_TYPE GuestCr3;
UINT64 PhysicalAddress;
GuestCr3.Flags = LayoutGetCurrentProcessCr3().Flags;
//
// Switch to new process's memory layout
//
CurrentCr3 = SwitchToProcessMemoryLayoutByCr3(GuestCr3);
//
// Validate if process id is valid
//
if (CurrentCr3.Flags == NULL64_ZERO)
{
//
// Pid is invalid
//
return NULL64_ZERO;
}
//
// Read the physical address based on new cr3
//
PhysicalAddress = MmGetPhysicalAddress(VirtualAddress).QuadPart;
//
// Restore the original process
//
SwitchToPreviousProcess(CurrentCr3);
return PhysicalAddress;
}