📄 vmqueryimpl.pas
字号:
unit VMQueryImpl;
interface
uses
Windows, SysUtils, Classes, Dialogs;
const
Delimiter = '|'; { Separate every part of the information string }
type
// Callback function of VirtualMemoryWalk function which outputs Buffer in specific window or component.
// Buffer format:
// <BaseAddress(Hex)>|<(Region/Block)Pages(4KB)>|<BlocksCount>|<(Region/Block)State(Commit/Free/Reserve)>|<(Region/Block)Type(Private/Image/Mapped)>|<PageAttributes(Read/Write/Execute/etc.)>|<Description>#0#0
TVirtualMemoryWalkerCallback = procedure (Buffer: PChar; BufferSize: DWORD); stdcall;
// Virtual memory information record, which extends the TMemoryBasicInformation record defined in Windows unit.
PVirtualMemoryInformation = ^TVirtualMemoryInformation;
TVirtualMemoryInformation = packed record
// Region Information
{ Pointer to the base address of the region of pages. }
RegionBaseAddress: Pointer;
{ Pointer to the base address of a range of pages allocated by the VirtualAlloc function. }
{ The page pointed to by the BaseAddress member is contained within this allocation range. }
RegionAllocationBase: Pointer;
{ Specifies the access protection given when the region was initially allocated. }
{ This member can be one of the following values, along with PAGE_GUARD and PAGE_NOCACHE. }
{ PAGE_READONLY, PAGE_READWRITE, PAGE_WRITECOPY, PAGE_EXECUTE, PAGE_EXECUTE_READ, }
{ PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY, PAGE_GUARD, PAGE_NOACCESS, or PAGE_NOCACHE }
RegionAllocationProtect: DWORD;
{ Specifies the size, in bytes, of the region beginning at the base address }
{ in which all pages have identical attributes. }
RegionSize: DWORD;
{ Specifies the state of the pages in the region. One of the following states is indicated. }
{ MEM_COMMIT, MEM_FREE, or MEM_RESERVE }
RegionState: DWORD;
{ Specifies the access protection of the pages in the region. }
{ One of the values listed for the AllocationProtect member is specified. }
RegionProtect: DWORD;
{ Specifies the type of pages in the region. The following types are defined. }
{ MEM_IMAGE, MEM_MAPPED, or MEM_PRIVATE }
RegionType: DWORD;
// Block Information
{ Pointer to the base address of the block of the region of pages. }
BlockBaseAddress: Pointer;
{ Specifies the number of blocks in the region of pages. }
BlocksCount: DWORD;
{ Specifies the number of blocks with PAGE_GUARD protect flag in the region of pages. }
BlocksCountWithPageGuard: DWORD;
{ Specifies the size, in bytes, of the block beginning at the base address }
{ in which all pages have identical attributes. }
BlockSize: DWORD;
{ Specifies the access protection of the pages in the block. }
{ One of the values listed for the AllocationProtect member is specified. }
BlockProtect: DWORD;
{ Specifies the state of the pages in the block. One of the following states is indicated. }
{ MEM_COMMIT, MEM_FREE, or MEM_RESERVE }
BlockState: DWORD;
{ Specifies the type of pages in the block. The following types are defined. }
{ MEM_IMAGE, MEM_MAPPED, or MEM_PRIVATE }
BlockType: DWORD;
end;
//var
// PageSize: DWORD = 0;
// AllocationGranularity: DWORD = 0;
// Get the page size of memory under specific CPU architecture
function GetPageSize(): DWORD; stdcall;
// Get the allocation granularity of memory under specific CPU architecture
function GetAllocationGranularity(): DWORD; stdcall;
// Convert a TVirtualMemoryInformation record to a null-terminated string
procedure GetMemoryInformation(
VMI: TVirtualMemoryInformation; { Information buffer }
var Buffer: PChar; var BufferSize: DWORD; { Converted string information buffer and its size }
Expanded: Boolean { If True, show expanded block information, otherwise just show region information }
); stdcall;
// Virtual memory query function
// If succeed, the return value is True, otherwise False.
function VirtualMemoryQuery(
Address: Pointer; { Base address of the block }
PVMI: PVirtualMemoryInformation; { Information buffer }
Length: DWORD { Size of the information buffer }
): BOOL; stdcall;
// Virtual memory walk function
// Iterate in the process space to get information of every region and its every block.
// If succeed, the return value is True, otherwise False.
function VirtualMemoryWalk(
VirtualMemoryWalker: TVirtualMemoryWalkerCallback; { Callback function of VirtualMemoryQuery }
Detailed: Boolean = True { If True, show detailed every block info of every region; otherwise show only region info }
): BOOL; stdcall;
function VMWalk(Detailed: Boolean = True): BOOL; stdcall;
implementation
uses
JuSectionObjs;
const
SReturnedInfoMemMapping = 'JuMemMapping.ReturnedInfo';
type
PReturnedInfo = ^TReturnedInfo;
TReturnedInfo = record
Size: Cardinal;
Data: array [0..64 * 1024 - 5] of Char;
end;
function GetAllocationGranularity(): DWORD; stdcall;
var
SI: TSystemInfo;
begin
GetSystemInfo(SI);
Result := SI.dwAllocationGranularity;
end;
function GetPageSize(): DWORD; stdcall;
var
SI: TSystemInfo;
begin
GetSystemInfo(SI);
Result := SI.dwPageSize;
end;
procedure GetMemoryInformation(VMI: TVirtualMemoryInformation; var Buffer: PChar; var BufferSize: DWORD; Expanded: Boolean); stdcall;
var
LInfoStr: string;
LBuffer: PChar;
LBufferSize: DWORD;
function GetRegionInformation(): string;
var
L1, L2, L3, L4: string;
L5: PChar;
begin
L1 := Format('%p', [VMI.RegionBaseAddress]);
L1 := L1 + Delimiter + Format('%d', [VMI.RegionSize div GetPageSize()]);
L1 := L1 + Delimiter + Format('%d', [VMI.BlocksCount]);
case VMI.RegionState of
MEM_COMMIT: L2 := 'Commit';
MEM_FREE: L2 := 'Free';
MEM_RESERVE: L2 := 'Reserve';
end;
L1 := L1 + Delimiter + L2;
case VMI.RegionType of
MEM_IMAGE: L3 := 'Image';
MEM_MAPPED: L3 := 'Mapped';
MEM_PRIVATE: L3 := 'Private';
end;
L1 := L1 + Delimiter + L3;
case VMI.RegionProtect and (not (PAGE_GUARD or PAGE_NOCACHE)) of
PAGE_READONLY: L4 := 'Read';
PAGE_READWRITE: L4 := 'Read/Write';
PAGE_WRITECOPY: L4 := 'Read/Write/Copy-on-write';
PAGE_EXECUTE: L4 := 'Execute';
PAGE_EXECUTE_READ: L4 := 'Read/Execute';
PAGE_EXECUTE_READWRITE: L4 := 'Read/Write/Execute';
PAGE_EXECUTE_WRITECOPY: L4 := 'Read/Write/Execute/Copy-on-write';
PAGE_NOACCESS: L4 := '';
end;
if (VMI.RegionProtect and PAGE_GUARD) = PAGE_GUARD then
L4 := L4 + '/Guard';
if (VMI.RegionProtect and PAGE_NOCACHE) = PAGE_NOCACHE then
L4 := L4 + '/No-cache';
L1 := L1 + Delimiter + L4;
if VMI.RegionAllocationBase <> nil then
begin
GetMem(L5, MAX_PATH);
try
if GetModuleFileName(HMODULE(VMI.RegionAllocationBase), L5, MAX_PATH) <> 0 then
L1 := L1 + Delimiter + L5
else
L1 := L1 + Delimiter;
finally
FreeMem(L5);
end;
end
else
L1 := L1 + Delimiter;
Result := L1;
end;
function GetBlockInformation(): string;
var
L1, L2, L3, L4: string;
begin
L1 := Format(' %p', [VMI.BlockBaseAddress]);
L1 := L1 + Delimiter + Format('%d', [VMI.BlockSize div GetPageSize()]);
L1 := L1 + Delimiter;
case VMI.BlockState of
MEM_COMMIT: L2 := 'Commit';
MEM_FREE: L2 := 'Free';
MEM_RESERVE: L2 := 'Reserve';
end;
L1 := L1 + Delimiter + L2;
case VMI.BlockType of
MEM_IMAGE: L3 := 'Image';
MEM_MAPPED: L3 := 'Mapped';
MEM_PRIVATE: L3 := 'Private';
end;
L1 := L1 + Delimiter + L3;
case VMI.BlockProtect and (not (PAGE_GUARD or PAGE_NOCACHE)) of
PAGE_READONLY: L4 := 'Read';
PAGE_READWRITE: L4 := 'Read/Write';
PAGE_WRITECOPY: L4 := 'Read/Write/Copy-on-write';
PAGE_EXECUTE: L4 := 'Execute';
PAGE_EXECUTE_READ: L4 := 'Read/Execute';
PAGE_EXECUTE_READWRITE: L4 := 'Read/Write/Execute';
PAGE_EXECUTE_WRITECOPY: L4 := 'Read/Write/Execute/Copy-on-write';
PAGE_NOACCESS: L4 := '';
end;
if (VMI.BlockProtect and PAGE_GUARD) = PAGE_GUARD then
L4 := L4 + '/Guard';
if (VMI.BlockProtect and PAGE_NOCACHE) = PAGE_NOCACHE then
L4 := L4 + '/No-cache';
L1 := L1 + Delimiter + L4 + Delimiter;
Result := L1;
end;
begin
if Expanded then
LInfoStr := GetBlockInformation()
else
LInfoStr := GetRegionInformation();
LBufferSize := Length(LInfoStr) + SizeOf(Char);// + 1;
GetMem(LBuffer, LBufferSize);
FillChar(LBuffer^, LBufferSize, 0);
StrCopy(LBuffer, PChar(LInfoStr));
Buffer := LBuffer;
BufferSize := LBufferSize;
end;
function VirtualMemoryQuery(Address: Pointer; PVMI: PVirtualMemoryInformation; Length: DWORD): BOOL; stdcall;
procedure DoCommittedMemoryQuery(PVMI: PVirtualMemoryInformation; MBI: TMemoryBasicInformation);
var
LRegionAllocationBase: Pointer;
LBlockAddress: Pointer;
LSentinal: Boolean;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -