0
votes

One week ago I started making a project to scan another processes memory. First I was thinking in just inject a DLL into the processes and then access its memory, but due to all difficulty I started doing this with VirtualQueryEx / ReadProcessMemory APIs. Some doubts emerged in my mind, below is the code:

var
  Form1: TForm1;
  PIDHandle: THandle;
  PID: dword;
  MemInfo: MEMORY_BASIC_INFORMATION;
  SysInfo: SYSTEM_INFO;
  PageSize, MemStart, ReceivedBytes: cardinal;
  Buff: PChar;
  IsWow64Process: TIsWow64Process;
  IsWow64: BOOL;

    while (VirtualQueryEx(PIDHandle, Pointer(MemStart), MemInfo, SizeOf(MemInfo)) > 0) do
      begin
        if ((MemInfo.State = MEM_COMMIT) and (not (MemInfo.Protect = PAGE_GUARD)
            or (MemInfo.Protect = PAGE_NOACCESS))) then
          begin
            if (0<>MemInfo.Protect and PAGE_READWRITE) then
              begin
                GetMem(Buff, MemInfo.RegionSize);
                if (ReadProcessMemory(PIDHandle, Pointer($00636ED0), Buff,
                                        MemInfo.RegionSize, ReceivedBytes)) then
                  begin
                    Memo1.Lines.Append(PAnsiChar(Buff));
                  end;
                FreeMem(Buff);
              end;
          end;
      MemStart:= MemStart + MemInfo.RegionSize;
    end;
  CloseHandle(PIDHandle);
  end;

First All - This while method:

while (VirtualQueryEx(PIDHandle, Pointer(MemStart), MemInfo, SizeOf(MemInfo)) > 0) do
...
 MemStart:= MemStart + MemInfo.RegionSize;

Am I scanning all the memory addresses? Or it's just 'jumping' addresses without reading??! Second and most important problem- I'm using notepad to make tests, and my objective is to read some string wrote there. If I make like this:

       if (0<>MemInfo.Protect and PAGE_READWRITE) then
              begin
                GetMem(Buff, MemInfo.RegionSize);
                if (ReadProcessMemory(PIDHandle, Pointer($00636ED0), Buff,
                                        MemInfo.RegionSize, ReceivedBytes)) then
                  begin
                    Memo1.Lines.Append(PAnsiChar(Buff));
                  end;
                FreeMem(Buff);
              end;

Passing the Address directly in the ReadProcessMemory, it works and get the first letter(or first byte) of my string. Remembering Buff is PChar... But if I do the same thing but ReadProcessMemory like this:

if (ReadProcessMemory(PIDHandle, MemInfo.BaseAddress, Buff,
  MemInfo.RegionSize, ReceivedBytes)) then
      begin
          Memo1.Lines.Append(PAnsiChar(Buff));
      end;
   FreeMem(Buff);
   end;

It add on the Memo a bunch of chinese and invalid characters. How can I automatically scan every single memory address and get my string wrote there? Any questions about the code, just ask-me... Waiting for your help

3
It's a mistake trying to interpret this memory as text. It isn't text. You want to display it the same way as a hex editor. - David Heffernan
Yes, more or less like this. Have some Hex Editors that have a function to search an exact text string in the memory. I want to do this, search for some kind of string in the memory... - HwTrap

3 Answers

0
votes

Allocate one extra character in Buff and initialize it with zero. I'm guessing Memo1.Lines.Append wants a null terminated string, the garbage characters are probably whatever happened to be in memory after Buff.

0
votes

To get the first memory address do this :

var
sysinfo : TSystemInfo;
GetSystemInfo(sysinfo);
start : DWORD;
begin
start := DWORD(sysinfo.lpMinimumApplicationAddress);
end;

You are getting garbage because an 0 occurss in the string before all memory is shown so do this use

var
   mybuffer : String;
begin
   SetLength(mybuffer,MemInfo.RegionSize);
   CopyMemory(@mybuffer[1],Buff,MemInfo.RegionSize);
   Memo1.Lines.Add(mybuffer);

end;
0
votes

If you are looking for dll injection (and other fun techniques), maybe you should a look at here? https://sites.google.com/site/delphibasics/system/app/pages/search?scope=search-site&q=dll+injection