Files
2023-03-30 22:49:13 +08:00

146 lines
4.3 KiB
C++

#include "pch.h"
#include "VadHelpers.h"
#include "Helpers.h"
NTSTATUS VadHelpers::GetVadCount(VadData* pData, PULONG pCount) {
NTSTATUS status = STATUS_SUCCESS;
ULONG nVads = 0;
PEPROCESS Process = nullptr;
status = PsLookupProcessByProcessId(UlongToHandle(pData->Pid), &Process);
if (NT_SUCCESS(status)) {
switch (pData->VadCountPos)
{
case VadCountPos::NumberGenericTableElements:
{
PUCHAR pTable = (PUCHAR)Process + pData->EprocessOffsets.VadRoot;
PUCHAR pNumberGenericElements = (PUCHAR)pTable + pData->TableOffsets.NumberGenericTableElements;
PUCHAR readAddr = pNumberGenericElements;
readAddr += (pData->TableOffsets.BitField.Position / 8);
ULONG readSz = (pData->TableOffsets.BitField.Position % 8 + pData->TableOffsets.BitField.Size
+ 7) / 8;
ULONG64 readBits;
ULONG64 bitCopy;
RtlCopyMemory(&readBits, readAddr, readSz);
readBits = readBits >> (pData->TableOffsets.BitField.Position % 8);
bitCopy = ((ULONG64)1 << pData->TableOffsets.BitField.Size);
bitCopy -= (ULONG64)1;
readBits &= bitCopy;
*pCount = readBits;
break;
}
case VadCountPos::NumberOfVads:
{
PULONG pNumberOfVads = (PULONG)((PUCHAR)Process + pData->EprocessOffsets.NumberOfVads);
*pCount = *pNumberOfVads;
break;
}
case VadCountPos::VadCount:
{
PULONG pVadCount = (PULONG)((PUCHAR)Process + pData->EprocessOffsets.VadCount);
*pCount = *pVadCount;
break;
}
default:
status = STATUS_UNKNOWN_REVISION;
break;
}
ObDereferenceObject(Process);
}
return status;
}
NTSTATUS VadHelpers::DumpsAllVadsForProcess(VadData* pData, VadInfo* pInfo) {
ULONG64 Next;
ULONG64 VadToDump;
ULONG64 ParentStored;
ULONG64 First;
ULONG64 Left;
ULONG64 Prev;
ULONG Flags;
ULONG Done;
ULONG Level = 0;
ULONG Count = 0;
ULONG AverageLevel = 0;
ULONG MaxLevel = 0;
ULONG VadFlagsPrivateMemory = 0, VadFlagsNoChange = 0;
ULONG PhysicalMapping = 0, ImageMap = 0, NoChange = 0, LargePages = 0, MemCommit = 0,
PrivateMemory = 0, Protection = 0;
ULONG64 StartingVpn = 0, EndingVpn = 0, Parent = 0, LeftChild = 0, RightChild = 0;
ULONG64 ControlArea = 0, FirstPrototypePte = 0, LastContiguousPte = 0, CommitCharge = 0;
VadToDump = 0;
Flags = 0;
PEPROCESS Process = nullptr;
NTSTATUS status = PsLookupProcessByProcessId(UlongToHandle(pData->Pid), &Process);
if (NT_SUCCESS(status)) {
do
{
VadToDump = (ULONG64)Process + pData->EprocessOffsets.VadRoot;
if (VadToDump == 0) {
status = STATUS_INVALID_PARAMETER;
break;
}
First = VadToDump;
if (First == 0) {
status = STATUS_INVALID_PARAMETER;
break;
}
PUCHAR readAddr = (PUCHAR)VadToDump + pData->VadFlagsOffsets.PrivateMemory;
VadFlagsPrivateMemory = Helpers::ReadBitField(readAddr, &pData->VadFlagsOffsets.PrivateMemoryBitField);
readAddr = (PUCHAR)VadToDump + pData->VadFlagsOffsets.NoChange;
VadFlagsNoChange = Helpers::ReadBitField(readAddr, &pData->VadFlagsOffsets.NoChangeBitField);
readAddr = (PUCHAR)VadToDump + pData->VadShortOffsets.StartingVpn;
ULONG readSz = pData->VadShortOffsets.VpnSize;
StartingVpn = Helpers::ReadFieldValue(readAddr, readSz);
readAddr = (PUCHAR)VadToDump + pData->VadShortOffsets.EndingVpn;
EndingVpn = Helpers::ReadFieldValue(readAddr, readSz);
readAddr = (PUCHAR)VadToDump + pData->VadShortOffsets.LeftChild;
readSz = pData->VadShortOffsets.ChildSize;
LeftChild = Helpers::ReadFieldValue(readAddr, readSz);
readAddr = (PUCHAR)VadToDump + pData->VadShortOffsets.RightChild;
RightChild = Helpers::ReadFieldValue(readAddr, readSz);
readAddr = (PUCHAR)VadToDump + pData->VadFlagsOffsets.CommitCharge;
CommitCharge = Helpers::ReadBitField(readAddr, &pData->VadFlagsOffsets.CommitChargeBitField);
Prev = First;
while (LeftChild != 0) {
Prev = First;
First = LeftChild;
Level += 1;
if (Level > MaxLevel) {
MaxLevel = Level;
}
readAddr = (PUCHAR)First + pData->VadShortOffsets.LeftChild;
readSz = pData->VadShortOffsets.ChildSize;
LeftChild = Helpers::ReadFieldValue(readAddr, readSz);
}
readAddr = (PUCHAR)First + pData->VadShortOffsets.StartingVpn;
readSz = pData->VadShortOffsets.VpnSize;
StartingVpn = Helpers::ReadFieldValue(readAddr, readSz);
} while (false);
ObDereferenceObject(Process);
}
return status;
}