O ile dobrze zorzumialem, bo napisałeś tak, że się motam się czytając powyższe. Musisz przeszukać pamięć procesu i wylistować wyniki. Niech strace, przykładowy kod poniżej. Mam nadzieję, że nie będzie dodatkowych pytań, bo poniższe jest w miarę oczywiste i proste jak się da, a także jak konstrukcja cepa :) I zaraz mnie za pewne "IngliszNazi" @Patryk27 zjedzie, że coś nie tak po angielsku, bo raz to przy okazji tego kodu robił. Ale dodam, że ignlisza to ja się uczyłem tylko cztery lata dawno temu w podstawówce, więc operuje nim jak potrafię. Ważne, że kod działa i wedle mnie taka metoda jest przejrzysta.
W oryginale kod pochodził z Google i zostal dopasowany przeze mnie na moje potrzeby. A co do kodu źródlowego Cheat Engine to przynajmniej ten pisany jeszcze pod Delphi 7 do wersji 5.6 da się ogarnąc. Wyciągałem sobie stamtąd i dostosowałem do WinAPI sposób obslugi HotKeyów we własnych trainerach, także jest to do okiełznania. Ok, oto mój kod. Jak widać jest funkcje do szukania zarówno tablicy bajtów jak i procedura do wyszukania stringów. Ale nie problem to sobie przerobić po swojemu i dopasować do swoich potrzeb aby szukało też wartości liczbowych tak, jak w Cheat Engine.
Ważne, że testowałem to nie raz oraz używałem i oczywiście działa dobrze, tak jak chciałem. Na Google znajdziesz funkcje do pobrania zarówno tak zwanego BaseAddress jak i rozmiaru exeka, coś jak to pokazywane przez LordPE. A co jest przydane kiedy niekoniecznie chcesz szukać w takim zakresie, jak robi to CE.
type
TOnFindProc = procedure(FindedAddress : Cardinal);
function FindBytesInMemory(APid : DWORD; RangeFrom, RangeTo : Cardinal;
ArrayOfBytes : array of Byte; OnFindProc : TOnFindProc;
StopAfterFirstFinding : boolean) : Cardinal;
const
BufferSize = 65535;
var
Found : boolean;
SizeOfArr : Byte;
HProcess : THandle;
X, Y, Addr : Cardinal;
BytesRead, BytesToRead : DWORD;
Buffer : array[0..BufferSize - 1] of Byte;
begin
Result := 0;
Found := False;
SizeOfArr := Length(ArrayOfBytes);
HProcess := OpenProcess(PROCESS_ALL_ACCESS, False, APid);
if (HProcess > 0) and (RangeFrom < RangeTo) then
begin
Addr := RangeFrom;
while Addr < RangeTo do
begin
BytesToRead := BufferSize;
if (RangeTo - Addr) < BytesToRead then
begin
BytesToRead := RangeTo - Addr;
end;
ReadProcessMemory(HProcess, Pointer(Addr), @Buffer[0], BytesToRead, BytesRead);
if BytesRead > 0 then
begin
for X := 0 to BytesRead - 1 do
begin
Found := True;
for Y := Low(ArrayOfBytes) to High(ArrayOfBytes) do
begin
if Buffer[X + Y] <> ArrayOfBytes[Y] then
begin
Found := False;
Break;
end;
end;
if Found then
begin
Result := Addr + X + Y - SizeOfArr;
if @OnFindProc <> nil then
begin
OnFindProc(Result);
end;
Break;
end;
end;
end;
Addr := Addr + BytesToRead;
if (Found) and (StopAfterFirstFinding) then
begin
Break;
end;
end;
CloseHandle(HProcess);
end;
end;
procedure FindStringInMemory(APID : WORD; RangeFrom, RangeTo : Cardinal;
StringToFind : string; IgnoreCase : boolean; OnFindProc : TOnFindProc);
const
BufferSize = 65535;
var
FOund : boolean;
S1, S2 : string;
SizeOfArr : Word;
X, Y, Addr : Cardinal;
ArrayOfBytes : array of Byte;
HProcess, BytesRead, BytesToRead : DWORD;
Buffer : array[0..BufferSize - 1] of Byte;
begin
if StringToFind <> '' then
begin
SetLength(ArrayOfBytes, Length(StringToFind));
for X := Low(ArrayOfBytes) to High(ArrayOfBytes) do
begin
ArrayOfBytes[X] := Ord(StringToFind[X + 1]);
end;
SizeOfArr := Length(ArrayOfBytes);
HProcess := OpenProcess(PROCESS_ALL_ACCESS, False, APID);
if (HProcess > 0) and (RangeFrom < RangeTo) then
begin
Addr := RangeFrom;
while Addr < RangeTo do
begin
BytesToRead := BufferSize;
if (RangeTo - Addr) < BytesToRead then
begin
BytesToRead := RangeTo - Addr;
end;
ReadProcessMemory(HProcess, Pointer(Addr), @Buffer[0], BytesToRead, BytesRead);
if BytesRead > 0 then
begin
for X := 0 to BytesRead - 1 do
begin
Found := True;
for Y := Low(ArrayOfBytes) to High(ArrayOfBytes) do
begin
if IgnoreCase then
begin
S1 := AnsiLowerCase(Chr(Buffer[X + Y]));
S2 := AnsiLowerCase(Chr(ArrayOfBytes[Y]));
if S1 <> S2 then
begin
Found := False;
Break;
end;
end
else
begin
if Buffer[X + Y] <> ArrayOfBytes[Y] then
begin
Found := False;
Break;
end;
end;
end;
if Found then
begin
if @OnFindProc <> nil then
begin
OnFindProc(Addr + X + Y - SizeOfArr);
end;
end;
end;
end;
Addr := Addr + BytesToRead;
end;
end;
CloseHandle(HProcess);
end;
end;
EDIT: a co do samego CheatEngine i jego źródla, to w tym którym ja dysponuje, o ile dobrze patrzę to wszystko co potrzeba jest zawarre w module o nazwie memscan
. Zaś więcej można dowiedzieć się analizując formatkę i kod głównego modułu, czyli MainUnit
.