Retrieving MmPhysicalMemoryBlock regardless of the NT version.
2008-10-15 15:56
821 查看
Here is a method I’m using in the next version of Win32DD (1.2), to retrieve MmPhysicalMemoryBlock regardless of the NT Version. The main problem with KDDEBUGGER_DATA64 structure is the version dependency. Then, we have to rebuild this field by ourselves.
To retrieve physical memory runs, I’m using MmGetPhysicalMemoryRanges() *undocumented* function. This function usage had been documented by Mark Russinovich in 1999, in the Volume 1 Number 5 edition of the Sysinternals Newsletter.
Actually, this function is defined in DDK. Even if, MSDN says “The following routines are reserved for system use. Do not use them in your driver.”
#if (NTDDI_VERSION >= NTDDI_WIN2K)
NTKERNELAPI
PPHYSICAL_MEMORY_RANGE
MmGetPhysicalMemoryRanges (
VOID
);
#endif
MmPhysicalMemoryBlock is a structure that provides information regarding the physical memory ranges used by the system and also total physical memory size. These uses motivated me to write MmGetPhysicalMemoryBlock().
[…]
// NT 5.1 Addition
ULONG64 MmPhysicalMemoryBlock;
[..]
As we can read in the KDDEBUGGER_DATA64 definition, MmPhysicalMemoryBlock field is an NT 5.1 Addition.
definition.
typedef struct _PHYSICAL_MEMORY_RUN {
PFN_NUMBER BasePage;
PFN_NUMBER PageCount;
} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR {
ULONG NumberOfRuns;
PFN_NUMBER NumberOfPages; // NumberOfPages * PAGE_SIZE is physical memory size.
PHYSICAL_MEMORY_RUN Run[1]; // NumberOfRuns is the total entries.
} PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
PPHYSICAL_MEMORY_DESCRIPTOR
MmGetPhysicalMemoryBlock(
VOID
);
code.
/*++
Function Name: MmGetPhysicalMemoryBlock
Overview:
- This function aims at retrieving MmPhysicalMemoryBlock, regardless
of the host version.
The caller has to free the memory block.
Parameters:
-
Environment:
- Kernel Mode. PASSIVE_LEVEL.
Return Values:
- PPHYSICAL_MEMORY_DESCRIPTOR
–*/
PPHYSICAL_MEMORY_DESCRIPTOR
MmGetPhysicalMemoryBlock(VOID
)
{
PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
PPHYSICAL_MEMORY_RANGE MmPhysicalMemoryRange;
ULONG MemoryBlockSize;
PFN_NUMBER NumberOfPages;
ULONG NumberOfRuns;
ULONG Run;
//
// PHYSICAL_MEMORY_DESCRIPTOR isn’t exported into KDDEBUGGER_DATA64
// NT 5.0 and below. But MmGetPhysicalMemoryRanges() computes
// PHYSICAL_MEMORY_RANGE with PHYSICAL_MEMORY_DESCRIPTOR. Then,
// We can easily rewrite PHYSICAL_MEMORY_DESCRIPTOR.
//
MmPhysicalMemoryRange = MmGetPhysicalMemoryRanges();
//
// Invalid ?
//
if (MmPhysicalMemoryRange == NULL) return NULL;
//
// Compute the number of runs and the number of pages
//
NumberOfRuns = 0;
NumberOfPages = 0;
while ((MmPhysicalMemoryRange[NumberOfRuns].BaseAddress.QuadPart != 0) &&
(MmPhysicalMemoryRange[NumberOfRuns].NumberOfBytes.QuadPart != 0))
{
NumberOfRuns++;
NumberOfPages += (PFN_NUMBER)BYTES_TO_PAGES(
MmPhysicalMemoryRange[NumberOfRuns].NumberOfBytes.QuadPart);
}
//
// Invalid ?
//
if (NumberOfRuns == 0) return NULL;
//
// Compute the size of the pool to allocate and then allocate
//
MemoryBlockSize = sizeof(ULONG) +
sizeof(PFN_NUMBER) +
sizeof(PHYSICAL_MEMORY_RUN) * NumberOfRuns;
MmPhysicalMemoryBlock = ExAllocatePoolWithTag(NonPagedPool,
MemoryBlockSize,
‘ mM’);
//
// Define PHYSICAL_MEMORY_DESCRIPTOR Header.=
//
MmPhysicalMemoryBlock->NumberOfRuns = NumberOfRuns;
MmPhysicalMemoryBlock->NumberOfPages = NumberOfPages;
for (Run = 0; Run < NumberOfRuns; Run++)
{
//
// BasePage
//
MmPhysicalMemoryBlock->Run[Run].BasePage =
(PFN_NUMBER)MI_CONVERT_PHYSICAL_TO_PFN(
MmPhysicalMemoryRange[NumberOfRuns].BaseAddress.QuadPart
);
//
// PageCount
//
MmPhysicalMemoryBlock->Run[Run].PageCount =
(PFN_NUMBER)BYTES_TO_PAGES(
MmPhysicalMemoryRange[Run].NumberOfBytes.QuadPart
);
}
return MmPhysicalMemoryBlock;
}
To retrieve physical memory runs, I’m using MmGetPhysicalMemoryRanges() *undocumented* function. This function usage had been documented by Mark Russinovich in 1999, in the Volume 1 Number 5 edition of the Sysinternals Newsletter.
Actually, this function is defined in DDK. Even if, MSDN says “The following routines are reserved for system use. Do not use them in your driver.”
#if (NTDDI_VERSION >= NTDDI_WIN2K)
NTKERNELAPI
PPHYSICAL_MEMORY_RANGE
MmGetPhysicalMemoryRanges (
VOID
);
#endif
MmPhysicalMemoryBlock is a structure that provides information regarding the physical memory ranges used by the system and also total physical memory size. These uses motivated me to write MmGetPhysicalMemoryBlock().
[…]
// NT 5.1 Addition
ULONG64 MmPhysicalMemoryBlock;
[..]
As we can read in the KDDEBUGGER_DATA64 definition, MmPhysicalMemoryBlock field is an NT 5.1 Addition.
definition.
typedef struct _PHYSICAL_MEMORY_RUN {
PFN_NUMBER BasePage;
PFN_NUMBER PageCount;
} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR {
ULONG NumberOfRuns;
PFN_NUMBER NumberOfPages; // NumberOfPages * PAGE_SIZE is physical memory size.
PHYSICAL_MEMORY_RUN Run[1]; // NumberOfRuns is the total entries.
} PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
PPHYSICAL_MEMORY_DESCRIPTOR
MmGetPhysicalMemoryBlock(
VOID
);
code.
/*++
Function Name: MmGetPhysicalMemoryBlock
Overview:
- This function aims at retrieving MmPhysicalMemoryBlock, regardless
of the host version.
The caller has to free the memory block.
Parameters:
-
Environment:
- Kernel Mode. PASSIVE_LEVEL.
Return Values:
- PPHYSICAL_MEMORY_DESCRIPTOR
–*/
PPHYSICAL_MEMORY_DESCRIPTOR
MmGetPhysicalMemoryBlock(VOID
)
{
PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
PPHYSICAL_MEMORY_RANGE MmPhysicalMemoryRange;
ULONG MemoryBlockSize;
PFN_NUMBER NumberOfPages;
ULONG NumberOfRuns;
ULONG Run;
//
// PHYSICAL_MEMORY_DESCRIPTOR isn’t exported into KDDEBUGGER_DATA64
// NT 5.0 and below. But MmGetPhysicalMemoryRanges() computes
// PHYSICAL_MEMORY_RANGE with PHYSICAL_MEMORY_DESCRIPTOR. Then,
// We can easily rewrite PHYSICAL_MEMORY_DESCRIPTOR.
//
MmPhysicalMemoryRange = MmGetPhysicalMemoryRanges();
//
// Invalid ?
//
if (MmPhysicalMemoryRange == NULL) return NULL;
//
// Compute the number of runs and the number of pages
//
NumberOfRuns = 0;
NumberOfPages = 0;
while ((MmPhysicalMemoryRange[NumberOfRuns].BaseAddress.QuadPart != 0) &&
(MmPhysicalMemoryRange[NumberOfRuns].NumberOfBytes.QuadPart != 0))
{
NumberOfRuns++;
NumberOfPages += (PFN_NUMBER)BYTES_TO_PAGES(
MmPhysicalMemoryRange[NumberOfRuns].NumberOfBytes.QuadPart);
}
//
// Invalid ?
//
if (NumberOfRuns == 0) return NULL;
//
// Compute the size of the pool to allocate and then allocate
//
MemoryBlockSize = sizeof(ULONG) +
sizeof(PFN_NUMBER) +
sizeof(PHYSICAL_MEMORY_RUN) * NumberOfRuns;
MmPhysicalMemoryBlock = ExAllocatePoolWithTag(NonPagedPool,
MemoryBlockSize,
‘ mM’);
//
// Define PHYSICAL_MEMORY_DESCRIPTOR Header.=
//
MmPhysicalMemoryBlock->NumberOfRuns = NumberOfRuns;
MmPhysicalMemoryBlock->NumberOfPages = NumberOfPages;
for (Run = 0; Run < NumberOfRuns; Run++)
{
//
// BasePage
//
MmPhysicalMemoryBlock->Run[Run].BasePage =
(PFN_NUMBER)MI_CONVERT_PHYSICAL_TO_PFN(
MmPhysicalMemoryRange[NumberOfRuns].BaseAddress.QuadPart
);
//
// PageCount
//
MmPhysicalMemoryBlock->Run[Run].PageCount =
(PFN_NUMBER)BYTES_TO_PAGES(
MmPhysicalMemoryRange[Run].NumberOfBytes.QuadPart
);
}
return MmPhysicalMemoryBlock;
}
相关文章推荐
- Digital forensics of the physical memory
- My priliminary understanding of the relationship between virtual address and physical memory address
- 【redis启动失败】he Windows version of Redis allocates a memory mapped heap for sharing with the forked pr
- Java compiler level does not match the version of the installed Java project facet. map解决方法
- 解决java compiler level does not match the version of the installed java project facet
- 解决java compiler level does not match the version of the installed java project facet
- 解决java compiler level does not match the version of the installed java project facet
- TimeStamp of the Logging Application Block in EntLib 2.0
- 如何处理qq for linux Dear user.your version of the software will be obsole
- This version of android studio is incompatible with the gradle version used.
- installing the 64-bit version of the Microsoft Access Database Engine 2010 redistributable on a syst
- Flex Builder cannot locate the required debug version of the Flash Player problem
- The version of CocoaPods used to generate the lockfile (1.2.0.beta.1) is higher than the version of
- 解决java compiler level does not match the version of the installed java project facet /faceted projec
- The problem of Memory Leak
- CRT detected that the application wrote to memory after end of the head buff怎么回事
- Java compiler level does not match the version of the installed Java project
- Java compiler level does not match the version of the installed Java project facet.
- This program requires version 3.4.0 of the Protocol Buffer runtime library
- Android studio 运行出现Error running app: This version of Android Studio is incompatible with the Gradle