HyperDbg Debugger
Loading...
Searching...
No Matches
MemoryMapper.c File Reference

This file shows the functions to map memory to reserved system ranges. More...

#include "pch.h"

Functions

_Use_decl_annotations_ UINT64 MemoryMapperGetIndex (PAGING_LEVEL Level, UINT64 Va)
 Get Index of VA on PMLx.
_Use_decl_annotations_ UINT32 MemoryMapperGetOffset (PAGING_LEVEL Level, UINT64 Va)
 Get page offset.
_Use_decl_annotations_ PVOID MemoryMapperGetPteVa (PVOID Va, PAGING_LEVEL Level)
 This function gets virtual address and returns its PTE of the virtual address.
_Use_decl_annotations_ PVOID MemoryMapperGetPteVaByCr3 (PVOID Va, PAGING_LEVEL Level, CR3_TYPE TargetCr3)
 This function gets virtual address and returns its PTE of the virtual address based on the specific cr3.
_Use_decl_annotations_ PVOID MemoryMapperGetPteVaOnTargetProcess (PVOID Va, PAGING_LEVEL Level)
 This function gets virtual address and returns its PTE of the virtual address based on the target virtual address.
BOOLEAN MemoryMapperCheckPteIsPresentOnTargetProcess (PVOID Va, PAGING_LEVEL Level)
 This function checks whether the virtual address is present in the RAM or not.
_Use_decl_annotations_ PVOID MemoryMapperSetExecuteDisableToPteOnTargetProcess (PVOID Va, BOOLEAN Set)
 This function gets virtual address and returns its PTE of the virtual address based on the target virtual address.
_Use_decl_annotations_ PVOID MemoryMapperGetPteVaWithoutSwitchingByCr3 (PVOID Va, PAGING_LEVEL Level, CR3_TYPE TargetCr3)
 This function gets virtual address and returns its PTE of the virtual address based on the specific cr3 but without switching to the target address.
_Use_decl_annotations_ BOOLEAN MemoryMapperCheckIfPageIsPresentByCr3 (PVOID Va, CR3_TYPE TargetCr3)
 This function checks if the page is mapped or not.
_Use_decl_annotations_ BOOLEAN MemoryMapperCheckIfPageIsNxBitSetByCr3 (PVOID Va, CR3_TYPE TargetCr3)
 This function checks if the page has NX bit or not.
_Use_decl_annotations_ BOOLEAN MemoryMapperCheckIfPageIsNxBitSetOnTargetProcess (PVOID Va)
 This function checks target process to see if the page has NX bit or not.
_Use_decl_annotations_ BOOLEAN MemoryMapperCheckIfPdeIsLargePageOnTargetProcess (PVOID Va)
 This function checks target process to see if the PDE is a large page or not.
_Use_decl_annotations_ PVOID MemoryMapperMapReservedPageRange (SIZE_T Size)
 This function reserve memory from system range (without physically allocating them).
_Use_decl_annotations_ VOID MemoryMapperUnmapReservedPageRange (PVOID VirtualAddress)
 This function frees the memory that was previously allocated from system range (without physically allocating them).
_Use_decl_annotations_ PVOID MemoryMapperGetPte (PVOID VirtualAddress)
 This function gets virtual address and returns its PTE (Pml4e) virtual address.
_Use_decl_annotations_ PVOID MemoryMapperGetPteByCr3 (PVOID VirtualAddress, CR3_TYPE TargetCr3)
 This function gets virtual address and returns its PTE (Pml4e) virtual address based on a specific Cr3.
_Use_decl_annotations_ PVOID MemoryMapperMapPageAndGetPte (PUINT64 PteAddress)
 This function MAPs one resreved page (4096) and returns its virtual adrresss and also PTE virtual address in PteAddress.
VOID MemoryMapperInitialize ()
 Initialize the Memory Mapper.
VOID MemoryMapperUninitialize ()
 uninitialize the Memory Mapper
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeByPte (PHYSICAL_ADDRESS PaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead, UINT64 PteVaAddress, UINT64 MappingVa, BOOLEAN InvalidateVpids)
 Read memory safely by mapping the buffer using PTE.
_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeByPte (PVOID SourceVA, PHYSICAL_ADDRESS PaAddressToWrite, SIZE_T SizeToWrite, UINT64 PteVaAddress, UINT64 MappingVa, BOOLEAN InvalidateVpids)
 Write memory safely by mapping the buffer using PTE.
_Use_decl_annotations_ UINT64 MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker (MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead, UINT64 AddressToRead, UINT32 TargetProcessId)
 Wrapper to read the memory safely by mapping the buffer by physical address (It's a wrapper).
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeWrapper (MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead, UINT64 AddressToRead, UINT64 BufferToSaveMemory, SIZE_T SizeToRead, UINT32 TargetProcessId)
 Wrapper to read the memory safely by mapping the buffer by physical address (It's a wrapper).
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeByPhysicalAddress (UINT64 PaAddressToRead, UINT64 BufferToSaveMemory, SIZE_T SizeToRead)
 Read memory safely by mapping the buffer by physical address (It's a wrapper).
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafe (UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
 Read memory safely by mapping the buffer (It's a wrapper).
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemoryUnsafe (UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead, UINT32 TargetProcessId)
 Read memory unsafely by mapping the buffer (It's a wrapper).
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeOnTargetProcess (UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
 Read memory safely by mapping the buffer on the target process memory (It's a wrapper).
_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeOnTargetProcess (UINT64 Destination, PVOID Source, SIZE_T Size)
 Write memory safely by mapping the buffer on the target process memory (It's a wrapper).
_Use_decl_annotations_ UINT64 MemoryMapperWriteMemorySafeWrapperAddressMaker (MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE TypeOfWrite, UINT64 DestinationAddr, PCR3_TYPE TargetProcessCr3, UINT32 TargetProcessId)
 Decides about making the address and converting the address to physical address based on the passed parameters.
_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeWrapper (MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE TypeOfWrite, UINT64 DestinationAddr, UINT64 Source, SIZE_T SizeToWrite, PCR3_TYPE TargetProcessCr3, UINT32 TargetProcessId)
 Write memory safely by mapping the buffer (It's a wrapper).
_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafe (UINT64 Destination, PVOID Source, SIZE_T SizeToWrite, CR3_TYPE TargetProcessCr3)
 Write memory by mapping the buffer (It's a wrapper).
_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemoryUnsafe (UINT64 Destination, PVOID Source, SIZE_T SizeToWrite, UINT32 TargetProcessId)
 Write memory safely by mapping the buffer (It's a wrapper).
_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeByPhysicalAddress (UINT64 DestinationPa, UINT64 Source, SIZE_T SizeToWrite)
 Write memory safely by mapping the buffer.
_Use_decl_annotations_ UINT64 MemoryMapperReserveUsermodeAddressOnTargetProcess (UINT32 ProcessId, BOOLEAN Allocate)
 Reserve user mode address (not allocated) in the target user mode application.
_Use_decl_annotations_ BOOLEAN MemoryMapperFreeMemoryOnTargetProcess (UINT32 ProcessId, PVOID BaseAddress)
 Deallocates a previously reserved user mode address in the target user mode application.
_Use_decl_annotations_ VOID MemoryMapperMapPhysicalAddressToPte (PHYSICAL_ADDRESS PhysicalAddress, PVOID TargetProcessVirtualAddress, CR3_TYPE TargetProcessKernelCr3)
 Maps a physical address to a PTE.
_Use_decl_annotations_ BOOLEAN MemoryMapperSetSupervisorBitWithoutSwitchingByCr3 (PVOID Va, BOOLEAN Set, PAGING_LEVEL Level, CR3_TYPE TargetCr3)
 This function the Supervisor bit of the target PTE based on the specific cr3.
BOOLEAN MemoryMapperReadMemorySafeFromVmxNonRootByPhysicalAddress (UINT64 PaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
 Read physical memory safely from vmx non-root mode.
BOOLEAN MemoryMapperWriteMemorySafeFromVmxNonRootyPhysicalAddress (UINT64 DestinationPa, PVOID Source, SIZE_T SizeToWrite)
 Write physical memory safely from vmx non-root mode.

Detailed Description

This file shows the functions to map memory to reserved system ranges.

This file shows the header functions to map memory to reserved system ranges.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)

also some of the functions derived from hvpp

Version
0.1
Date
2020-05-3
Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)

also some of the functions derived from hvpp

Version
0.1
Date
2020-05-3

Function Documentation

◆ MemoryMapperCheckIfPageIsNxBitSetByCr3()

_Use_decl_annotations_ BOOLEAN MemoryMapperCheckIfPageIsNxBitSetByCr3 ( PVOID Va,
CR3_TYPE TargetCr3 )

This function checks if the page has NX bit or not.

Parameters
VaVirtual Address
TargetCr3kernel cr3 of target process
Returns
PPAGE_ENTRY virtual address of PTE based on cr3
447{
448 PPAGE_ENTRY PageEntry;
449
450 //
451 // Find the page table entry
452 //
453 PageEntry = MemoryMapperGetPteVaByCr3(Va, PagingLevelPageTable, TargetCr3);
454
455 if (PageEntry != NULL && !PageEntry->Fields.ExecuteDisable)
456 {
457 return TRUE;
458 }
459 else
460 {
461 return FALSE;
462 }
463}
_Use_decl_annotations_ PVOID MemoryMapperGetPteVaByCr3(PVOID Va, PAGING_LEVEL Level, CR3_TYPE TargetCr3)
This function gets virtual address and returns its PTE of the virtual address based on the specific c...
Definition MemoryMapper.c:88
struct _PAGE_ENTRY * PPAGE_ENTRY
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113
@ PagingLevelPageTable
Definition DataTypes.h:25
UINT64 ExecuteDisable
Definition MemoryMapper.h:95
struct _PAGE_ENTRY::@376376202121063303120064260270315140365371076130::@103064255274005116234107103217043340214273361203 Fields

◆ MemoryMapperCheckIfPageIsNxBitSetOnTargetProcess()

_Use_decl_annotations_ BOOLEAN MemoryMapperCheckIfPageIsNxBitSetOnTargetProcess ( PVOID Va)

This function checks target process to see if the page has NX bit or not.

Parameters
VaVirtual Address
TargetCr3kernel cr3 of target process
Returns
BOOLEAN
476{
477 BOOLEAN Result;
478 CR3_TYPE GuestCr3;
479 PPAGE_ENTRY PageEntry;
480 CR3_TYPE CurrentProcessCr3 = {0};
481
482 //
483 // Move to guest process as we're currently in system cr3
484 //
485
486 //
487 // Find the current process cr3
488 //
490
491 CurrentProcessCr3 = SwitchToProcessMemoryLayoutByCr3(GuestCr3);
492
493 //
494 // Find the page table entry
495 //
497
498 if (PageEntry != NULL && !PageEntry->Fields.ExecuteDisable)
499 {
500 Result = TRUE;
501 }
502 else
503 {
504 Result = FALSE;
505 }
506
507 //
508 // Restore the original process
509 //
510 SwitchToPreviousProcess(CurrentProcessCr3);
511
512 return Result;
513}
_Use_decl_annotations_ PVOID MemoryMapperGetPteVa(PVOID Va, PAGING_LEVEL Level)
This function gets virtual address and returns its PTE of the virtual address.
Definition MemoryMapper.c:59
UCHAR BOOLEAN
Definition BasicTypes.h:35
struct _CR3_TYPE CR3_TYPE
CR3 Structure.
IMPORT_EXPORT_VMM VOID SwitchToPreviousProcess(_In_ CR3_TYPE PreviousProcess)
IMPORT_EXPORT_VMM CR3_TYPE SwitchToProcessMemoryLayoutByCr3(_In_ CR3_TYPE TargetCr3)
IMPORT_EXPORT_VMM CR3_TYPE LayoutGetCurrentProcessCr3()
Get cr3 of the target running process.
Definition Layout.c:55
UINT64 Flags
Definition BasicTypes.h:239

◆ MemoryMapperCheckIfPageIsPresentByCr3()

_Use_decl_annotations_ BOOLEAN MemoryMapperCheckIfPageIsPresentByCr3 ( PVOID Va,
CR3_TYPE TargetCr3 )

This function checks if the page is mapped or not.

this function checks for PRESENT Bit of the page table

Parameters
VaVirtual Address
TargetCr3kernel cr3 of target process
Returns
PPAGE_ENTRY virtual address of PTE based on cr3
419{
420 PPAGE_ENTRY PageEntry;
421
422 //
423 // Find the page table entry
424 //
425 PageEntry = MemoryMapperGetPteVaByCr3(Va, PagingLevelPageTable, TargetCr3);
426
427 if (PageEntry != NULL && PageEntry->Fields.Present)
428 {
429 return TRUE;
430 }
431 else
432 {
433 return FALSE;
434 }
435}
UINT64 Present
Definition MemoryMapper.h:81

◆ MemoryMapperCheckIfPdeIsLargePageOnTargetProcess()

_Use_decl_annotations_ BOOLEAN MemoryMapperCheckIfPdeIsLargePageOnTargetProcess ( PVOID Va)

This function checks target process to see if the PDE is a large page or not.

Parameters
VaVirtual Address
TargetCr3kernel cr3 of target process
Returns
BOOLEAN
526{
527 BOOLEAN Result;
528 CR3_TYPE GuestCr3;
529 PPAGE_ENTRY PageEntry;
530 CR3_TYPE CurrentProcessCr3 = {0};
531
532 //
533 // Move to guest process as we're currently in system cr3
534 //
535
536 //
537 // Find the current process cr3
538 //
540
541 CurrentProcessCr3 = SwitchToProcessMemoryLayoutByCr3(GuestCr3);
542
543 //
544 // Find the page table entry (PDE)
545 //
547
548 if (PageEntry != NULL && PageEntry->Fields.LargePage)
549 {
550 Result = TRUE;
551 }
552 else
553 {
554 Result = FALSE;
555 }
556
557 //
558 // Restore the original process
559 //
560 SwitchToPreviousProcess(CurrentProcessCr3);
561
562 return Result;
563}
@ PagingLevelPageDirectory
Definition DataTypes.h:26
UINT64 LargePage
Definition MemoryMapper.h:88

◆ MemoryMapperCheckPteIsPresentOnTargetProcess()

BOOLEAN MemoryMapperCheckPteIsPresentOnTargetProcess ( PVOID Va,
PAGING_LEVEL Level )

This function checks whether the virtual address is present in the RAM or not.

Parameters
VaVirtual Address
LevelPMLx
Returns
BOOLEAN Is present or not
175{
176 PPAGE_ENTRY PageEntry = NULL;
177 CR3_TYPE GuestCr3;
178 CR3_TYPE CurrentProcessCr3 = {0};
179 BOOLEAN Result = FALSE;
180
181 //
182 // Move to guest process as we're currently in system cr3
183 //
184
185 //
186 // Find the current process cr3
187 //
189
190 //
191 // Switch to new process's memory layout
192 // It is because, we're not trying to change the cr3 multiple times
193 // so instead of using PhysicalAddressToVirtualAddressByCr3 we use
194 // PhysicalAddressToVirtualAddress, but keep in mind that cr3 should
195 // be a kernel cr3 (not KPTI user cr3) as the functions to translate
196 // physical address to virtual address is not mapped on the user cr3
197 //
198 CurrentProcessCr3 = SwitchToProcessMemoryLayoutByCr3(GuestCr3);
199
200 //
201 // Call the wrapper
202 //
203 PageEntry = MemoryMapperGetPteVaWithoutSwitchingByCr3(Va, Level, GuestCr3);
204
205 if (PageEntry == NULL)
206 {
207 Result = FALSE;
208 }
209 else
210 {
211 //
212 // Check if page is present or not
213 //
214 if (PageEntry->Fields.Present == TRUE)
215 {
216 //
217 // It's present
218 //
219 Result = TRUE;
220 }
221 else
222 {
223 //
224 // It's not present
225 //
226 Result = FALSE;
227 }
228 }
229
230 //
231 // Restore the original process
232 //
233 SwitchToPreviousProcess(CurrentProcessCr3);
234
235 return Result;
236}
_Use_decl_annotations_ PVOID MemoryMapperGetPteVaWithoutSwitchingByCr3(PVOID Va, PAGING_LEVEL Level, CR3_TYPE TargetCr3)
This function gets virtual address and returns its PTE of the virtual address based on the specific c...
Definition MemoryMapper.c:314
NULL()
Definition test-case-generator.py:530

◆ MemoryMapperFreeMemoryOnTargetProcess()

_Use_decl_annotations_ BOOLEAN MemoryMapperFreeMemoryOnTargetProcess ( UINT32 ProcessId,
PVOID BaseAddress )

Deallocates a previously reserved user mode address in the target user mode application.

this function should be called from vmx non-root mode

Parameters
ProcessIdTarget Process Id
BaseAddressPreviously allocated base address
Returns
BOOLEAN whether the operation was successful or not
1584{
1585 NTSTATUS Status;
1586 SIZE_T AllocSize = PAGE_SIZE;
1587 PEPROCESS SourceProcess;
1588 KAPC_STATE State = {0};
1589
1590 if (PsGetCurrentProcessId() != (HANDLE)ProcessId)
1591 {
1592 //
1593 // User needs another process memory
1594 //
1595
1596 if (PsLookupProcessByProcessId((HANDLE)ProcessId, &SourceProcess) != STATUS_SUCCESS)
1597 {
1598 //
1599 // if the process not found
1600 //
1601 return FALSE;
1602 }
1603 __try
1604 {
1605 KeStackAttachProcess(SourceProcess, &State);
1606
1607 //
1608 // Free memory in target process
1609 //
1610 Status = ZwFreeVirtualMemory(NtCurrentProcess(),
1611 &BaseAddress,
1612 &AllocSize,
1613 MEM_RELEASE);
1614
1615 KeUnstackDetachProcess(&State);
1616
1617 ObDereferenceObject(SourceProcess);
1618 }
1619 __except (EXCEPTION_EXECUTE_HANDLER)
1620 {
1621 KeUnstackDetachProcess(&State);
1622
1623 ObDereferenceObject(SourceProcess);
1624 return FALSE;
1625 }
1626 }
1627 else
1628 {
1629 //
1630 // Deallocate memory in target process
1631 //
1632 Status = ZwFreeVirtualMemory(NtCurrentProcess(),
1633 &BaseAddress,
1634 &AllocSize,
1635 MEM_RELEASE);
1636 }
1637
1638 if (!NT_SUCCESS(Status))
1639 {
1640 return FALSE;
1641 }
1642
1643 //
1644 // Operation was successful
1645 //
1646 return TRUE;
1647}
#define PAGE_SIZE
Size of each page (4096 bytes).
Definition common.h:80

◆ MemoryMapperGetIndex()

_Use_decl_annotations_ UINT64 MemoryMapperGetIndex ( PAGING_LEVEL Level,
UINT64 Va )

Get Index of VA on PMLx.

Parameters
LevelPMLx
VaVirtual Address
Returns
UINT64
26{
27 UINT64 Result = Va;
28 Result >>= 12 + Level * 9;
29
30 return Result;
31}

◆ MemoryMapperGetOffset()

_Use_decl_annotations_ UINT32 MemoryMapperGetOffset ( PAGING_LEVEL Level,
UINT64 Va )

Get page offset.

Parameters
LevelPMLx
VaVirtual Address
Returns
UINT32
43{
44 UINT32 Result = (UINT32)MemoryMapperGetIndex(Level, Va);
45 Result &= (1 << 9) - 1; // 0x1ff
46
47 return Result;
48}
_Use_decl_annotations_ UINT64 MemoryMapperGetIndex(PAGING_LEVEL Level, UINT64 Va)
Get Index of VA on PMLx.
Definition MemoryMapper.c:25
unsigned int UINT32
Definition BasicTypes.h:54

◆ MemoryMapperGetPte()

_Use_decl_annotations_ PVOID MemoryMapperGetPte ( PVOID VirtualAddress)

This function gets virtual address and returns its PTE (Pml4e) virtual address.

Parameters
VirtualAddressVirtual Address
Returns
virtual address of PTE (Pml4e)
605{
606 return MemoryMapperGetPteVa(VirtualAddress, PagingLevelPageTable);
607}

◆ MemoryMapperGetPteByCr3()

_Use_decl_annotations_ PVOID MemoryMapperGetPteByCr3 ( PVOID VirtualAddress,
CR3_TYPE TargetCr3 )

This function gets virtual address and returns its PTE (Pml4e) virtual address based on a specific Cr3.

Parameters
VirtualAddressVirtual Address
TargetCr3Target process cr3
Returns
virtual address of PTE (Pml4e)
620{
621 return MemoryMapperGetPteVaByCr3(VirtualAddress, PagingLevelPageTable, TargetCr3);
622}

◆ MemoryMapperGetPteVa()

_Use_decl_annotations_ PVOID MemoryMapperGetPteVa ( PVOID Va,
PAGING_LEVEL Level )

This function gets virtual address and returns its PTE of the virtual address.

Parameters
VaVirtual Address
LevelPMLx
Returns
PVOID virtual address of PTE
60{
61 CR3_TYPE Cr3;
62
63 //
64 // Read the current cr3
65 //
66 Cr3.Flags = CpuReadCr3();
67
68 //
69 // Call the wrapper
70 //
71 return MemoryMapperGetPteVaWithoutSwitchingByCr3(Va, Level, Cr3);
72}
ULONG_PTR CpuReadCr3(VOID)
Read CR3.
Definition PlatformIntrinsics.c:100

◆ MemoryMapperGetPteVaByCr3()

_Use_decl_annotations_ PVOID MemoryMapperGetPteVaByCr3 ( PVOID Va,
PAGING_LEVEL Level,
CR3_TYPE TargetCr3 )

This function gets virtual address and returns its PTE of the virtual address based on the specific cr3.

the TargetCr3 should be kernel cr3 as we will use it to translate kernel addresses so the kernel functions to translate addresses should be mapped; thus, don't pass a KPTI meltdown user cr3 to this function

Parameters
VaVirtual Address
LevelPMLx
TargetCr3kernel cr3 of target process
Returns
PVOID virtual address of PTE based on cr3
89{
90 PPAGE_ENTRY PageEntry = NULL;
91 CR3_TYPE CurrentProcessCr3 = {0};
92
93 //
94 // Switch to new process's memory layout
95 // It is because, we're not trying to change the cr3 multiple times
96 // so instead of using PhysicalAddressToVirtualAddressByCr3 we use
97 // PhysicalAddressToVirtualAddress, but keep in mind that cr3 should
98 // be a kernel cr3 (not KPTI user cr3) as the functions to translate
99 // physical address to virtual address is not mapped on the user cr3
100 //
101 CurrentProcessCr3 = SwitchToProcessMemoryLayoutByCr3(TargetCr3);
102
103 //
104 // Call the wrapper
105 //
106 PageEntry = MemoryMapperGetPteVaWithoutSwitchingByCr3(Va, Level, TargetCr3);
107
108 //
109 // Restore the original process
110 //
111 SwitchToPreviousProcess(CurrentProcessCr3);
112
113 return PageEntry;
114}

◆ MemoryMapperGetPteVaOnTargetProcess()

_Use_decl_annotations_ PVOID MemoryMapperGetPteVaOnTargetProcess ( PVOID Va,
PAGING_LEVEL Level )

This function gets virtual address and returns its PTE of the virtual address based on the target virtual address.

Parameters
VaVirtual Address
LevelPMLx
Returns
PVOID virtual address of PTE based on cr3
128{
129 PPAGE_ENTRY PageEntry = NULL;
130 CR3_TYPE GuestCr3;
131 CR3_TYPE CurrentProcessCr3 = {0};
132
133 //
134 // Move to guest process as we're currently in system cr3
135 //
136
137 //
138 // Find the current process cr3
139 //
141
142 //
143 // Switch to new process's memory layout
144 // It is because, we're not trying to change the cr3 multiple times
145 // so instead of using PhysicalAddressToVirtualAddressByCr3 we use
146 // PhysicalAddressToVirtualAddress, but keep in mind that cr3 should
147 // be a kernel cr3 (not KPTI user cr3) as the functions to translate
148 // physical address to virtual address is not mapped on the user cr3
149 //
150 CurrentProcessCr3 = SwitchToProcessMemoryLayoutByCr3(GuestCr3);
151
152 //
153 // Call the wrapper
154 //
155 PageEntry = MemoryMapperGetPteVaWithoutSwitchingByCr3(Va, Level, GuestCr3);
156
157 //
158 // Restore the original process
159 //
160 SwitchToPreviousProcess(CurrentProcessCr3);
161
162 return PageEntry;
163}

◆ MemoryMapperGetPteVaWithoutSwitchingByCr3()

_Use_decl_annotations_ PVOID MemoryMapperGetPteVaWithoutSwitchingByCr3 ( PVOID Va,
PAGING_LEVEL Level,
CR3_TYPE TargetCr3 )

This function gets virtual address and returns its PTE of the virtual address based on the specific cr3 but without switching to the target address.

the TargetCr3 should be kernel cr3 as we will use it to translate kernel addresses so the kernel functions to translate addresses should be mapped; thus, don't pass a KPTI meltdown user cr3 to this function

Parameters
VaVirtual Address
LevelPMLx
TargetCr3kernel cr3 of target process
Returns
PVOID virtual address of PTE based on cr3
315{
316 CR3_TYPE Cr3;
317 UINT64 TempCr3;
318 PUINT64 Cr3Va;
319 PUINT64 PdptVa;
320 PUINT64 PdVa;
321 PUINT64 PtVa;
322 UINT32 Offset;
323
324 Cr3.Flags = TargetCr3.Flags;
325
326 //
327 // Cr3 should be shifted 12 to the left because it's PFN
328 //
329 TempCr3 = Cr3.Fields.PageFrameNumber << 12;
330
331 //
332 // we need VA of Cr3, not PA
333 //
334 Cr3Va = (UINT64 *)PhysicalAddressToVirtualAddress(TempCr3);
335
336 //
337 // Check for invalid address
338 //
339 if (Cr3Va == NULL)
340 {
341 return NULL;
342 }
343
345
346 PPAGE_ENTRY Pml4e = (PAGE_ENTRY *)&Cr3Va[Offset];
347
348 if (!Pml4e->Fields.Present || Level == PagingLevelPageMapLevel4)
349 {
350 return Pml4e;
351 }
352
353 PdptVa = (UINT64 *)PhysicalAddressToVirtualAddress(Pml4e->Fields.PageFrameNumber << 12);
354
355 //
356 // Check for invalid address
357 //
358 if (PdptVa == NULL)
359 {
360 return NULL;
361 }
362
364
365 PPAGE_ENTRY Pdpte = (PAGE_ENTRY *)&PdptVa[Offset];
366
367 if (!Pdpte->Fields.Present || Pdpte->Fields.LargePage || Level == PagingLevelPageDirectoryPointerTable)
368 {
369 return Pdpte;
370 }
371
372 PdVa = (UINT64 *)PhysicalAddressToVirtualAddress(Pdpte->Fields.PageFrameNumber << 12);
373
374 //
375 // Check for invalid address
376 //
377 if (PdVa == NULL)
378 {
379 return NULL;
380 }
381
383
384 PPAGE_ENTRY Pde = (PAGE_ENTRY *)&PdVa[Offset];
385
386 if (!Pde->Fields.Present || Pde->Fields.LargePage || Level == PagingLevelPageDirectory)
387 {
388 return Pde;
389 }
390
391 PtVa = (UINT64 *)PhysicalAddressToVirtualAddress(Pde->Fields.PageFrameNumber << 12);
392
393 //
394 // Check for invalid address
395 //
396 if (PtVa == NULL)
397 {
398 return NULL;
399 }
400
401 Offset = MemoryMapperGetOffset(PagingLevelPageTable, (UINT64)Va);
402
403 PPAGE_ENTRY Pt = (PAGE_ENTRY *)&PtVa[Offset];
404
405 return Pt;
406}
_Use_decl_annotations_ UINT32 MemoryMapperGetOffset(PAGING_LEVEL Level, UINT64 Va)
Get page offset.
Definition MemoryMapper.c:42
struct _PAGE_ENTRY PAGE_ENTRY
Page Entries.
@ PagingLevelPageDirectoryPointerTable
Definition DataTypes.h:27
@ PagingLevelPageMapLevel4
Definition DataTypes.h:28
IMPORT_EXPORT_VMM UINT64 PhysicalAddressToVirtualAddress(_In_ UINT64 PhysicalAddress)
UINT64 PageFrameNumber
Definition BasicTypes.h:244
struct _CR3_TYPE::@244034060255073137115274324157111341233214336223::@234224113264105317012146222243166211041242274101 Fields
UINT64 PageFrameNumber
Definition MemoryMapper.h:91

◆ MemoryMapperInitialize()

VOID MemoryMapperInitialize ( )

Initialize the Memory Mapper.

This function should be called in vmx non-root in a IRQL <= APC_LEVEL

Returns
VOID
662{
663 UINT64 TempPte;
664 ULONG ProcessorsCount;
665
666 ProcessorsCount = KeQueryActiveProcessorCount(0);
667
668 //
669 // *** Reserve the address for all cores (read pte and va) ***
670 //
671
672 if (g_MemoryMapper != NULL)
673 {
674 //
675 // It's already initialized
676 //
677 return;
678 }
679
680 //
681 // Allocate the memory buffer structure
682 //
684
685 //
686 // Set the core's id and initialize memory mapper
687 //
688 for (SIZE_T i = 0; i < ProcessorsCount; i++)
689 {
690 //
691 // *** Initialize memory mapper for each core ***
692 //
693
694 //
695 // Initial and reserve for read operations
696 //
697 g_MemoryMapper[i].VirualAddressForRead = (UINT64)MemoryMapperMapPageAndGetPte(&TempPte);
698 g_MemoryMapper[i].PteVirtualAddressForRead = TempPte;
699
700 //
701 // Initial and reserve for write operations
702 //
703 g_MemoryMapper[i].VirualAddressForWrite = (UINT64)MemoryMapperMapPageAndGetPte(&TempPte);
704 g_MemoryMapper[i].PteVirtualAddressForWrite = TempPte;
705 }
706}
_Use_decl_annotations_ PVOID MemoryMapperMapPageAndGetPte(PUINT64 PteAddress)
This function MAPs one resreved page (4096) and returns its virtual adrresss and also PTE virtual add...
Definition MemoryMapper.c:633
struct _MEMORY_MAPPER_ADDRESSES MEMORY_MAPPER_ADDRESSES
Memory mapper PTE and reserved virtual address.
PVOID PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
Allocates zeroed non-paged pool memory.
Definition PlatformMem.c:248
unsigned long ULONG
Definition BasicTypes.h:31
MEMORY_MAPPER_ADDRESSES * g_MemoryMapper
Save the state of memory mapper.
Definition GlobalVariables.h:44

◆ MemoryMapperMapPageAndGetPte()

_Use_decl_annotations_ PVOID MemoryMapperMapPageAndGetPte ( PUINT64 PteAddress)

This function MAPs one resreved page (4096) and returns its virtual adrresss and also PTE virtual address in PteAddress.

Parameters
PteAddressAddress of Page Table Entry
Returns
virtual address of mapped (not physically) address
634{
635 PVOID Va;
636 UINT64 Pte;
637
638 //
639 // Reserve the page from system va space
640 //
642
643 //
644 // Get the page's Page Table Entry
645 //
646 Pte = (UINT64)MemoryMapperGetPte(Va);
647
648 *PteAddress = Pte;
649
650 return Va;
651}
_Use_decl_annotations_ PVOID MemoryMapperGetPte(PVOID VirtualAddress)
This function gets virtual address and returns its PTE (Pml4e) virtual address.
Definition MemoryMapper.c:604
_Use_decl_annotations_ PVOID MemoryMapperMapReservedPageRange(SIZE_T Size)
This function reserve memory from system range (without physically allocating them).
Definition MemoryMapper.c:573
void * PVOID
Definition BasicTypes.h:56

◆ MemoryMapperMapPhysicalAddressToPte()

_Use_decl_annotations_ VOID MemoryMapperMapPhysicalAddressToPte ( PHYSICAL_ADDRESS PhysicalAddress,
PVOID TargetProcessVirtualAddress,
CR3_TYPE TargetProcessKernelCr3 )

Maps a physical address to a PTE.

Find the PTE from MemoryMapperGetPteVaByCr3

Parameters
PhysicalAddressPhysical Address to be mapped
TargetProcessVirtualAddressVirtual Address of target process
TargetProcessKernelCr3Target process cr3
Returns
VOID
1664{
1665 PPAGE_ENTRY PreviousPteEntry;
1666 PAGE_ENTRY PageEntry;
1667 CR3_TYPE CurrentProcessCr3;
1668
1669 //
1670 // Find the page table entry of the reserved page in the target
1671 // process memory layout
1672 //
1673 PreviousPteEntry = MemoryMapperGetPteVaByCr3(TargetProcessVirtualAddress, PagingLevelPageTable, TargetProcessKernelCr3);
1674
1675 //
1676 // Switch to new process's memory layout
1677 //
1678 CurrentProcessCr3 = SwitchToProcessMemoryLayoutByCr3(TargetProcessKernelCr3);
1679
1680 //
1681 // Read the previous entry in order to modify it
1682 //
1683 PageEntry.Flags = PreviousPteEntry->Flags;
1684
1685 //
1686 // Make sure that the target PTE is readable, writable, executable
1687 // present, global, etc.
1688 //
1689 PageEntry.Fields.Present = 1;
1690
1691 //
1692 // It's not a supervisor page
1693 //
1694 PageEntry.Fields.Supervisor = 1;
1695
1696 //
1697 // Generally we want each page to be writable
1698 //
1699 PageEntry.Fields.Write = 1;
1700
1701 //
1702 // Do not flush this page from the TLB on CR3 switch, by setting the
1703 // global bit in the PTE.
1704 //
1705 PageEntry.Fields.Global = 1;
1706
1707 //
1708 // Set the PFN of this PTE to that of the provided physical address.
1709 //
1710 PageEntry.Fields.PageFrameNumber = PhysicalAddress.QuadPart >> 12;
1711
1712 //
1713 // Apply the page entry in a single instruction
1714 //
1715 PreviousPteEntry->Flags = PageEntry.Flags;
1716
1717 //
1718 // Finally, invalidate the caches for the virtual address
1719 // It's not mandatory to invalidate the address in the VM nested-virtualization
1720 // because it will be automatically invalidated by the top hypervisor, however,
1721 // we should use invlpg in physical computers as it won't invalidate it automatically
1722 //
1723 CpuInvlpg(TargetProcessVirtualAddress);
1724
1725 //
1726 // Restore the original process
1727 //
1728 SwitchToPreviousProcess(CurrentProcessCr3);
1729}
VOID CpuInvlpg(VOID *Address)
Invalidate TLB entry for a virtual address.
Definition PlatformIntrinsics.c:440
UINT64 Write
Definition MemoryMapper.h:82
UINT64 Global
Definition MemoryMapper.h:89
UINT64 Supervisor
Definition MemoryMapper.h:83
UINT64 Flags
Definition MemoryMapper.h:66

◆ MemoryMapperMapReservedPageRange()

_Use_decl_annotations_ PVOID MemoryMapperMapReservedPageRange ( SIZE_T Size)

This function reserve memory from system range (without physically allocating them).

Parameters
SizeSize of reserving buffers
Returns
PVOID Return the VA of the page
574{
575 //
576 // The MmAllocateMappingAddress routine reserves a range of
577 // system virtual address space of the specified size.
578 //
579 return MmAllocateMappingAddress(Size, POOLTAG);
580}
#define POOLTAG
Pool tag.
Definition Constants.h:419

◆ MemoryMapperReadMemorySafe()

_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafe ( UINT64 VaAddressToRead,
PVOID BufferToSaveMemory,
SIZE_T SizeToRead )

Read memory safely by mapping the buffer (It's a wrapper).

Parameters
VaAddressToReadVirtual Address to read
BufferToSaveMemoryDestination to save
SizeToReadSize
Returns
BOOLEAN if it was successful the returns TRUE and if it was unsuccessful then it returns FALSE
1124{
1126 VaAddressToRead,
1127 (UINT64)BufferToSaveMemory,
1128 SizeToRead,
1129 NULL_ZERO);
1130}
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeWrapper(MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead, UINT64 AddressToRead, UINT64 BufferToSaveMemory, SIZE_T SizeToRead, UINT32 TargetProcessId)
Wrapper to read the memory safely by mapping the buffer by physical address (It's a wrapper).
Definition MemoryMapper.c:989
@ MEMORY_MAPPER_WRAPPER_READ_VIRTUAL_MEMORY
Definition MemoryMapper.h:37
#define NULL_ZERO
Definition BasicTypes.h:110

◆ MemoryMapperReadMemorySafeByPhysicalAddress()

_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeByPhysicalAddress ( UINT64 PaAddressToRead,
UINT64 BufferToSaveMemory,
SIZE_T SizeToRead )

Read memory safely by mapping the buffer by physical address (It's a wrapper).

Parameters
PaAddressToReadPhysical Address to read
BufferToSaveMemoryDestination to save
SizeToReadSize
Returns
BOOLEAN if it was successful the returns TRUE and if it was unsuccessful then it returns FALSE
1101{
1102 //
1103 // Call the wrapper
1104 //
1106 PaAddressToRead,
1107 BufferToSaveMemory,
1108 SizeToRead,
1109 NULL_ZERO);
1110}
@ MEMORY_MAPPER_WRAPPER_READ_PHYSICAL_MEMORY
Definition MemoryMapper.h:36

◆ MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker()

_Use_decl_annotations_ UINT64 MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker ( MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead,
UINT64 AddressToRead,
UINT32 TargetProcessId )

Wrapper to read the memory safely by mapping the buffer by physical address (It's a wrapper).

Parameters
TypeOfReadType of read
AddressToReadPhysical Address to read
TargetProcessIdTarget Process Id
Returns
UINT64 returns the target physical address and NULL if it fails
935{
936 PHYSICAL_ADDRESS PhysicalAddress = {0};
937
938 switch (TypeOfRead)
939 {
941
942 PhysicalAddress.QuadPart = AddressToRead;
943
944 break;
945
947
948 PhysicalAddress.QuadPart = VirtualAddressToPhysicalAddress((PVOID)AddressToRead);
949
950 break;
951
953
954 if (TargetProcessId == NULL_ZERO)
955 {
956 PhysicalAddress.QuadPart = VirtualAddressToPhysicalAddress((PVOID)AddressToRead);
957 }
958 else
959 {
960 PhysicalAddress.QuadPart = VirtualAddressToPhysicalAddressByProcessId((PVOID)AddressToRead, TargetProcessId);
961 }
962
963 break;
964
965 default:
966
967 return NULL64_ZERO;
968 break;
969 }
970
971 return PhysicalAddress.QuadPart;
972}
@ MEMORY_MAPPER_WRAPPER_READ_VIRTUAL_MEMORY_UNSAFE
Definition MemoryMapper.h:38
#define NULL64_ZERO
Definition BasicTypes.h:111
IMPORT_EXPORT_VMM UINT64 VirtualAddressToPhysicalAddress(_In_ PVOID VirtualAddress)
Converts Virtual Address to Physical Address.
Definition Conversion.c:154
IMPORT_EXPORT_VMM UINT64 VirtualAddressToPhysicalAddressByProcessId(_In_ PVOID VirtualAddress, _In_ UINT32 ProcessId)

◆ MemoryMapperReadMemorySafeByPte()

_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeByPte ( PHYSICAL_ADDRESS PaAddressToRead,
PVOID BufferToSaveMemory,
SIZE_T SizeToRead,
UINT64 PteVaAddress,
UINT64 MappingVa,
BOOLEAN InvalidateVpids )

Read memory safely by mapping the buffer using PTE.

Parameters
PaAddressToReadPhysical address to read
BufferToSaveMemorybuffer to save the memory
SizeToReadSize
PteVaAddressVirtual Address of PTE
MappingVaMapping virtual address
InvalidateVpidswhether invalidate based on VPIDs or not
Returns
BOOLEAN returns TRUE if it was successful and FALSE if there was error
767{
768 PVOID NewAddress;
769 PAGE_ENTRY PageEntry;
770 PPAGE_ENTRY Pte = (PAGE_ENTRY *)PteVaAddress;
771 PVOID Va = (PVOID)MappingVa;
772
773 //
774 // Copy the previous entry into the new entry
775 //
776 PageEntry.Flags = Pte->Flags;
777
778 PageEntry.Fields.Present = 1;
779
780 //
781 // Generally we want each page to be writable
782 //
783 PageEntry.Fields.Write = 1;
784
785 //
786 // Do not flush this page from the TLB on CR3 switch, by setting the
787 // global bit in the PTE.
788 //
789 PageEntry.Fields.Global = 1;
790
791 //
792 // Set the PFN of this PTE to that of the provided physical address,
793 //
794 PageEntry.Fields.PageFrameNumber = PaAddressToRead.QuadPart >> 12;
795
796 //
797 // Apply the page entry in a single instruction
798 //
799 Pte->Flags = PageEntry.Flags;
800
801 //
802 // Finally, invalidate the caches for the virtual address
803 // It's not mandatory to invalidate the address in the VM nested-virtualization
804 // because it will be automatically invalidated by the top hypervisor, however,
805 // we should use invlpg in physical computers as it won't invalidate it automatically
806 //
807 CpuInvlpg(Va);
808
809 //
810 // Also invalidate it from vpids if we're in vmx root
811 //
812 if (InvalidateVpids)
813 {
814 // __invvpid_addr(VPID_TAG, Va);
815 }
816
817 //
818 // Compute the address
819 //
820 NewAddress = (PVOID)((UINT64)Va + (PAGE_4KB_OFFSET & (PaAddressToRead.QuadPart)));
821
822 //
823 // Move the address into the buffer in a safe manner
824 //
825 memcpy(BufferToSaveMemory, NewAddress, SizeToRead);
826
827 //
828 // Unmap Address
829 //
830 Pte->Flags = NULL64_ZERO;
831
832 return TRUE;
833}
#define PAGE_4KB_OFFSET
Definition MemoryMapper.h:21

◆ MemoryMapperReadMemorySafeFromVmxNonRootByPhysicalAddress()

BOOLEAN MemoryMapperReadMemorySafeFromVmxNonRootByPhysicalAddress ( UINT64 PaAddressToRead,
PVOID BufferToSaveMemory,
SIZE_T SizeToRead )

Read physical memory safely from vmx non-root mode.

Parameters
PaAddressToReadPhysical Address to read
BufferToSaveMemoryDestination to save
SizeToReadSize
Returns
BOOLEAN whether was successful or not
1781{
1782 if (AsmVmxVmcall(VMCALL_READ_PHYSICAL_MEMORY, (UINT64)PaAddressToRead, (UINT64)BufferToSaveMemory, (UINT64)SizeToRead) == STATUS_SUCCESS)
1783 {
1784 return TRUE;
1785 }
1786 else
1787 {
1788 return FALSE;
1789 }
1790}
NTSTATUS AsmVmxVmcall(UINT64 VmcallNumber, UINT64 OptionalParam1, UINT64 OptionalParam2, UINT64 OptionalParam3)
Request Vmcall.
#define VMCALL_READ_PHYSICAL_MEMORY
VMCALL to read physical memory.
Definition Vmcall.h:315

◆ MemoryMapperReadMemorySafeOnTargetProcess()

_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeOnTargetProcess ( UINT64 VaAddressToRead,
PVOID BufferToSaveMemory,
SIZE_T SizeToRead )

Read memory safely by mapping the buffer on the target process memory (It's a wrapper).

Parameters
VaAddressToReadVirtual Address to read
BufferToSaveMemoryDestination to save
SizeToReadSize
Returns
BOOLEAN if it was successful the returns TRUE and if it was unsuccessful then it returns FALSE
1166{
1167 CR3_TYPE GuestCr3;
1168 CR3_TYPE OriginalCr3;
1169 BOOLEAN Result;
1170
1171 //
1172 // Move to guest process as we're currently in system cr3
1173 //
1174
1175 //
1176 // Find the current process cr3
1177 //
1179
1180 //
1181 // Move to new cr3
1182 //
1183 OriginalCr3.Flags = CpuReadCr3();
1184 CpuWriteCr3(GuestCr3.Flags);
1185
1186 //
1187 // Read target memory
1188 //
1189 Result = MemoryMapperReadMemorySafe(VaAddressToRead, BufferToSaveMemory, SizeToRead);
1190
1191 //
1192 // Move back to original cr3
1193 //
1194 CpuWriteCr3(OriginalCr3.Flags);
1195
1196 return Result;
1197}
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafe(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
Read memory safely by mapping the buffer (It's a wrapper).
Definition MemoryMapper.c:1123
VOID CpuWriteCr3(ULONG_PTR Cr3Value)
Write CR3.
Definition PlatformIntrinsics.c:119

◆ MemoryMapperReadMemorySafeWrapper()

_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeWrapper ( MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead,
UINT64 AddressToRead,
UINT64 BufferToSaveMemory,
SIZE_T SizeToRead,
UINT32 TargetProcessId )

Wrapper to read the memory safely by mapping the buffer by physical address (It's a wrapper).

Parameters
TypeOfReadType of read
AddressToReadAddress to read
BufferToSaveMemoryDestination to save
SizeToReadSize
TargetProcessIdThe process pid
Returns
BOOLEAN if it was successful the returns TRUE and if it was unsuccessful then it returns FALSE
995{
996 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
997 UINT64 AddressToCheck;
998 PHYSICAL_ADDRESS PhysicalAddress;
999
1000 //
1001 // Check to see if PTE and Reserved VA already initialized
1002 //
1003 if (g_MemoryMapper[CurrentCore].VirualAddressForRead == NULL64_ZERO ||
1004 g_MemoryMapper[CurrentCore].PteVirtualAddressForRead == NULL64_ZERO)
1005 {
1006 //
1007 // Not initialized
1008 //
1009 return FALSE;
1010 }
1011
1012 //
1013 // Check whether we should apply multiple accesses or not
1014 //
1015 AddressToCheck = (CHAR *)AddressToRead + SizeToRead - ((CHAR *)PAGE_ALIGN(AddressToRead));
1016
1017 if (AddressToCheck > PAGE_SIZE)
1018 {
1019 //
1020 // Address should be accessed in more than one page
1021 //
1022 UINT64 ReadSize = AddressToCheck;
1023
1024 while (SizeToRead != 0)
1025 {
1026 ReadSize = (UINT64)PAGE_ALIGN(AddressToRead + PAGE_SIZE) - AddressToRead;
1027
1028 if (ReadSize == PAGE_SIZE && SizeToRead < PAGE_SIZE)
1029 {
1030 ReadSize = SizeToRead;
1031 }
1032
1033 /*
1034 LogInfo("Addr From : %llx to Addr To : %llx | ReadSize : %llx\n",
1035 AddressToRead,
1036 AddressToRead + ReadSize,
1037 ReadSize);
1038 */
1039
1040 //
1041 // One access is enough (page+size won't pass from the PAGE_ALIGN boundary)
1042 //
1043 PhysicalAddress.QuadPart = MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker(TypeOfRead,
1044 AddressToRead,
1045 TargetProcessId);
1046
1048 PhysicalAddress,
1049 (PVOID)BufferToSaveMemory,
1050 ReadSize,
1051 g_MemoryMapper[CurrentCore].PteVirtualAddressForRead,
1052 g_MemoryMapper[CurrentCore].VirualAddressForRead,
1053 FALSE))
1054 {
1055 return FALSE;
1056 }
1057
1058 //
1059 // Apply the changes to the next addresses (if any)
1060 //
1061 SizeToRead = SizeToRead - ReadSize;
1062 AddressToRead = AddressToRead + ReadSize;
1063 BufferToSaveMemory = BufferToSaveMemory + ReadSize;
1064 }
1065
1066 return TRUE;
1067 }
1068 else
1069 {
1070 //
1071 // One access is enough (page+size won't pass from the PAGE_ALIGN boundary)
1072 //
1073 PhysicalAddress.QuadPart = MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker(TypeOfRead,
1074 AddressToRead,
1075 TargetProcessId);
1076
1078 PhysicalAddress,
1079 (PVOID)BufferToSaveMemory,
1080 SizeToRead,
1081 g_MemoryMapper[CurrentCore].PteVirtualAddressForRead,
1082 g_MemoryMapper[CurrentCore].VirualAddressForRead,
1083 FALSE);
1084 }
1085}
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafeByPte(PHYSICAL_ADDRESS PaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead, UINT64 PteVaAddress, UINT64 MappingVa, BOOLEAN InvalidateVpids)
Read memory safely by mapping the buffer using PTE.
Definition MemoryMapper.c:761
_Use_decl_annotations_ UINT64 MemoryMapperReadMemorySafeByPhysicalAddressWrapperAddressMaker(MEMORY_MAPPER_WRAPPER_FOR_MEMORY_READ TypeOfRead, UINT64 AddressToRead, UINT32 TargetProcessId)
Wrapper to read the memory safely by mapping the buffer by physical address (It's a wrapper).
Definition MemoryMapper.c:931
char CHAR
Definition BasicTypes.h:33
#define PAGE_ALIGN(Va)
Aligning a page.
Definition common.h:86

◆ MemoryMapperReadMemoryUnsafe()

_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemoryUnsafe ( UINT64 VaAddressToRead,
PVOID BufferToSaveMemory,
SIZE_T SizeToRead,
UINT32 TargetProcessId )

Read memory unsafely by mapping the buffer (It's a wrapper).

Parameters
VaAddressToReadVirtual Address to read
BufferToSaveMemoryDestination to save
SizeToReadSize
TargetProcessIdThe process pid
Returns
BOOLEAN if it was successful the returns TRUE and if it was unsuccessful then it returns FALSE
1146{
1148 VaAddressToRead,
1149 (UINT64)BufferToSaveMemory,
1150 SizeToRead,
1151 TargetProcessId);
1152}

◆ MemoryMapperReserveUsermodeAddressOnTargetProcess()

_Use_decl_annotations_ UINT64 MemoryMapperReserveUsermodeAddressOnTargetProcess ( UINT32 ProcessId,
BOOLEAN Allocate )

Reserve user mode address (not allocated) in the target user mode application.

this function should be called from vmx non-root mode

Parameters
ProcessIdTarget Process Id
AllocateWhether allocate or just reserve
Returns
Reserved address in the target user mode application
1503{
1504 NTSTATUS Status;
1505 PVOID AllocPtr = NULL;
1506 SIZE_T AllocSize = PAGE_SIZE;
1507 PEPROCESS SourceProcess;
1508 KAPC_STATE State = {0};
1509
1510 if (PsGetCurrentProcessId() != (HANDLE)ProcessId)
1511 {
1512 //
1513 // User needs another process memory
1514 //
1515
1516 if (PsLookupProcessByProcessId((HANDLE)ProcessId, &SourceProcess) != STATUS_SUCCESS)
1517 {
1518 //
1519 // if the process not found
1520 //
1521 return NULL64_ZERO;
1522 }
1523 __try
1524 {
1525 KeStackAttachProcess(SourceProcess, &State);
1526
1527 //
1528 // Allocate (not allocate, just reserve or reserve and allocate) in memory in target process
1529 //
1530 Status = ZwAllocateVirtualMemory(
1531 NtCurrentProcess(),
1532 &AllocPtr,
1533 (ULONG_PTR)NULL,
1534 &AllocSize,
1535 Allocate ? MEM_COMMIT : MEM_RESERVE,
1536 PAGE_EXECUTE_READWRITE);
1537
1538 KeUnstackDetachProcess(&State);
1539
1540 ObDereferenceObject(SourceProcess);
1541 }
1542 __except (EXCEPTION_EXECUTE_HANDLER)
1543 {
1544 KeUnstackDetachProcess(&State);
1545
1546 ObDereferenceObject(SourceProcess);
1547 return NULL64_ZERO;
1548 }
1549 }
1550 else
1551 {
1552 //
1553 // Allocate in memory in target process
1554 //
1555 Status = ZwAllocateVirtualMemory(
1556 NtCurrentProcess(),
1557 &AllocPtr,
1558 (ULONG_PTR)NULL,
1559 &AllocSize,
1560 Allocate ? MEM_COMMIT : MEM_RESERVE,
1561 PAGE_EXECUTE_READWRITE);
1562 }
1563
1564 if (!NT_SUCCESS(Status))
1565 {
1566 return NULL64_ZERO;
1567 }
1568
1569 return (UINT64)AllocPtr;
1570}

◆ MemoryMapperSetExecuteDisableToPteOnTargetProcess()

_Use_decl_annotations_ PVOID MemoryMapperSetExecuteDisableToPteOnTargetProcess ( PVOID Va,
BOOLEAN Set )

This function gets virtual address and returns its PTE of the virtual address based on the target virtual address.

the TargetCr3 should be kernel cr3 as we will use it to translate kernel addresses so the kernel functions to translate addresses should be mapped; thus, don't pass a KPTI meltdown user cr3 to this function

Parameters
VaVirtual Address
Set
Returns
PVOID virtual address of PTE based on cr3
253{
254 PPAGE_ENTRY PageEntry = NULL;
255 CR3_TYPE GuestCr3;
256 CR3_TYPE CurrentProcessCr3 = {0};
257
258 //
259 // Move to guest process as we're currently in system cr3
260 //
261
262 //
263 // Find the current process cr3
264 //
266
267 //
268 // Switch to new process's memory layout
269 // It is because, we're not trying to change the cr3 multiple times
270 // so instead of using PhysicalAddressToVirtualAddressByCr3 we use
271 // PhysicalAddressToVirtualAddress, but keep in mind that cr3 should
272 // be a kernel cr3 (not KPTI user cr3) as the functions to translate
273 // physical address to virtual address is not mapped on the user cr3
274 //
275 CurrentProcessCr3 = SwitchToProcessMemoryLayoutByCr3(GuestCr3);
276
277 //
278 // Call the wrapper
279 //
281
282 //
283 // Set execute disable bit
284 //
285 PageEntry->Fields.ExecuteDisable = Set;
286
287 //
288 // Invalidate the TLB
289 //
290 CpuInvlpg(Va);
291
292 //
293 // Restore the original process
294 //
295 SwitchToPreviousProcess(CurrentProcessCr3);
296
297 return PageEntry;
298}

◆ MemoryMapperSetSupervisorBitWithoutSwitchingByCr3()

_Use_decl_annotations_ BOOLEAN MemoryMapperSetSupervisorBitWithoutSwitchingByCr3 ( PVOID Va,
BOOLEAN Set,
PAGING_LEVEL Level,
CR3_TYPE TargetCr3 )

This function the Supervisor bit of the target PTE based on the specific cr3.

Parameters
VaVirtual Address
SetSet it to 1 or 0
LevelPMLx
TargetCr3kernel cr3 of target process
Returns
BOOLEAN whether was successful or not
1743{
1744 PPAGE_ENTRY Pml = NULL;
1745
1746 Pml = MemoryMapperGetPteVaWithoutSwitchingByCr3(Va, Level, TargetCr3);
1747
1748 if (!Pml)
1749 {
1750 return FALSE;
1751 }
1752
1753 //
1754 // Change the supervisor bit
1755 //
1756 if (Set)
1757 {
1758 Pml->Fields.Supervisor = 1;
1759 }
1760 else
1761 {
1762 Pml->Fields.Supervisor = 0;
1763 }
1764
1765 return TRUE;
1766}

◆ MemoryMapperUninitialize()

VOID MemoryMapperUninitialize ( )

uninitialize the Memory Mapper

This function should be called in vmx non-root in a IRQL <= APC_LEVEL

Returns
VOID
717{
718 ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
719
720 for (SIZE_T i = 0; i < ProcessorsCount; i++)
721 {
722 //
723 // Unmap and free the reserved buffer
724 //
725 if (g_MemoryMapper[i].VirualAddressForRead != NULL64_ZERO)
726 {
728 }
729
730 if (g_MemoryMapper[i].VirualAddressForWrite != NULL64_ZERO)
731 {
733 }
734
735 g_MemoryMapper[i].VirualAddressForRead = NULL64_ZERO;
736 g_MemoryMapper[i].PteVirtualAddressForRead = NULL64_ZERO;
737
738 g_MemoryMapper[i].VirualAddressForWrite = NULL64_ZERO;
739 g_MemoryMapper[i].PteVirtualAddressForWrite = NULL64_ZERO;
740 }
741
742 //
743 // Set the g_MemoryMapper to null
744 //
746}
_Use_decl_annotations_ VOID MemoryMapperUnmapReservedPageRange(PVOID VirtualAddress)
This function frees the memory that was previously allocated from system range (without physically al...
Definition MemoryMapper.c:591

◆ MemoryMapperUnmapReservedPageRange()

_Use_decl_annotations_ VOID MemoryMapperUnmapReservedPageRange ( PVOID VirtualAddress)

This function frees the memory that was previously allocated from system range (without physically allocating them).

Parameters
VirtualAddressVirtual Address
Returns
VOID
592{
593 MmFreeMappingAddress(VirtualAddress, POOLTAG);
594}

◆ MemoryMapperWriteMemorySafe()

_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafe ( UINT64 Destination,
PVOID Source,
SIZE_T SizeToWrite,
CR3_TYPE TargetProcessCr3 )

Write memory by mapping the buffer (It's a wrapper).

this function CAN be called from vmx-root mode

Parameters
DestinationDestination Virtual Address
SourceSource Virtual Address
SizeToWriteSize
TargetProcessCr3CR3 of target process
Returns
BOOLEAN returns TRUE if it was successful and FALSE if there was error
1433{
1435 Destination,
1436 (UINT64)Source,
1437 SizeToWrite,
1438 &TargetProcessCr3,
1439 NULL_ZERO);
1440}
_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeWrapper(MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE TypeOfWrite, UINT64 DestinationAddr, UINT64 Source, SIZE_T SizeToWrite, PCR3_TYPE TargetProcessCr3, UINT32 TargetProcessId)
Write memory safely by mapping the buffer (It's a wrapper).
Definition MemoryMapper.c:1321
@ MEMORY_MAPPER_WRAPPER_WRITE_VIRTUAL_MEMORY_SAFE
Definition MemoryMapper.h:49

◆ MemoryMapperWriteMemorySafeByPhysicalAddress()

_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeByPhysicalAddress ( UINT64 DestinationPa,
UINT64 Source,
SIZE_T SizeToWrite )

Write memory safely by mapping the buffer.

Parameters
DestinationPaDestination Physical Address
SourceSource Address
SizeToWriteSize
Returns
BOOLEAN returns TRUE if it was successful and FALSE if there was error
1480{
1481 //
1482 // Call the wrapper for safe memory read
1483 //
1485 DestinationPa,
1486 Source,
1487 SizeToWrite,
1488 NULL,
1489 NULL_ZERO);
1490}
@ MEMORY_MAPPER_WRAPPER_WRITE_PHYSICAL_MEMORY
Definition MemoryMapper.h:48

◆ MemoryMapperWriteMemorySafeByPte()

_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeByPte ( PVOID SourceVA,
PHYSICAL_ADDRESS PaAddressToWrite,
SIZE_T SizeToWrite,
UINT64 PteVaAddress,
UINT64 MappingVa,
BOOLEAN InvalidateVpids )

Write memory safely by mapping the buffer using PTE.

Parameters
SourceVASource virtual address
PaAddressToWriteDestination physical address
SizeToWriteSize
PteVaAddressPTE of target virtual address
MappingVaMapping Virtual Address
InvalidateVpidsInvalidate VPIDs or not
Returns
BOOLEAN returns TRUE if it was successful and FALSE if there was error
854{
855 PVOID NewAddress;
856 PAGE_ENTRY PageEntry;
857 PPAGE_ENTRY Pte = (PAGE_ENTRY *)PteVaAddress;
858 PVOID Va = (PVOID)MappingVa;
859
860 //
861 // Copy the previous entry into the new entry
862 //
863 PageEntry.Flags = Pte->Flags;
864
865 PageEntry.Fields.Present = 1;
866
867 //
868 // Generally we want each page to be writable
869 //
870 PageEntry.Fields.Write = 1;
871
872 //
873 // Do not flush this page from the TLB on CR3 switch, by setting the
874 // global bit in the PTE.
875 //
876 PageEntry.Fields.Global = 1;
877
878 //
879 // Set the PFN of this PTE to that of the provided physical address.
880 //
881 PageEntry.Fields.PageFrameNumber = PaAddressToWrite.QuadPart >> 12;
882
883 //
884 // Apply the page entry in a single instruction
885 //
886 Pte->Flags = PageEntry.Flags;
887
888 //
889 // Finally, invalidate the caches for the virtual address.
890 //
891 CpuInvlpg(Va);
892
893 //
894 // Also invalidate it from vpids if we're in vmx root
895 //
896 if (InvalidateVpids)
897 {
898 // __invvpid_addr(VPID_TAG, Va);
899 }
900
901 //
902 // Compute the address
903 //
904 NewAddress = (PVOID)((UINT64)Va + (PAGE_4KB_OFFSET & (PaAddressToWrite.QuadPart)));
905
906 //
907 // Move the address into the buffer in a safe manner
908 //
909 memcpy(NewAddress, SourceVA, SizeToWrite);
910
911 //
912 // Unmap Address
913 //
914 Pte->Flags = NULL64_ZERO;
915
916 return TRUE;
917}

◆ MemoryMapperWriteMemorySafeFromVmxNonRootyPhysicalAddress()

BOOLEAN MemoryMapperWriteMemorySafeFromVmxNonRootyPhysicalAddress ( UINT64 DestinationPa,
PVOID Source,
SIZE_T SizeToWrite )

Write physical memory safely from vmx non-root mode.

Parameters
DestinationVaDestination Virtual Address
SourceSource Address
SizeToWriteSize
Returns
BOOLEAN whether was successful or not
1805{
1806 if (AsmVmxVmcall(VMCALL_WRITE_PHYSICAL_MEMORY, (UINT64)DestinationPa, (UINT64)Source, (UINT64)SizeToWrite) == STATUS_SUCCESS)
1807 {
1808 return TRUE;
1809 }
1810 else
1811 {
1812 return FALSE;
1813 }
1814}
#define VMCALL_WRITE_PHYSICAL_MEMORY
VMCALL to write physical memory.
Definition Vmcall.h:321

◆ MemoryMapperWriteMemorySafeOnTargetProcess()

_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeOnTargetProcess ( UINT64 Destination,
PVOID Source,
SIZE_T Size )

Write memory safely by mapping the buffer on the target process memory (It's a wrapper).

Parameters
DestinationVirtual Address to write
Sourcevalue to write
SizeSize
Returns
BOOLEAN if it was successful the returns TRUE and if it was unsuccessful then it returns FALSE
1211{
1212 CR3_TYPE GuestCr3;
1213 CR3_TYPE OriginalCr3;
1214 BOOLEAN Result;
1215
1216 //
1217 // *** Move to guest process ***
1218 //
1219
1220 //
1221 // Find the current process cr3
1222 //
1224
1225 //
1226 // Move to new cr3
1227 //
1228 OriginalCr3.Flags = CpuReadCr3();
1229 CpuWriteCr3(GuestCr3.Flags);
1230
1231 //
1232 // Write target memory
1233 //
1234 Result = MemoryMapperWriteMemorySafe(Destination, Source, Size, GuestCr3);
1235
1236 //
1237 // Move back to original cr3
1238 //
1239 CpuWriteCr3(OriginalCr3.Flags);
1240
1241 return Result;
1242}
_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafe(UINT64 Destination, PVOID Source, SIZE_T SizeToWrite, CR3_TYPE TargetProcessCr3)
Write memory by mapping the buffer (It's a wrapper).
Definition MemoryMapper.c:1429

◆ MemoryMapperWriteMemorySafeWrapper()

_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeWrapper ( MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE TypeOfWrite,
UINT64 DestinationAddr,
UINT64 Source,
SIZE_T SizeToWrite,
PCR3_TYPE TargetProcessCr3,
UINT32 TargetProcessId )

Write memory safely by mapping the buffer (It's a wrapper).

Parameters
TypeOfWriteType of memory write
DestinationAddrDestination Address
SourceSource Address
SizeToWriteSize
TargetProcessCr3The process CR3 (might be null)
TargetProcessIdThe process PID (might be null)
Returns
BOOLEAN returns TRUE if it was successful and FALSE if there was error
1327{
1328 ULONG CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
1329 UINT64 AddressToCheck;
1330 PHYSICAL_ADDRESS PhysicalAddress;
1331
1332 //
1333 // Check to see if PTE and Reserved VA already initialized
1334 //
1335 if (g_MemoryMapper[CurrentCore].VirualAddressForWrite == NULL64_ZERO ||
1336 g_MemoryMapper[CurrentCore].PteVirtualAddressForWrite == NULL64_ZERO)
1337 {
1338 //
1339 // Not initialized
1340 //
1341 return FALSE;
1342 }
1343
1344 //
1345 // Check whether it needs multiple accesses to different pages or no
1346 //
1347 AddressToCheck = (CHAR *)DestinationAddr + SizeToWrite - ((CHAR *)PAGE_ALIGN(DestinationAddr));
1348
1349 if (AddressToCheck > PAGE_SIZE)
1350 {
1351 //
1352 // It need multiple accesses to different pages to access the memory
1353 //
1354
1355 UINT64 WriteSize = AddressToCheck;
1356
1357 while (SizeToWrite != 0)
1358 {
1359 WriteSize = (UINT64)PAGE_ALIGN(DestinationAddr + PAGE_SIZE) - DestinationAddr;
1360
1361 if (WriteSize == PAGE_SIZE && SizeToWrite < PAGE_SIZE)
1362 {
1363 WriteSize = SizeToWrite;
1364 }
1365
1366 /*
1367 LogInfo("Addr From : %llx to Addr To : %llx | WriteSize : %llx\n",
1368 DestinationAddr,
1369 DestinationAddr + WriteSize,
1370 WriteSize);
1371 */
1372
1373 PhysicalAddress.QuadPart = MemoryMapperWriteMemorySafeWrapperAddressMaker(TypeOfWrite,
1374 DestinationAddr,
1375 TargetProcessCr3,
1376 TargetProcessId);
1377
1379 (PVOID)Source,
1380 PhysicalAddress,
1381 WriteSize,
1382 g_MemoryMapper[CurrentCore].PteVirtualAddressForWrite,
1383 g_MemoryMapper[CurrentCore].VirualAddressForWrite,
1384 FALSE))
1385 {
1386 return FALSE;
1387 }
1388
1389 SizeToWrite = SizeToWrite - WriteSize;
1390 DestinationAddr = DestinationAddr + WriteSize;
1391 Source = Source + WriteSize;
1392 }
1393
1394 return TRUE;
1395 }
1396 else
1397 {
1398 //
1399 // One access is enough to write
1400 //
1401 PhysicalAddress.QuadPart = MemoryMapperWriteMemorySafeWrapperAddressMaker(TypeOfWrite,
1402 DestinationAddr,
1403 TargetProcessCr3,
1404 TargetProcessId);
1406 (PVOID)Source,
1407 PhysicalAddress,
1408 SizeToWrite,
1409 g_MemoryMapper[CurrentCore].PteVirtualAddressForWrite,
1410 g_MemoryMapper[CurrentCore].VirualAddressForWrite,
1411 FALSE);
1412 }
1413}
_Use_decl_annotations_ UINT64 MemoryMapperWriteMemorySafeWrapperAddressMaker(MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE TypeOfWrite, UINT64 DestinationAddr, PCR3_TYPE TargetProcessCr3, UINT32 TargetProcessId)
Decides about making the address and converting the address to physical address based on the passed p...
Definition MemoryMapper.c:1257
_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemorySafeByPte(PVOID SourceVA, PHYSICAL_ADDRESS PaAddressToWrite, SIZE_T SizeToWrite, UINT64 PteVaAddress, UINT64 MappingVa, BOOLEAN InvalidateVpids)
Write memory safely by mapping the buffer using PTE.
Definition MemoryMapper.c:848

◆ MemoryMapperWriteMemorySafeWrapperAddressMaker()

_Use_decl_annotations_ UINT64 MemoryMapperWriteMemorySafeWrapperAddressMaker ( MEMORY_MAPPER_WRAPPER_FOR_MEMORY_WRITE TypeOfWrite,
UINT64 DestinationAddr,
PCR3_TYPE TargetProcessCr3,
UINT32 TargetProcessId )

Decides about making the address and converting the address to physical address based on the passed parameters.

Parameters
TypeOfWriteType of memory write
DestinationAddrDestination Address
TargetProcessCr3The process CR3 (might be null)
TargetProcessIdThe process PID (might be null)
Returns
UINT64 returns the target physical address and NULL if it fails
1261{
1262 PHYSICAL_ADDRESS PhysicalAddress = {0};
1263
1264 switch (TypeOfWrite)
1265 {
1267
1268 PhysicalAddress.QuadPart = DestinationAddr;
1269
1270 break;
1271
1273
1274 if (TargetProcessId == NULL_ZERO)
1275 {
1276 PhysicalAddress.QuadPart = VirtualAddressToPhysicalAddress((PVOID)DestinationAddr);
1277 }
1278 else
1279 {
1280 PhysicalAddress.QuadPart = VirtualAddressToPhysicalAddressByProcessId((PVOID)DestinationAddr, TargetProcessId);
1281 }
1282
1283 break;
1284
1286
1287 if (TargetProcessCr3 == NULL || TargetProcessCr3->Flags == NULL64_ZERO)
1288 {
1289 PhysicalAddress.QuadPart = VirtualAddressToPhysicalAddress((PVOID)DestinationAddr);
1290 }
1291 else
1292 {
1293 PhysicalAddress.QuadPart = VirtualAddressToPhysicalAddressByProcessCr3((PVOID)DestinationAddr, *TargetProcessCr3);
1294 }
1295
1296 break;
1297
1298 default:
1299 return NULL64_ZERO;
1300
1301 break;
1302 }
1303
1304 return PhysicalAddress.QuadPart;
1305}
@ MEMORY_MAPPER_WRAPPER_WRITE_VIRTUAL_MEMORY_UNSAFE
Definition MemoryMapper.h:50
IMPORT_EXPORT_VMM UINT64 VirtualAddressToPhysicalAddressByProcessCr3(_In_ PVOID VirtualAddress, _In_ CR3_TYPE TargetCr3)

◆ MemoryMapperWriteMemoryUnsafe()

_Use_decl_annotations_ BOOLEAN MemoryMapperWriteMemoryUnsafe ( UINT64 Destination,
PVOID Source,
SIZE_T SizeToWrite,
UINT32 TargetProcessId )

Write memory safely by mapping the buffer (It's a wrapper).

this function should not be called from vmx-root mode

Parameters
DestinationDestination Virtual Address
SourceSource Virtual Address
SizeToWriteSize
TargetProcessIdTarget Process Id
Returns
BOOLEAN returns TRUE if it was successful and FALSE if there was error
1457{
1459 Destination,
1460 (UINT64)Source,
1461 SizeToWrite,
1462 NULL,
1463 TargetProcessId);
1464}