简体   繁体   中英

Search for an array of bytes in another process

I wish to search for an array of bytes inside another process. I am using VirtualQueryEx and ReadProcessMemory but i am unsure of the correct what to do this.

Here is how my code looks so far:

procedure TForm1.Button2Click(Sender: TObject);
const
  Target: array[0..7] of byte = ($A0, $19, $40, $2B, $F6, $7F, $00, $00);
var
  Mbi: TMemoryBasicInformation;
  Handle: THandle;
  buff: array of byte;
  hWin, ProcID, BuffSize: Cardinal;
  Addr: DWORD_PTR;
  BytesRead: NativeUInt;
  i: integer;
begin
  hWin := FindWindow(nil, 'Minesweeper');
  if hWin > 0 then
    GetWindowThreadProcessID(hWin, @ProcId);
  if ProcId > 0 then
  begin
    Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, ProcId);
    if Handle <> 0 then
    begin
      while (VirtualQueryEx(Handle, Ptr(Addr), Mbi, SizeOf(Mbi)) <> 0) do
      begin
        SetLength(buff, BuffSize);
        if ReadProcessMemory(Handle, Mbi.BaseAddress, Buff, Mbi.RegionSize, BytesRead) then
        begin
          for i := 0 to Length(Buff) do
          if CompareMem(@Buff[i], @Target[1], Length(Target)) then
          begin
            ShowMessage('Found');
          end;
        end;
        if Addr + BuffSize < Addr then
          break;
        Addr := Addr + BuffSize;
      end;
      SetLength(buff, 0);
      CloseHandle(Handle);
    end;
  end;
end;

Program freezes.

There are a number of issues with your code.
Rather than spoonfeed the solution I'm going to explain where to get the info.

Every local variable that you use, must be initialized beforehand.

Initialize local variables
The following vars are not initialized:

{mbi - Set to zero using} FillChar(mbi, SizeOf(Mbi), #0);

BuffSize:= 1024*4 + SizeOf(Target);
//Also add a 
const
  DefaultBufSize = 1024*4; 

Do not start reading from 0
Instead initialize Addr to the starting address of the process using GetModuleInfo Don't forget to initialize the mi: TModuleInfo structure using: FillChar(mi, SizeOf(mi), #0);

Read a 4k+ buffer
Now keep loading buffers of BuffSize , but only increase Addr with DefaultBuffSize .

Check how many bytes are actually read
Make sure to check the BytesRead parameter and reduce the BuffSize if fewer bytes are read (or you'll get access violations).

Utilize a smart search algorithm
Use the following routine to find the string:

Boyer-Moore-Horspool string search algorithm - Wiki
(Thanks to: Dorin Duminica)

{$PointerMath on}
function FindMem(P1: pointer; Size1: Cardinal; P2: Pointer; Size2: Cardinal): Integer;
var
  i,j,k: Integer;
  LenPattern: Integer;
  LenValue: Integer;
  SkipTable: array[byte] of Integer;
  Found: Boolean;
  B: Byte;

    function __SameByte: Boolean;
    begin
      Result := (PByte(P1)[i] = PByte(P2)[j])
    end; // function __SameChar: Boolean;

begin
  Found := False;
  Result := -1;
  LenPattern := size2;
  if LenPattern = 0 then begin
    Result := 0;
    Found := True;
  end; // if LenPattern = 0
  for B:= low(byte) to high(byte) do SkipTable[B]:= LenPattern;
  for k:= 1 to LenPattern - 1 do SkipTable[PByte(P2)[k]]:= LenPattern - k;
  k:= LenPattern + 0;
  LenValue := size1;
  while (not Found) and (k <= LenValue) do begin
    i := k;
    j := LenPattern;
    while (j >= 1) do begin
      if __SameByte then begin
        j := j -1;
        i := i -1;
      end else
        j := -1;
      if j = 0 then begin
        Result := i;
        Found := True;
      end; // if j = 0 
      k := k + SkipTable[PByte(P1)[k]];
    end; // while (j >= 1)
  end; // while (not Found) and (k <= Size1)
end;

See here for info on GetModuleInfo

Good luck

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM