Array of bytes na string

0

Witam.
Znalazłem na forum taki kod:

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;

Bardzo fajny, ale dało by radę go jakoś łatwo zmienić na przeszukiwanie stringów, zamiast array of bytes? Było by to bardziej pożyteczne z tego względu, że każdy tekst obecnie zamieniam na array of bytes, a później w programie to wpisuję jako $coś $coś $coś. Trochę dużo z tym roboty i lepiej by było po prostu wpisać tekst :)

0

zrób funkcję która zrobi konwersję stringu a właściwie to ansistringu na array of bytes

function ansistringToArrayOfBytes(aString: AnsiString; var aArray: array of byte):integer;
begin
  result:=min(length(aArray),length(aString));
  CopyMemory(@aArray[0], @aString[1], result);
end;
2

Przecież ciągi znaków można bez problemu traktować jako tablice bajtów – nawet składnia jest identyczna. Wystarczy zmienić deklarację poniższej stałej:

const
  Target: array[0..4] of byte = ($6E, $69, $63, $6F);

na ciąg znaków:

const
  Target: String = #$6E#$69#$63#$6F;

i to wszystko.

A tak na marginesie – masz zadeklarowaną pięcioelementową tablicę, ale definiujesz cztery pierwsze bajty. Mało tego, w funkcji CompareMem podajesz adres drugiej komórki tej tablicy (o indeksie 1), zamiast pierwszej, która ma indeks 0. To nie ma prawa działać prawidłowo – autor walnął się w kilku miejscach. ;)

Jak przerobisz stałą na ciąg znaków to @Target[1] będzie pasować.

0

Autorem jest chyba kAzek i działa to rewelacyjnie.


Target: String = 'target';


         begin
          SetLength(buff, Mbi.RegionSize);
          if ReadProcessMemory(Handle, Mbi.BaseAddress, Buff, Mbi.RegionSize, BytesRead) then
          begin
            for i := 0 to length(Target) do
            if CompareMem(@target[i], @target[1], Length(target)) then
            begin
              Form13.Memo1.Lines.Add(Format('"target" found at: %0:.8x', [Int64(Mbi.BaseAddress) + i]));
              Form13.Label1.Caption := 'on';
            end;
          end;
        end;

Wiem że coś jest źle. Może ktoś powiedzieć co - poprawić to?

1

@kAzek nie ma z tym kodem nic wspólnego – w sieci można znaleźć kilka wątków z takim samym lub podobnym kodem i żaden z nich nie został opublikowany przez niego:

We wszystkich trzech wątkach powielany jest ten sam błąd:

const
  {
    - 5 bajtów, indeksowanie od 0, definicja czterech pierwszych bajtów,
    - piąty bajt niezdefiniowany (będzie zerem przy domyślnych ustawieniach)
  }
  Target: array[0..4] of byte = ($6E, $69, $63, $6F);
  
{..}

{
  - porównanie bloku pamięci stałej Target od drugiego bajtu, bo jest ona indeksowana od 0,    
  - Length(Target) zwraca 5 – porównanie pięciu bajtów zaczynając od drugiego, a więc:
    - trzech środkowych – indeksy 1, 2 i 3, czyli wartości $69, $63 i $6F
    - czwartego niezdefiniowanego – indeks 4
    - piątego śmieciowego – indeks 5, a więc spoza bloku pamięci tablicy
}
if CompareMem(@Buff[i], @Target[1], Length(Target)) then

Jak więc ten kod ma działać prawidłowo, skoro tablica jest nie do końca zdefiniowana, a funkcja porównująca bloki pamięci używa śmieci spoza tablicy?


Zibby napisał(a):
if CompareMem(@target[i], @target[1], Length(target)) then

Porównujesz Target do Target, zamiast Buff do Target. Poza tym, miałeś zmienić typ stałej i jej zawartość, a zadeklarowałeś nową zmienną.

1

Jak najbardziej odcinam, się od tego błędnego kodu tutaj zwróciłem uwagę na ten powtarzany błąd:
https://api.4programmers.net/Forum/Delphi_Pascal/300328-szukanie_array_of_bytes_w_innym_procesie?p=1424107#id1424107
a w końcu poprawiłem cały kod.

0

@kAzek: do tego pytacz sam przyznał, że Twoja poprawiona (bezpieczna) wersja działa „rewelacyjnie”. :D

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