Szukanie array of bytes w innym procesie

Odpowiedz Nowy wątek
2017-11-29 14:18
Inny Inaczej
0

Witam.

Co w tym kodzie jest nie tak?:

const
  Target: array[0..4] of byte = ($6E, $69, $63, $6F); 
var
  Mbi: TMemoryBasicInformation;
  Handle: THandle;
  buff: array of byte;
  hWin, ProcID, BuffSize: Cardinal;
  Addr: DWORD_PTR;
  BytesRead: NativeUInt;
  i: integer;
begin
  hWin := FindWindow(nil, 'TestSft');
  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;

Odpowiedzią programu na kliknięcie w button jest "Out of memory".
Proszę o pomoc. Dziękuję.

Pozostało 580 znaków

2017-11-29 14:24
0

4 bajtami nie namierzysz tablicy, bo będzie ich z 1000 w całej aplikacji.

koło 20-30 bajtów na takie szukanie starczy :)

Pozostało 580 znaków

2017-11-29 14:33
1

Nie inicjalizujesz BuffSize.

Pozostało 580 znaków

2017-11-29 14:58
Inny Inaczej
0

W takim razie jest tak:

procedure TForm1.Button3Click(Sender: TObject);
const
  Target: array[0..4] of byte = ($6E, $69, $63, $6F); 
  BufSize = 1024*4;
var
  Mbi: TMemoryBasicInformation;
  Handle: THandle;
  buff: array of byte;
  hWin, ProcID, BuffSize: Cardinal;
  Addr: DWORD_PTR;
  BytesRead: NativeUInt;
  i: integer;
begin
BuffSize:= 1024*4 + SizeOf(Target);
  hWin := FindWindow(nil, 'TestSft');
  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;

Po użyciu buguje mi cały program. Albo coś zrobiłem źle, albo za dużo arrays jest w tym zewnętrznym programie do sprawdzenia.

Pozostało 580 znaków

2017-11-29 15:26
0

Co to znaczy „buguje” i w którym miejscu?

Ile wynosi Mbi.RegionSize i po co w takim razie ustawiasz rozmiar bufora na jakieś dziwne 1024*4 + SizeOf(Target)?

edytowany 1x, ostatnio: Azarien, 2017-11-29 15:27

Pozostało 580 znaków

2017-11-29 15:35
1

Tak w ciemno tylko patrząc na kod bez użycia debuggera, który zapewne jest Ci obcy zmień:

SetLength(buff, BuffSize);

na:

SetLength(buff, Mbi.RegionSize);

tu też trochę lipa:

          for i := 0 to Length(Buff) do
          if CompareMem(@Buff[i], @Target[1], Length(Target)) then
          begin
            ShowMessage('Found');
          end;

bezpieczniej:

          for i := 0 to Length(Buff)  - Length(Target) do
          if CompareMem(@Buff[i], @Target[1], Length(Target)) then
          begin
            ShowMessage('Found');
          end;

Kiedy ten warunek będzie spełniony? BuffSize będzie ujemne? Po co to?

        if Addr + BuffSize < Addr then
          break;

Już raczej ewentualnie można by:

        if BytesRead = 0 then
          break;

A to:

Addr := Addr + BuffSize;

raczej zmień na:

Addr := Addr + BytesRead;

Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
edytowany 1x, ostatnio: kAzek, 2017-11-29 15:44

Pozostało 580 znaków

2017-11-29 16:08
Inny Inaczej
0
procedure TForm1.Button3Click(Sender: TObject);
const
  Target: array[0..4] of byte = ($6E, $69, $63, $6F); 
  BufSize = 1024*4;
var
  Mbi: TMemoryBasicInformation;
  Handle: THandle;
  buff: array of byte;
  hWin, ProcID, BuffSize: Cardinal;
  Addr: DWORD_PTR;
  BytesRead: NativeUInt;
  i: integer;
begin
BuffSize:= 1024*4 + SizeOf(Target);
  hWin := FindWindow(nil, 'TestSft');
  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, Mbi.RegionSize);
        if ReadProcessMemory(Handle, Mbi.BaseAddress, Buff, Mbi.RegionSize, BytesRead) then
        begin
         for i := 0 to Length(Buff)  - Length(Target) do
          if CompareMem(@Buff[i], @Target[1], Length(Target)) then
          begin
            ShowMessage('Found');
          end;
        if BytesRead = 0 then
          break;
        Addr := Addr + BytesRead;
      end;
      SetLength(buff, 0);
      CloseHandle(Handle);
    end;
  end;
end;
end;

Pisząc "buguje" miałem na myśli to że program się zawieszał i musiałem go wyłączyć. Teraz się nie zawiesza, ale w sumie nic się nie dzieje.

Pozostało 580 znaków

2017-11-29 16:30
1

Jeszcze:

if CompareMem(@Buff[i], @Target[1], Length(Target)) then

na

if CompareMem(@Buff[i], @Target[0], Length(Target)) then

bo widzę że tablica Target indeksowana jest od 0


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.

Pozostało 580 znaków

2017-11-29 16:31
0
Inny Inaczej napisał(a):

Teraz się nie zawiesza, ale w sumie nic się nie dzieje.

Dzieje się, tylko nie ma wizualnych efektów działania. Sprawdź pod debuggerem, linia po linii. W ten sposób sprawdzisz przepływ sterowania i znajdziesz przyczynę w kilka minut.


edytowany 1x, ostatnio: furious programming, 2017-11-29 16:32

Pozostało 580 znaków

2017-11-29 17:39
Inny Inaczej
0
kAzek napisał(a):

Jeszcze:

if CompareMem(@Buff[i], @Target[1], Length(Target)) then

na

if CompareMem(@Buff[i], @Target[0], Length(Target)) then

bo widzę że tablica Target indeksowana jest od 0 [/quote]

Nadal nic :/

edytowany 2x, ostatnio: furious programming, 2017-11-29 19:07

Pozostało 580 znaków

2017-11-29 18:02

Ech dopiero po odpaleni zauważyłem byki takie jak próby odczytu z pamięci do której nie mamy dostępu (można by próbować uzyskać dostęp funkcja VirtualProtect ale co gorsze CloseHandle odpowiedzialne za zamknięcie uchwytu procesu było po nie tym end więc zamykało go zbyt wcześnie. Masz działającą chyba poprawnie (na tyle na ile zdążyłem przetestować) funkcję. Zawiera ona proste logowanie do Memo dla testu to możesz usunąć te linie.

procedure TForm2.Button1Click(Sender: TObject);
const
  Target: array[0..3] of byte = ($6E, $69, $63, $6F);
var
  Mbi: TMemoryBasicInformation;
  Handle: THandle;
  buff: array of byte;
  hWin, ProcID, BuffSize: Cardinal;
  Addr: DWORD_PTR;
  BytesRead: NativeUInt;
  i: integer;
begin
  Addr:= $400000; //tak dla testu initcjalizacja adresu szukania
  Memo1.Lines.Clear;
  hWin := FindWindow(nil, 'TestSft');
  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
        if ((Mbi.State = MEM_COMMIT) and (not (Mbi.Protect = PAGE_GUARD)
           or (Mbi.Protect = PAGE_NOACCESS)) and (Mbi.Protect = PAGE_READWRITE)) then
        begin
          Memo1.Lines.Add(Format('%0:.8x', [Int64(Mbi.BaseAddress)]));
          SetLength(buff, Mbi.RegionSize);
          if ReadProcessMemory(Handle, Mbi.BaseAddress, Buff, Mbi.RegionSize, BytesRead) then
          begin
            for i := 0 to BytesRead - Length(Target)  -1 do
            if CompareMem(@Buff[i], @Target[0], Length(Target)) then
            begin
              Memo1.Lines.Add(Format('Found at %0:.8x', [Int64(Mbi.BaseAddress) + i]));
              //ShowMessage('Found');
            end;
          end;
        end;
        Addr := Addr + Mbi.RegionSize;
      end;
    end;
    SetLength(buff, 0);
    CloseHandle(Handle);
  end;
end;

Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
edytowany 2x, ostatnio: kAzek, 2017-12-06 03:58
Jeszcze podziel to na metody robiące jedną rzecz (SRP) i mające góra kilka linijek kodu, zwracaj wynik zamiast wrzucać do memo i będzie zajebiście :-) - ŁF 2017-12-06 16:32

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0