各位大哥大姐,我想读取某进程的内存内容,用到ReadProcessMemory,但是读取失败,它没出错,但总返回False.各位帮帮我看是什么原因,谢谢!全部代码如下:unit Unit1;interfaceuses
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[i]));
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.
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[i]));
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.
if ReadProcessMemory(ProHandle, // 被读取进程的句柄
sMemoryInfo.BaseAddress, // 读的起始地址
pBuffe, //将这段内存读到自己的缓冲里面
SizeOf(Integer), //一次读取的字节数
rReadSize //实际读取的字节数
) then 这里不能另pBuffe := Nil; 应该给pBuffer分配内存。如pBuffe := GetMemory(ReadSize);
procedure TForm1.Button1Click(Sender: TObject);
var
sProcessEntry32: TProcessEntry32;
sHandle,ProcessHandle: THandle;
sBool: Boolean;
test:integer;
lpNumberOfBytes:DWORD;
begin
sHandle := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
sBool := Process32First(sHandle,sProcessEntry32);
while sBool do
begin
if UpperCase(sProcessEntry32.szExeFile)<> UpperCase('abc.exe') then
begin
sBool := Process32Next(sHandle, sProcessEntry32);
end
else
begin
sbool:=false;
ProcessHandle:=OpenProcess(PROCESS_ALL_ACCESS,False,sProcessEntry32.th32ProcessID );
if ProcessHandle<>0 then
begin
ReadProcessMemory(ProcessHandle,Pointer(地址),@test,sizeof(test),lpNumberOfBytes);
edit1.Text:=inttostr(test);
end;
closehandle(processhandle);
end;
end;
CloseHandle(sHandle);
end;
网上有例子的
sMemoryInfo.BaseAddress, // 读的起始地址
pBuffe, //将这段内存读到自己的缓冲里面
SizeOf(Integer), //一次读取的字节数
rReadSize //实际读取的字节数
) then