W
wallysw
Unregistered / Unconfirmed
GUEST, unregistred user!
各位大哥大姐,我想读取某进程的内存内容,用到ReadProcessMemory,但是读取失败,各位帮帮我看是什么原因,谢谢!
全部代码如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, TLHelp32;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
procedure Button1Click(Sender: TObject);
private
procedure GetProID(StrList: TStringList);
procedure GetNum(ProID: Cardinal);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
TempStr: TStringList;
i: integer;
begin
TempStr := TStringList.Create;
GetProID(TempStr);
Memo1.Lines := TempStr;
for i := 0 to TempStr.Count - 1 do
GetNum(StrToInt(TempStr.Strings));
TempStr.Free;
end;
procedure TForm1.GetNum(ProID: Cardinal); //在进程地址空间中读取内存
var
_SystemInfo: _SYSTEM_INFO;
minP, maxP, TempPointer: Pointer;
sPageSize: Cardinal;
ProHandle: THandle;
sMemoryInfo: MEMORY_BASIC_INFORMATION; // MEMORY_BASIC_INFORMATION结构,用于返回内存空间的信息
pBuffe: Pointer;
rReadSize: Cardinal;
TempStr: String;
TempArry: array of Char;
begin
ProHandle := OpenProcess(PROCESS_ALL_ACCESS, False, ProID); //得到进程句柄
GetSystemInfo(_SystemInfo); //得到0~~2GB其中的一部分的起点和终点
minP := _SystemInfo.lpMinimumApplicationAddress;
maxP := _SystemInfo.lpMaximumApplicationAddress;
sPageSize := _SystemInfo.dwPageSize;
TempPointer := minP;
Label2.Caption := IntToStr(integer(maxP));
while integer(TempPointer) < integer(maxP) do
begin
VirtualQueryEx(ProHandle, // 进程的句柄
TempPointer, // 内存地址指针
sMemoryInfo, // 指向MEMORY_BASIC_INFORMATION结构的指针,用于返回内存空间的信息
SizeOf(MEMORY_BASIC_INFORMATION)
);
if (sMemoryInfo.Type_9 = MEM_PRIVATE) //私有页面
and (sMemoryInfo.AllocationProtect = PAGE_READWRITE) //可读写页面
and (sMemoryInfo.State = MEM_RESERVE) //已提交页面
then
begin
pBuffe := Nil;
if ReadProcessMemory(ProHandle, // 被读取进程的句柄
sMemoryInfo.BaseAddress, // 读的起始地址
pBuffe, //将这段内存读到自己的缓冲里面
SizeOf(Integer), //一次读取的字节数
rReadSize //实际读取的字节数
) then
begin
SetLength(TempArry, sPageSize);
FillChar(TempArry, Length(TempArry), #0);
CopyMemory(@TempArry[0], pBuffe, sPageSize);
StrPCopy(@TempArry, TempStr);
Application.ProcessMessages;
if Trim(TempStr) <> '' then
Memo1.Lines.Add(TempStr);
end;
end;
Application.ProcessMessages;
Label4.Caption := IntToStr(integer(TempPointer));
Inc(Integer(TempPointer), sPageSize); //指针向前偏移一个内存块
end;
end;
procedure TForm1.GetProID(StrList: TStringList); //取得指定应用程序的进程ID
var
sProcessEntry32: TProcessEntry32;
sHandle: THandle;
sBool: Boolean;
begin
if not assigned(StrList) then
Exit;
sHandle := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
sBool := Process32First(sHandle, sProcessEntry32);
while sBool do
begin //遍历进程
if UpperCase(sProcessEntry32.szExeFile) = UpperCase('abc.exe') then //查找进程名为abc.exe的应用程序
StrList.Add(Trim(IntToStr(sProcessEntry32.th32ProcessID))); //将其PID添加到列表中.
sBool := Process32Next(sHandle, sProcessEntry32);
end;
CloseHandle(sHandle);
end;
end.
全部代码如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, TLHelp32;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
procedure Button1Click(Sender: TObject);
private
procedure GetProID(StrList: TStringList);
procedure GetNum(ProID: Cardinal);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
TempStr: TStringList;
i: integer;
begin
TempStr := TStringList.Create;
GetProID(TempStr);
Memo1.Lines := TempStr;
for i := 0 to TempStr.Count - 1 do
GetNum(StrToInt(TempStr.Strings));
TempStr.Free;
end;
procedure TForm1.GetNum(ProID: Cardinal); //在进程地址空间中读取内存
var
_SystemInfo: _SYSTEM_INFO;
minP, maxP, TempPointer: Pointer;
sPageSize: Cardinal;
ProHandle: THandle;
sMemoryInfo: MEMORY_BASIC_INFORMATION; // MEMORY_BASIC_INFORMATION结构,用于返回内存空间的信息
pBuffe: Pointer;
rReadSize: Cardinal;
TempStr: String;
TempArry: array of Char;
begin
ProHandle := OpenProcess(PROCESS_ALL_ACCESS, False, ProID); //得到进程句柄
GetSystemInfo(_SystemInfo); //得到0~~2GB其中的一部分的起点和终点
minP := _SystemInfo.lpMinimumApplicationAddress;
maxP := _SystemInfo.lpMaximumApplicationAddress;
sPageSize := _SystemInfo.dwPageSize;
TempPointer := minP;
Label2.Caption := IntToStr(integer(maxP));
while integer(TempPointer) < integer(maxP) do
begin
VirtualQueryEx(ProHandle, // 进程的句柄
TempPointer, // 内存地址指针
sMemoryInfo, // 指向MEMORY_BASIC_INFORMATION结构的指针,用于返回内存空间的信息
SizeOf(MEMORY_BASIC_INFORMATION)
);
if (sMemoryInfo.Type_9 = MEM_PRIVATE) //私有页面
and (sMemoryInfo.AllocationProtect = PAGE_READWRITE) //可读写页面
and (sMemoryInfo.State = MEM_RESERVE) //已提交页面
then
begin
pBuffe := Nil;
if ReadProcessMemory(ProHandle, // 被读取进程的句柄
sMemoryInfo.BaseAddress, // 读的起始地址
pBuffe, //将这段内存读到自己的缓冲里面
SizeOf(Integer), //一次读取的字节数
rReadSize //实际读取的字节数
) then
begin
SetLength(TempArry, sPageSize);
FillChar(TempArry, Length(TempArry), #0);
CopyMemory(@TempArry[0], pBuffe, sPageSize);
StrPCopy(@TempArry, TempStr);
Application.ProcessMessages;
if Trim(TempStr) <> '' then
Memo1.Lines.Add(TempStr);
end;
end;
Application.ProcessMessages;
Label4.Caption := IntToStr(integer(TempPointer));
Inc(Integer(TempPointer), sPageSize); //指针向前偏移一个内存块
end;
end;
procedure TForm1.GetProID(StrList: TStringList); //取得指定应用程序的进程ID
var
sProcessEntry32: TProcessEntry32;
sHandle: THandle;
sBool: Boolean;
begin
if not assigned(StrList) then
Exit;
sHandle := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
sBool := Process32First(sHandle, sProcessEntry32);
while sBool do
begin //遍历进程
if UpperCase(sProcessEntry32.szExeFile) = UpperCase('abc.exe') then //查找进程名为abc.exe的应用程序
StrList.Add(Trim(IntToStr(sProcessEntry32.th32ProcessID))); //将其PID添加到列表中.
sBool := Process32Next(sHandle, sProcessEntry32);
end;
CloseHandle(sHandle);
end;
end.