NTSTATUS AddHiddenPageRecord(
ULONG64
CR3,
PVOID
pHiddenPageBase, PHIDDEN_PAGE_RECORD pHiddenPageRecord)
{
KIRQL EntryIrql;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
KeAcquireSpinLock(&pHiddenPageRecord->SpinLock, &EntryIrql);
MyPrint(_TitleAndFunc
"pHiddenPageRecord->Count:%16IX\n"
, pHiddenPageRecord->Count);
if
(pHiddenPageRecord->Count == MAX_HIDDEN_PAGE_COUNT)
goto
Lable_Error;
PSPECIFIC_HIDDEN_PAGE_RECORD pCurrentRecord = &pHiddenPageRecord->Record[pHiddenPageRecord->Count];
pCurrentRecord->pPTE = pGetSpecificAddresspPTEPhysical(CR3, pHiddenPageBase);
MyPrint(_TitleAndFunc
"pCurrentRecord->pPTE:%16IX\n"
, pCurrentRecord->pPTE);
if
(pCurrentRecord->pPTE == NULL)
goto
Lable_Error;
pCurrentRecord->pHiddenBase = pHiddenPageBase;
MyPrint(_TitleAndFunc
"pCurrentRecord->pHiddenBase:%16IX\n"
, pCurrentRecord->pHiddenBase);
ContextVirtualToPhysical(&g_PhysicalOpCR3);
pCurrentRecord->OriginalPfn = pCurrentRecord->pPTE->PageFrameNumber;
ContextPhysicalToVirtual(&g_PhysicalOpCR3);
MyPrint(_TitleAndFunc
"pCurrentRecord->OriginalPfn:%16IX\n"
, pCurrentRecord->OriginalPfn);
PVOID
TemporaryVirtual = MmAllocateNonCachedMemory(PAGE_SIZE);
if
(TemporaryVirtual == NULL)
goto
Lable_Error;
PHYSICAL_ADDRESS TemporaryPhysical = MmGetPhysicalAddress(TemporaryVirtual);
LARGE_INTEGER PhysicalLength = { 0 };
PhysicalLength.QuadPart = PAGE_SIZE;
pCurrentRecord->HiddenPfn = pPhysicalAddresstoPTEPFN((
PVOID
)(TemporaryPhysical.QuadPart));
MyPrint(_TitleAndFunc
"pCurrentRecord->HiddenPfn:%16IX\n"
, pCurrentRecord->HiddenPfn);
MmFreeNonCachedMemory(TemporaryVirtual, PAGE_SIZE);
Status = MmMarkPhysicalMemoryAsBad(&TemporaryPhysical, &PhysicalLength);
ContextVirtualToPhysical(&g_PhysicalOpCR3);
RtlCopyMemory((
PVOID
)(TemporaryPhysical.QuadPart),
pCurrentRecord->pHiddenBase,
PAGE_SIZE
);
ContextPhysicalToVirtual(&g_PhysicalOpCR3);
if
(!NT_SUCCESS(Status))
goto
Lable_Error;
pHiddenPageRecord->Count++;
KeReleaseSpinLock(&pHiddenPageRecord->SpinLock, EntryIrql);
return
STATUS_SUCCESS;
Lable_Error:
KeReleaseSpinLock(&pHiddenPageRecord->SpinLock, EntryIrql);
return
STATUS_UNSUCCESSFUL;
}