求助:读取某进程内存块数据(100分)

  • 主题发起人 主题发起人 wallysw
  • 开始时间 开始时间
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.
 
出错了使用 GetLastError 看看什么错误。
 
他没出错,但是返回的全是False
 
下面是窗体界面:

object Form1: TForm1
Left = 192
Top = 107
Width = 696
Height = 482
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 56
Top = 16
Width = 23
Height = 13
Caption = 'total:'
end
object Label2: TLabel
Left = 88
Top = 16
Width = 32
Height = 13
Caption = 'Label2'
end
object Label3: TLabel
Left = 56
Top = 40
Width = 18
Height = 13
Caption = 'cur:'
end
object Label4: TLabel
Left = 88
Top = 40
Width = 32
Height = 13
Caption = 'Label4'
end
object Button1: TButton
Left = 80
Top = 288
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object Memo1: TMemo
Left = 288
Top = 16
Width = 377
Height = 433
ScrollBars = ssVertical
TabOrder = 1
end
end
 
在线等待中!
 
调用 AdjustTokenPrivileges 提升本进程权限
 
确实,需要现调整到 debug 权限。
 
ReadProcessMemory 的第四个参数不对,应该是缓冲区的大小
 
后退
顶部