33 if (NULL == OffsetsCount)
38 if (NULL == OffsetsTrace)
47 OffsetsTrace[count++] = 8ull *
PML5_INDEX(VirtualAddress);
48 OffsetsTrace[count++] = 8ull *
PML4_INDEX(VirtualAddress);
49 OffsetsTrace[count++] = 8ull *
PDP_INDEX(VirtualAddress);
50 OffsetsTrace[count++] = 8ull *
PD_INDEX(VirtualAddress);
51 OffsetsTrace[count++] = 8ull *
PT_INDEX(VirtualAddress);
55 OffsetsTrace[count++] = 8ull *
PML4_INDEX(VirtualAddress);
56 OffsetsTrace[count++] = 8ull *
PDP_INDEX(VirtualAddress);
57 OffsetsTrace[count++] = 8ull *
PD_INDEX(VirtualAddress);
58 OffsetsTrace[count++] = 8ull *
PT_INDEX(VirtualAddress);
65 OffsetsTrace[count++] = 8ull * (((
DWORD)VirtualAddress & 0xC0000000) >> 30);
66 OffsetsTrace[count++] = 8ull *
PD_INDEX(VirtualAddress);
67 OffsetsTrace[count++] = 8ull *
PT_INDEX(VirtualAddress);
72 OffsetsTrace[count++] = 4ull *
PD32_INDEX(VirtualAddress);
73 OffsetsTrace[count++] = 4ull *
PT32_INDEX(VirtualAddress);
77 *OffsetsCount = count;
111 QWORD localVirtualAddress;
114 if (0 == CurrentPage)
136 localVirtualAddress =
PAGE_SX(VirtualAddress | ((
QWORD)i << (12 + (9 * (Level - 1)))));
142 status = Callback(Cr3, localVirtualAddress, pPage[i],
PAGE_SIZE_4K);
144 else if ((2 == Level) && (0 != (pPage[i] &
PD_PS)))
146 status = Callback(Cr3, localVirtualAddress, pPage[i],
PAGE_SIZE_2M);
148 else if ((3 == Level) && (0 != (pPage[i] &
PDP_PS)))
150 status = Callback(Cr3, localVirtualAddress, pPage[i],
PAGE_SIZE_1G);
152 else if ((4 == Level) && (0 != (pPage[i] & PDP_PS)))
154 status = Callback(Cr3, localVirtualAddress, pPage[i], 512 *
PAGE_SIZE_1G);
183 localVirtualAddress =
PAGE_SX(VirtualAddress | ((
QWORD)i << (12 + (9 * (Level - 1)))));
187 if ((pPage[i] &
PHYS_PAGE_MASK) == (CurrentPage & PHYS_PAGE_MASK))
195 status = Callback(Cr3, localVirtualAddress, pPage[i],
PAGE_SIZE_4K);
197 else if ((2 == Level) && (0 != (pPage[i] &
PD_PS)))
199 status = Callback(Cr3, localVirtualAddress, pPage[i],
PAGE_SIZE_2M);
201 else if ((3 == Level) && (0 != (pPage[i] &
PDP_PS)))
203 status = Callback(Cr3, localVirtualAddress, pPage[i],
PAGE_SIZE_1G);
209 pPage[i] & PHYS_PAGE_MASK,
239 localVirtualAddress = ((
DWORD)VirtualAddress | (i << (12 + (9 * (Level - 1)))));
251 status = Callback(Cr3, localVirtualAddress, pPage[i],
PAGE_SIZE_4K);
253 else if ((2 == Level) && (0 != (pPage[i] &
PD_PS)))
255 status = Callback(Cr3, localVirtualAddress, pPage[i],
PAGE_SIZE_2M);
261 pPage[i] & PHYS_PAGE_MASK,
284 localVirtualAddress = ((
DWORD)VirtualAddress | (i << (12 + (10 * (Level - 1)))));
296 status = Callback(Cr3, localVirtualAddress, pPage[i],
PAGE_SIZE_4K);
298 else if ((2 == Level) && (0 != (pPage[i] &
PD_PS)))
300 status = Callback(Cr3, localVirtualAddress, pPage[i],
PAGE_SIZE_4M);
306 pPage[i] & PHYS_PAGE_MASK,
346 QWORD efer, cr0, cr4;
353 if (NULL == Callback)
384 else if (0 != (efer & EFER_LMA))
392 else if (0 != (cr0 &
CR0_PG))
447 ERROR(
"[ERROR] IntTranslateVirtualAddressEx failed: 0x%08x\n", status);
454 ERROR(
"[ERROR] Page %llx is not present!\n", va);
461 ERROR(
"[ERROR] Page %llx is not writable!\n", va);
466 if ((0 == Ring) && tr.
IsUser)
468 ERROR(
"[ERROR] Page %llx is not a kernel page!\n", va);
472 if ((3 == Ring) && !tr.
IsUser)
474 ERROR(
"[ERROR] Page %llx is not a user page!\n", va);
482 ERROR(
"[ERROR] IntHookGpaGetEPTPageProtection failed: 0x%08x\n", status);
488 ERROR(
"[ERROR] Page %llx is not a writable in EPT!\n", va);
527 DWORD pagesCount, i, left, offset;
542 if (VirtualAddress + Size - 1 < VirtualAddress)
565 ERROR(
"[ERROR] IntIcFlush failed: 0x%08x\n", status);
574 ERROR(
"[ERROR] IntCr3Read failed: 0x%08x\n", status);
575 goto cleanup_and_exit;
579 for (va = VirtualAddress &
PAGE_MASK; va <= VirtualAddress + Size - 1; va +=
PAGE_SIZE)
585 ERROR(
"[ERROR] IntTranslateVirtualAddressEx failed: 0x%08x\n", status);
586 goto cleanup_and_exit;
592 ERROR(
"[ERROR] Page %llx is not present!\n", va);
594 goto cleanup_and_exit;
600 ERROR(
"[ERROR] Page %llx is not writable!\n", va);
602 goto cleanup_and_exit;
607 if ((0 == Ring) && tr.
IsUser)
609 ERROR(
"[ERROR] Page %llx is not a kernel page!\n", va);
611 goto cleanup_and_exit;
614 if ((3 == Ring) && !tr.
IsUser)
616 ERROR(
"[ERROR] Page %llx is not a user page!\n", va);
618 goto cleanup_and_exit;
625 ERROR(
"[ERROR] IntHookGpaGetEPTPageProtection failed: 0x%08x\n", status);
626 goto cleanup_and_exit;
638 ERROR(
"[ERROR] IntHookGpaIsPageHooked failed: 0x%08x\n", status);
639 goto cleanup_and_exit;
646 goto cleanup_and_exit;
653 ERROR(
"[ERROR] IntPhysMemMap failed: 0x%08x\n", status);
654 goto cleanup_and_exit;
659 pbuf = (
PBYTE)Buffer;
665 pa[0] += VirtualAddress & 0xFFF;
671 memcpy(pa[i++], pbuf + offset, currentSize);
677 offset += currentSize;
680 pa[0] -= VirtualAddress & 0xFFF;
687 for (i = 0; i < pagesCount; i++)
#define INT_STATUS_ACCESS_DENIED
#define INT_STATUS_PAGE_NOT_PRESENT
Indicates that a virtual address is not present.
QWORD PhysicalAddress
The physical address to which VirtualAddress translates to.
#define INT_STATUS_SUCCESS
INTSTATUS IntIterateVirtualAddressSpace(QWORD Cr3, PFUNC_VirtualAddressSpaceCallback Callback)
Iterate an entire virtual address space.
#define PAGE_REMAINING(addr)
BOOLEAN IsWritable
True if this page is writable.
static INTSTATUS IntIterateVirtualAddressSpaceRec(QWORD VirtualAddress, QWORD Cr3, QWORD CurrentPage, BYTE PagingMode, BYTE Level, PFUNC_VirtualAddressSpaceCallback Callback)
Iterate, recursively, an entire virtual address space.
INTSTATUS(* PFUNC_VirtualAddressSpaceCallback)(QWORD Cr3, QWORD VirtualAddress, QWORD Entry, QWORD PageSize)
The type of callback invoked by PFUNC_IntIterateVaSpace while iterating the guest virtual address spa...
#define INT_SUCCESS(Status)
INTSTATUS IntHookGpaIsPageHooked(QWORD Gpa, BYTE *Read, BYTE *Write, BYTE *Execute)
Get the read, write and execute access for the given guest physical page.
INTSTATUS IntHookGpaGetEPTPageProtection(DWORD EptIndex, QWORD Address, BYTE *Read, BYTE *Write, BYTE *Execute)
Get the EPT page protection for the indicated guest physical address.
#define HpAllocWithTag(Len, Tag)
int INTSTATUS
The status data type.
#define TRFLG_NONE
No special options.
#define _Out_writes_(expr)
INTSTATUS IntValidateRangeForWrite(QWORD Cr3, QWORD VirtualAddress, DWORD Size, DWORD Ring)
Validate a range of virtual memory for write.
QWORD Flags
The entry that maps VirtualAddress to PhysicalAddress, together with all the control bits...
#define IG_CURRENT_VCPU
For APIs that take a VCPU number as a parameter, this can be used to specify that the current VCPU sh...
BOOLEAN PaeEnabled
True if Physical Address Extension is enabled.
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
INTSTATUS IntCr0Read(DWORD CpuNumber, QWORD *Cr0Value)
Reads the value of the guest CR0.
#define INT_STATUS_INVALID_PARAMETER_4
INTSTATUS IntSplitVirtualAddress(QWORD VirtualAddress, DWORD *OffsetsCount, QWORD *OffsetsTrace)
Split a linear address into page-table indexes.
#define HpFreeAndNullWithTag(Add, Tag)
#define INT_STATUS_INVALID_PARAMETER_5
INTSTATUS IntTranslateVirtualAddressEx(QWORD Gva, QWORD Cr3, DWORD Flags, VA_TRANSLATION *Translation)
Translates a guest virtual address to a guest physical address.
void * InstructionCache
The currently used instructions cache.
INTSTATUS IntVirtMemSafeWrite(QWORD Cr3, QWORD VirtualAddress, DWORD Size, void *Buffer, DWORD Ring)
Safely modify guest memory.
#define _In_reads_bytes_(expr)
GUEST_STATE gGuest
The current guest state.
INTSTATUS IntIcFlush(PINS_CACHE Cache)
Flush the entire instruction cache.
BOOLEAN LA57
True if 5-level paging is being used.
INTSTATUS IntCr3Read(DWORD CpuNumber, QWORD *Cr3Value)
Reads the value of the guest CR3.
INTSTATUS IntCr4Read(DWORD CpuNumber, QWORD *Cr4Value)
Reads the value of the guest CR4.
__must_check INTSTATUS IntPhysMemMap(QWORD PhysAddress, DWORD Length, DWORD Flags, void **HostPtr)
Maps a guest physical address inside Introcore VA space.
Encapsulates information about a virtual to physical memory translation.
#define INT_STATUS_INVALID_PARAMETER_1
#define INT_STATUS_NOT_SUPPORTED
unsigned long long * PQWORD
INTSTATUS IntPhysMemUnmap(void **HostPtr)
Unmaps an address previously mapped with IntPhysMemMap.
BOOLEAN IsUser
True if this page is accessible to user mode code.
DWORD UntrustedEptIndex
The EPTP index of the untrusted EPT.
#define INT_STATUS_INVALID_PARAMETER_2
INTSTATUS IntEferRead(QWORD CpuNumber, QWORD *Efer)
Reads the value of the guest IA32 EFER MSR.
#define MAX_TRANSLATION_DEPTH
Maximum depth of the translation hierarchy.
#define INT_STATUS_INSUFFICIENT_RESOURCES
#define INT_STATUS_INVALID_PARAMETER_3