ReadProcessMemory

ŁF
// C
BOOL ReadProcessMemory(
  HANDLE hProcess,
  LPCVOID lpBaseAddress,
  LPVOID lpBuffer,
  SIZE_T nSize,
  SIZE_T* lpNumberOfBytesRead
);
// Delphi
function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesRead: DWORD): BOOL; external kernel32 name 'ReadProcessMemory';

Funkcja ReadProcessMemory umożliwia odczyt pamięci innego procesu.

Parametry:
[in] hProcess
Uchwyt procesu, którego pamięć ma być odczytana. Uchwyt musi mieć ustawione prawo PROCESS_VM_READ aby operacja odczytu się powiodła.

[in] lpBaseAddress
Wskaźnik będący adresem bazowym obszaru pamięci, z którego ma nastąpić odczyt. Zanim nastąpi odczyt, system sprawdza czy są ustawione odpowiednie prawa umożliwiające dostęp do pamięci drugiego procesu. Jeśli takich praw nie ma, funkcja nie wykonuje odczytu i zwraca 0.

[out] lpBuffer
Wskaźnik do bufora, do którego zostanie odczytana pamięć.

[in] nSize
Ilość bajtów do odczytania (rozmiar bufora).

[out] lpNumberOfBytesRead
Ilość odczytanych bajtów.

Zwracana wartość
Jeśli operacja się powiedzie, zwraca niezerową wartość (true), w przeciwnym wypadku zwraca 0 (false). Aby dostać dokładniejsze informacje o błędzie, użyj funkcji GetLastError. Funkcja zwraca błąd jeśli nie ma niezbędnych uprawnień do chociaż jedego z bloków odczytywanej pamięci.

Przykład
Poniżej znajduje się funkcja napisana w Delphi, umożliwiająca odczyt linii poleceń z jaką został uruchomiony proces.

function GetCmdLine(hProcess : thandle) : string;
var
  h2 : thandle;
  PROCESSENTRY32 : TPROCESSENTRY32;
  i,j : cardinal;
  buf : array of char;
  memStart : pointer;
  memInfo : MEMORY_BASIC_INFORMATION;
  s     : string;
begin
  result := '';
  h2 := OpenProcess (PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, hProcess);
  if h2 = 0 then exit;

  memstart := pointer($20000);
  while VirtualQueryEx(h2, memstart, memInfo, SizeOf(MEMORY_BASIC_INFORMATION)) = SizeOf(MEMORY_BASIC_INFORMATION) do
  begin
    if (meminfo.State = MEM_COMMIT) then
    begin
      setlength(buf,meminfo.RegionSize);
      if ReadProcessMemory(h2, memInfo.BaseAddress, buf, memInfo.RegionSize, i) then
      begin
         move(buf[1176],buf[0],meminfo.RegionSize-1176);

         i := Pos(#0#0,string(buf));
         move(buf[i+6],buf[0],meminfo.RegionSize-i-6);
         i := pos(#0#0,string(buf));
         while buf[i] = #0 do inc(i);
         if i > 2048 then break;
         move(buf[i],buf[0],meminfo.RegionSize-i);

         j := pos(#0#0,string(buf)) div 2;
         setlength(s,j);
         for i := 0 to j-1 do s[i+1] := buf[i*2];

         result := s;
         break;
      end;
      buf := nil;
    end;
    integer(memstart) := integer(meminfo.BaseAddress) + meminfo.regionsize;
  end;
  CloseHandle(h2);
end;

Zobacz też:

1 komentarz

A u mnie ten przykład nie działa - tzn. zwraca puste stringi. Poprosiłbym o jakiś krótki praktyczny przykład :)