For a start look on Ms-Rem Extreme dumper (in attach). Forensic tools usually works with dumps of physical memory. For this approach see
(also it has link to win32dd).
Code: Select allNTSTATUS MmGenerateFullMemoryDump (IN PUNICODE_STRING OutputFileName)
{
UNICODE_STRING PhysicalMemoryDevice;
OBJECT_ATTRIBUTES MemoryAttributes, DumpFileAttributes;
SYSTEM_BASIC_INFORMATION SystemBasicInfo;
HANDLE MemoryHandle;
HANDLE DumpFileHandle;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER ViewBase;
NTSTATUS Status;
ULONG PageIndex;
SIZE_T ViewSize;
PUCHAR Buffer;
PCHAR NullPage;
PEPROCESS Process;
ACCESS_MASK DesiredSectionAccess;
ULONG ProtectMaskForAccess;
PSECTION Section;
RtlInitUnicodeString(&PhysicalMemoryDevice, L"\\Device\\PhysicalMemory");
InitializeObjectAttributes(&MemoryAttributes,
&PhysicalMemoryDevice,
OBJ_CASE_INSENSITIVE,
(HANDLE) NULL,
NULL);
InitializeObjectAttributes(&DumpFileAttributes,
OutputFileName,
OBJ_KERNEL_HANDLE,
(HANDLE) NULL,
NULL);
MemoryHandle = 0;
Status = ObOpenObjectByName(&MemoryAttributes,
MmSectionObjectType,
KernelMode,
NULL,
SECTION_MAP_READ,
NULL,
&MemoryHandle);
if ( !NT_SUCCESS(Status) )
{
return STATUS_ACCESS_DENIED;
}
Status = ZwQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo,
sizeof(SYSTEM_BASIC_INFORMATION), 0);
if ( !NT_SUCCESS(Status) )
{
goto Exit;
}
if ( SystemBasicInfo.PhysicalPageSize == PAGE_SIZE )
{
Status = ZwCreateFile(&DumpFileHandle,
FILE_WRITE_ACCESS | SYNCHRONIZE,
&DumpFileAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_SUPERSEDE,
FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if ( NT_SUCCESS(Status) )
{
ViewBase.LowPart = 0;
ViewBase.HighPart = 0;
NullPage = (PCHAR)ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, 'pmuD');
if (NullPage)
{
memzero(NullPage, PAGE_SIZE);
Process = IoGetCurrentProcess();
ProtectMaskForAccess = MiMakeProtectionMask(PAGE_READONLY);
ProtectMaskForAccess = ProtectMaskForAccess & 0x7;
DesiredSectionAccess = MmMakeSectionAccess[ProtectMaskForAccess];
Status = ObReferenceObjectByHandle(MemoryHandle,
DesiredSectionAccess,
MmSectionObjectType,
KernelMode,
(PVOID *)&Section,
NULL);
if ( NT_SUCCESS(Status) )
{
for (PageIndex = 0; PageIndex < SystemBasicInfo.NumberOfPhysicalPages; PageIndex++)
{
Buffer = NULL;
ViewSize = PAGE_SIZE;
Status = MmMapViewOfSection((PVOID)Section,
Process,
(PVOID *)&Buffer,
0L,
PAGE_SIZE,
&ViewBase,
&ViewSize,
ViewUnmap,
0,
PAGE_READONLY);
if ( !NT_SUCCESS(Status) )
{
if (PageIndex > 0)
{
Status = ZwWriteFile(DumpFileHandle, 0, 0, 0,
&IoStatusBlock, NullPage, PAGE_SIZE, &ViewBase, 0);
ViewBase.LowPart += PAGE_SIZE;
continue;
}
break;
}
Status = ZwWriteFile(DumpFileHandle, 0, 0, 0,
&IoStatusBlock, Buffer, PAGE_SIZE, &ViewBase, 0);
if ( !NT_SUCCESS(Status) )
{
MmUnmapViewOfSection(Process, Buffer);
break;
}
MmUnmapViewOfSection(Process, Buffer);
ViewBase.LowPart += PAGE_SIZE;
}
if (PageIndex == SystemBasicInfo.NumberOfPhysicalPages) Status = STATUS_SUCCESS;
ObfDereferenceObject(Section);
}
ExFreePoolWithTag(NullPage, 'pmuD');
}
//ExAllocatePoolWithTag
ZwClose(DumpFileHandle);
} //ZwCreateFile
}
Exit:
ZwClose(MemoryHandle);
return Status;
}