Recent

Author Topic: Reading values from other process memory. *nix,[example]  (Read 2154 times)

CynicRus

  • New Member
  • *
  • Posts: 46
Reading values from other process memory. *nix,[example]
« on: March 11, 2015, 08:53:34 pm »
Just example, I spent a lot of time to figure it out. I hope it will be useful for someone.

Code: [Select]
function process_vm_readv (PID: pid_t;local_iov: piovec;liovcnt: ulong;remote_iov: piovec;riovcnt: ulong; flags: ulong):ssize_t;cdecl; external clib name 'process_vm_readv';
function process_vm_writev (PID: pid_t;local_iov: piovec;liovcnt: ulong;remote_iov: piovec;riovcnt: ulong; flags: ulong):ssize_t;cdecl; external clib name 'process_vm_writev';

function TLinuxMemoryScanner.Attach: boolean;
var
  Status: longint = 0;
begin
if PTrace(PTRACE_ATTACH, pid_t(PID), nil, 0) = -1 then
    begin
      result:=false;
      raise Exception.Create(Format(ErrFailedToAttach,[PID]));
    end;
if (WaitPid(PID,@status,0) = -1) or not WIFSTOPPED(status) then
    begin
      result:=false;
      raise Exception.Create(ErrSigStopWaiting);
    end;
result:=true;
end;

function TLinuxMemoryScanner.Detach: boolean;
begin
  result:= ptrace(PTRACE_DETACH, pid, nil, nil) > -1;
end;

{$IFDEF OLDKERNEL}
function TLinuxMemoryScanner.GetValue(Address: integer; ValueSize: integer;
  Value: Pointer): boolean;
var
  i: integer;
  x:longint=0;
begin
if not Attach then
    begin
      result:=false;
      exit;
    end;
  i:=0;
  while i <= ValueSize do
    begin
      x := ptrace(PTRACE_PEEKDATA, PID, Address + i, nil);
      PByteArray(Value)^[i]:=x;
      inc(i);
    end;
detach();
result:=true;
end;

function TLinuxMemoryScanner.SetValue(Address: integer; ValueSize: integer;
  Value: Pointer): boolean;
var
  i: integer;
  x:longint=0;
begin
if not Attach then
    begin
      result:=false;
      exit;
    end;
  for i:= 0 to ValueSize - 1 do
     begin
     x := ptrace(PTRACE_POKEDATA, PID, Address + i, PByteArray(Value)^[i]);
      if errno <> 0 then
        begin
         Detach;
         result:=false;
        end;
      end;
detach();
result:=true;
end;
{$ELSE}
function TLinuxMemoryScanner.GetValue(Address: integer; ValueSize: integer;
  Value: Pointer): boolean;
var
  local,remote: array [0..0] of iovec;
  NRead: longint = 0;
begin
  result:=false;
  Local[0].iov_len:=ValueSize;
  Local[0].iov_base:=Value;
  Remote[0].iov_base:=Pointer(Address);
  Remote[0].iov_len:=Valuesize;
  Nread:=process_vm_readv(PID,@local[0],1,@remote[0],1,0);
  if not Nread <> ValueSize then
     result:=true;
end;

function TLinuxMemoryScanner.SetValue(Address: integer; ValueSize: integer;
  Value: Pointer): boolean;
var
  local,remote: array [0..0] of iovec;
  NWritten: longint = 0;
begin
  result:=false;
  Local[0].iov_len:=ValueSize;
  Local[0].iov_base:=Value;
  Remote[0].iov_base:=Pointer(Address);
  Remote[0].iov_len:=Valuesize;
  NWritten:=process_vm_writev(PID,@local[0],1,@remote[0],1,0);
  if not NWritten <> ValueSize then
     result:=true;
end;
{$ENDIF}

Tested on Ubuntu, works fine:)

 

TinyPortal © 2005-2018