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.