Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nmulasmajic/56007f5dfd92a4c78b3a904add5a18f9 to your computer and use it in GitHub Desktop.
Save nmulasmajic/56007f5dfd92a4c78b3a904add5a18f9 to your computer and use it in GitHub Desktop.
// Get the process that we are currently executing in.
CurrentProcess = CurrentThread->Tcb.ApcState.Process;
// Is the current process the one we're reading memory from?
if ( CurrentProcess == FromProcess )
{
ApcState_FromProcess.Process = NULL;
}
else
{
// It's not, so we will swap to that process context.
KiStackAttachProcess(FromProcess, 0, &ApcState_FromProcess);
}
EnclaveVad = NULL;
// Is there a valid pointer here? If not, we skip VAD iteration.
if ( !FromProcess->Vm.Instance.VmWorkingSetList[3].LastAccessClearingRemainder )
{
NumberOfBytesIntoFromAddress = BufferLength;
goto SkipVadIteration;
}
// Acquire a lock on the "FromProcess"' address space. This'll disallow memory
// allocations, frees, and more.
LOCK_ADDRESS_SPACE(CurrentThread, FromProcess);
// Start at the root node.
CurrentVadEntry = (_MMVAD *)FromProcess->VadRoot.Root;
bStoppedOnRightNode = FALSE;
bFoundVadEntry = FALSE;
// Do we have a root node? If not, skip this logic.
if ( !CurrentVadEntry )
goto VadNoRoot;
// Find the VAD entry corresponding to the address we're copying from.
VirtualPageFrameNumber = (FromAddress >> 12) /* This strips off the offset from the address. */;
// Walk the right nodes.
while ( VirtualPageFrameNumber >
/* This will take into consideration the "High" byte that's saved in the VAD when using the "Virtual Page Number"
* (Vpn) address. */
(CurrentVadEntry->Core.EndingVpn | ((unsigned __int64)CurrentVadEntry->Core.EndingVpnHigh << 32)) )
{
// Walk the right nodes.
NewVadEntry = (_MMVAD *)CurrentVadEntry->Core.VadNode.Right;
// The right node doesn't exist.
if ( !NewVadEntry )
{
// Signal that we stopped during a walk of the right nodes.
bStoppedOnRightNode = TRUE;
goto VadNoRoot;
}
WalkRight:
// Keep iterating.
CurrentVadEntry = NewVadEntry;
}
// Walk a left node (this isn't a loop).
if ( VirtualPageFrameNumber <
(CurrentVadEntry->Core.StartingVpn | ((unsigned __int64)CurrentVadEntry->Core.StartingVpnHigh << 32)) )
{
NewVadEntry = (_MMVAD *)CurrentVadEntry->Core.VadNode.Left;
if ( !NewVadEntry )
{
// Signal that we stopped during a walk of the left nodes.
bStoppedOnRightNode = FALSE;
goto VadNoRoot;
}
// Go back to iterating the right nodes.
goto WalkRight;
}
// At this point we're done walking both the left nodes and the right nodes.
bFoundVadEntry = TRUE;
VadNoRoot:
// Did we find a VAD entry corresponding to the target VirtualPageFrameNumber?
if ( bFoundVadEntry )
{
if ( CurrentVadEntry->Core.u.VadFlags.VadType != VadAwe /* 3 */ )
goto NotVadAwe_Or_NotEnclave;
VadFlags = CurrentVadEntry->Core.u.VadFlags;
// Is the Enclave bit set?
if (!_bittest((const signed int *)&VadFlags, 18u))
goto NotVadAwe_Or_NotEnclave;
EnclaveVad = CurrentVadEntry;
// If bit 1 is set of the LastContiguousPte, it means it's not the appropriate
// type.
if ( CurrentVadEntry->LastContiguousPte & 2 )
goto NotVadAwe_Or_NotEnclave;
EnclaveVad = NULL;
}
else /* We didn't find a VAD entry. */
{
// Did we stop on the right-node walk?
if ( bStoppedOnRightNode )
{
OriginalVadEntry = CurrentVadEntry;
RightVadChildEntry = CurrentVadEntry->Core.VadNode.Right;
// I don't think this will ever be true.
if ( RightVadChildEntry )
{
CurrentVadEntry = (_MMVAD *)CurrentVadEntry->Core.VadNode.Right;
for ( i = (_MMVAD *)RightVadChildEntry->Left; i; i = (_MMVAD *)i->Core.VadNode.Left )
CurrentVadEntry = i;
}
}
else
{
for ( CurrentVadEntry = (_MMVAD *)(CurrentVadEntry->Core.VadNode.ParentValue & 0xFFFFFFFFFFFFFFFCui64);
CurrentVadEntry;
CurrentVadEntry = (_MMVAD *)(CurrentVadEntry->Core.VadNode.ParentValue & 0xFFFFFFFFFFFFFFFCui64) )
{
if ( (_MMVAD *)CurrentVadEntry->Core.VadNode.Left == OriginalVadEntry )
break;
OriginalVadEntry = CurrentVadEntry;
}
}
NotVadAwe_Or_NotEnclave:
if ( EnclaveVad )
{
NumberOfBytesIntoFromAddress = (((EnclaveVad->Core.EndingVpn | ((unsigned __int64)(unsigned __int8)EnclaveVad->Core.EndingVpnHigh << 32)) << 12) | 0xFFF)
- FromAddress
+ 1;
goto DoneWithVadIteration;
}
}
// Did we find a valid Vad node now?
if ( !CurrentVadEntry )
goto NoVadRootNode;
do
{
VadEntry = CurrentVadEntry;
// This logic is similar to the one above, so it will not be documented as
// thoroughly. It's important to note that this is most likely a function that
// has been inlined multiple times.
if ( CurrentVadEntry->Core.u.VadFlags.VadType == VadAwe )
{
VadFlags = CurrentVadEntry->Core.u.LongFlags;
// Enclave bit check again.
if ( _bittest((const signed int *)&VadFlags, 18u) )
{
EnclaveVad = CurrentVadEntry;
if ( CurrentVadEntry->LastContiguousPte & 2 )
break;
EnclaveVad = NULL;
}
}
if ((CurrentVadEntry->Core.EndingVpn | ((unsigned __int64)(unsigned __int8)CurrentVadEntry->Core.EndingVpnHigh << 32)) >= (FromAddress + BufferLength - 1) >> 12 )
goto NoVadRootNode;
TemporaryEntry = CurrentVadEntry;
RightVadChildEntry = CurrentVadEntry->Core.VadNode.Right;
if ( RightVadChildEntry )
{
CurrentVadEntry = (_MMVAD *)CurrentVadEntry->Core.VadNode.Right;
for ( j = (_MMVAD *)RightVadChildEntry->Left; j; j = (_MMVAD *)j->Core.VadNode.Left )
CurrentVadEntry = j;
}
else
{
for ( CurrentVadEntry = (_MMVAD *)(CurrentVadEntry->Core.VadNode.ParentValue & 0xFFFFFFFFFFFFFFFCui64);
CurrentVadEntry;
CurrentVadEntry = (_MMVAD *)(CurrentVadEntry->Core.VadNode.ParentValue & 0xFFFFFFFFFFFFFFFCui64) )
{
if ( (_MMVAD *)CurrentVadEntry->Core.VadNode.Left == TemporaryEntry )
break;
TemporaryEntry = CurrentVadEntry;
}
}
} while ( CurrentVadEntry );
if ( CurrentVadEntry )
{
NumberOfBytesIntoFromAddress = ((VadEntry->Core.StartingVpn | ((unsigned __int64)(unsigned __int8)VadEntry->Core.StartingVpnHigh << 32)) << 12) - FromAddress;
}
else
{
NoVadRootNode:
NumberOfBytesIntoFromAddress = BufferLength;
}
DoneWithVadIteration:
// Release lock.
UNLOCK_ADDRESS_SPACE(CurrentThread, FromProcess);
SkipVadIteration:
// Detach from process context, if needed.
if ( CurrentProcess != FromProcess )
KiUnstackDetachProcess(&ApcState_FromProcess, 0i64);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment