I want to extract the full process memory of notepad process and write it to a text file. The problem is that i do not find what i type in notepad in the textfile. For example, if i type "test123" in notepad, i cannot find the string in the textfile that the program creates. Here is the code:
{$APPTYPE CONSOLE}
uses
Windows,
TLHelp32,
SysUtils;
var
Snap, err: dword;
sysinfo: TSystemInfo;
Process: TPROCESSENTRY32;
Handle: THandle;
Mbi: TMemoryBasicInformation;
Addr, BytesRead: dword;
Buf: PChar;
f: TextFile;
begin
GetSystemInfo(sysinfo);
Handle := OpenProcess(PROCESS_ALL_ACCESS, false, 2928);
if Handle <> 0 then
begin
writeln(Process.szExeFile);
Addr := dword(sysinfo.lpMinimumApplicationAddress);
while (Addr < $80000000) do
begin
if VirtualQueryEx(Handle, Ptr(Addr), Mbi, SizeOf(Mbi)) = 0 then
begin
err := GetLastError;
inc(Addr, sysinfo.dwPageSize);
continue;
end;
Buf := AllocMem(Mbi.RegionSize);
ReadProcessMemory(Handle, Mbi.BaseAddress, Buf, Mbi.RegionSize, BytesRead);
AssignFile(f, 'Test.txt');
Append(f);
WriteLn(f, Buf);
CloseFile(f);
FreeMem(Buf);
if Addr + Mbi.RegionSize < Addr then
break;
Addr := Addr + Mbi.RegionSize;
end;
CloseHandle(Handle)
end;
Readln;
end.
The correct way to retrieve notepad's text content is to locate the HWND
of notepad's edit field, using FindWindowEx()
or EnumChildWindows()
or similar, and then send it a WM_GETTEXT
message.
But if you must dump Notepad's allocated memory, then you need to fix your code. It is ignoring errors, and not writing the retrieved data to your file correctly. Try something more like this instead:
uses
Windows,
TLHelp32,
SysUtils;
var
err: DWORD;
sysinfo: TSystemInfo;
Handle: THandle;
Mbi: TMemoryBasicInformation;
Addr: DWORD_PTR;
BytesRead: DWORD;
Buf: array of Byte;
f: TFileStream;
begin
GetSystemInfo(sysinfo);
Handle := OpenProcess(PROCESS_ALL_ACCESS, FALSE, 2928);
if Handle = 0 then
begin
err := GetLastError;
// do something...
end else
try
f := TFileStream.Create('Test.txt', fmCreate);
try
Addr := DWORD_PTR(SysInfo.lpMinimumApplicationAddress);
while (Addr < $80000000) do
begin
if VirtualQueryEx(Handle, Pointer(Addr), Mbi, SizeOf(Mbi)) = 0 then
begin
err := GetLastError;
Inc(Addr, sysinfo.dwPageSize);
Continue;
end;
if Mbi.RegionSize > Length(Buf) then
SetLength(Buf, Mbi.RegionSize);
if not ReadProcessMemory(Handle, Mbi.BaseAddress, @Buf[0], Mbi.RegionSize, BytesRead) then
begin
err := GetLastError;
// do something...
end else
f.WriteBuffer(Buf[0], BytesRead);
if Addr + Mbi.RegionSize < Addr then
break;
Addr := Addr + Mbi.RegionSize;
end;
finally
f.Free;
end;
finally
CloseHandle(Handle);
end;
Readln;
end.