Witam.
Chciałbym wiedzieć czy jest jakaś możliwość przeczytania adresu od danego procesu.
Chodzi mi o coś takiego: Powiedzmy że mam grę Gothic 2 i koniecznie chcę znać jej adres.
Dziękuję.
Witam.
Chciałbym wiedzieć czy jest jakaś możliwość przeczytania adresu od danego procesu.
Chodzi mi o coś takiego: Powiedzmy że mam grę Gothic 2 i koniecznie chcę znać jej adres.
Dziękuję.
Szukasz chyba tego: Trainer do gry, jak znaleźć Base Address w Windows 7 64bit
Z tym że nie interesują mnie pointery, jakieś ich dodawanie itp.
Chcę prosto i gładko odczytać adres procesu.
Mam na chwilę obecną tak:
function GetModuleBaseAddress(ProcessID: Cardinal; MName: String): Pointer;
var
Modules : Array of HMODULE;
cbNeeded, i : Cardinal;
ModuleInfo : TModuleInfo;
ModuleName : Array[0..MAX_PATH] of Char;
PHandle : THandle;
begin
Result := nil;
SetLength(Modules, 1024);
PHandle := OpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ, False, ProcessID);
if (PHandle <> 0) then
begin
EnumProcessModules(PHandle, @Modules[0], 1024 * SizeOf(HMODULE), cbNeeded); //Getting the enumeration of modules
SetLength(Modules, cbNeeded div SizeOf(HMODULE)); //Setting the number of modules
for i := 0 to Length(Modules) - 1 do //Start the bucle
begin
GetModuleBaseName(PHandle, Modules[i], ModuleName, SizeOf(ModuleName)); //Getting the name of module
if AnsiCompareText(MName, ModuleName) = 0 then //If the module name match with the name of module we are looking for...
begin
GetModuleInformation(PHandle, Modules[i], @ModuleInfo, SizeOf(ModuleInfo)); //Get the information of module
Result := ModuleInfo.lpBaseOfDll; //Return the information we want (The image base address)
CloseHandle(PHandle);
Exit;
end;
end;
end;
end;
var
ProcessID : Cardinal;
begin
Label1.Caption := (string(GetModuleBaseAddress(ProcessID, 'Gothic2.exe')));
end;
Coś jest nie tak, bo label1 robi się pusty.
Sorry że tak wklejam linki, ale szkoda czasu na tłumaczenia :) http://forum.cheatengine.org/viewtopic.php?t=559714&sid=6c35dfcca6d151fad10a50e15318120e
A jak to wykorzystać do mojego celu?
Label1.Caption := ReadProcessMemory(PHandle(Pointer(DWORD(GetModuleBaseAddress(PId, ProcessName))), @Name, 8, buffer);
wówczas pisze, że PID jest undeclared.
Label1.Caption := ReadProcessMemory(PHandle(Pointer(DWORD(GetModuleBaseAddress('Gothic2.exe'))), @Name, 8, buffer);
Incompatible types: 'cardinal' and 'string';
Dobra, napisałem długiego posta, potem wytestowałem ten Twój kod, potem poszukałem w necie i mam wnioski:
Z tego Twojego kodu wynika że korzystasz z JCL i generalnie pakietu JEDI. Zapomnij o tym! To niby ułatwia różne rzeczy, a potem będziesz płakać jak zrobić w zwykłym StringGridzie podświetlenie/zaznaczenia linijki.
Druga sprawa: po komunikacie Incompatible types: cardinal
and string
; można łatwo wywnioskować że mamy niezgodność typów (badum tssss...), czyli trzeba zapoznać się z funkcjami wspomagającymi konwersję typów (tu i tak to nie pomoże, ale uwierz mi i tak się przyda).
Po trzecie: użycie:
GetModuleInformation(PHandle, Modules[i], @ModuleInfo, SizeOf(ModuleInfo));
To są funkcje windowsowe, więc przy szukaniu rozwiązań proponuję do googla dopisywać MSDN.
I teraz do meritum: zapoznaj się proszę z ReadProcessMemory Skopiuj sobie ten kod, skompiluj, przyjrzyj mu się dokładnie i zobacz co z tego jest ci potrzebne (zaręczam że jest tam odpowiedź na Twoje pytanie). A i to nie jest tak, ze jestem ostatnim Wujem i robię ci na złość nie poprawiając kodu/nie pisząc kodu. Wszyscy tutaj uczyli się kopiując z gotowców i patrząc jak to działa (BTW są trzy fazy programowania: 1. czemu to k.. nie działa, 2. O! k.., działa! i 3. jak to k.. działa).
function GetBasePointerOfModule(ProcessId: dword; Modulename: string): Integer;
var
FSnapshotHandle: THandle;
FModulEntry32: MODULEENTRY32;
s: string;
begin
Result := 0;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessId);
try
if FSnapshotHandle <> INVALID_HANDLE_VALUE then
begin
FModulEntry32.dwSize := SizeOf(FModulEntry32);
if Module32First(FSnapshotHandle, FModulEntry32) then
begin
repeat
s := FModulEntry32.szModule;
if s = Modulename then
begin
Result := Integer(FModulEntry32.modBaseAddr);
break;
end;
until (not Module32Next(FSnapshotHandle, FModulEntry32));
end;
end;
finally
closeHandle(FSnapshotHandle);
end;
end;
var
GameHandle : Cardinal;
BaseAddress : int64;
Addr : Int64;
Window : cardinal;
PID : cardinal;
begin
Window := FindWindow(nil,'Gothic2');
GetWindowThreadProcessId(Window,PID);
GameHandle := OpenProcess(PROCESS_VM_READ,false,PID);
if GameHandle > 0 then
begin
BaseAddress := GetBasePointerOfModule(PID, 'Gothic2.exe');
edit2.text := ('$')+inttostr(BaseAddress);
end
else
showmessage('Open Game');
end;
Chyba jestem blisko, jednak to wciąż nie to. Dlaczego edit2.text := $3604480, kiedy powinien być $C924F98 ? Co robię źle?
Powinno być:
edit2.text := Format('0x%0:x', [BaseAddress]);
lub jak wolisz:
edit2.text := Format('0x%0:.8x', [BaseAddress]);
ale to nie rozwiąże tego problemu(?). Skąd wiesz jaki adres jest prawidłowy, bo podany przez Ciebie nie wygląda mi na taki (jak na exe apki)?
A no chodzi o to, że gdy podłączę cheat engine z jakimkolwiek exe i zrobię pointer, który załóżmy będzie wyglądać tak:
"Gothic2.exe"+0033EC50 wówczas wychodzi -> 08947BB8, więc jestem wstanie sprawdzić jaki addres ma dany proces poprzez odwrotne działanie : 08947BB8-0033EC50 = 8608F68. Właśnie taki adres chciałbym otrzymywać w delphi nie piernicząc się w CE.
Ten address, który odczytuję jest dobry, jednak w Delphi nie potrafię go wykorzystać tak jak to jest wykorzystywane w CE.
Proszę:
Mi pojawia się błąd już w "1" równaniu:
Dlaczego? Bo 01150000 + 0033EC50 nigdy mi nie wyjdzie 0C640008, bo gdy dodam $3c0 nie zwraca mi ten adres żadnej wartości. Jeżeli zaś pominę pierwsze równanie znając Od razu wynik i zrobię w delphi tak: $0C640008 + $3c0, to wynik jest poprawny:
Spinedit5.value := round(memreaddouble(($0C640008+$3c0)));
Jakimś dziwnym trafem (mój nieogar) w delphi nie poprafię tego równania zaczynając od "1" wykonać poprawnie, a CE robi to bez problemu.
Nie znam sie na Chat Engine (nigdy sie nie bawiłem) ale faktycznie tam masz zaznaczony Pointer to może czyta wartość z pod tego adresu (sumy 01150000 + 0033EC50) i gdyby odczytać z tego adresu DWORD może by wyszło właśnie to 0C640008. W końcu zaznaczone Pointer nie jest dla jaj.
Pointera używa się do odczytywania wartości z dynamicznych addressów.
Adres od processu zmienia się za każdym razem gdy uruchomię *exe file na nowo.
Adresem nie zmieniającym się w moim przypadku jest 0033EC50, natomiast 3c0 jest offsetem, który jest potrzebny do odczytania tego, co chcę odczytać.
Dlatego wygląda to tak
(odczytany adres z exeka) 01150000 + 0033EC50 + 3c0.
w cheat engine może to również wyglądać tak:
"Gothic2.exe" + 0033EC50 + 3c0 i wyjdzie na to samo.
Jako że adres z exeka się zmienia musiałem pierw mieć kod, który mi go będzie odczytywać. Niestety nie wiem dlaczego w cheat engine całe działanie działa poprawnie, a u mnie nie. Coś jakby odczytany adres nie był zbyt poprawny do tego typu równania.
W autoit wygląda to tak:
Local $Staticoffset = 0x0033EC50
Local $hOpen, $sRead
$PID = ProcessExists("Gothic2.exe")
$hOpen = _MemoryOpen($PID )
Local $Base = _MemoryModuleGetBaseAddress($PID, 'Gothic2.exe')
$sRead = _MemoryRead($Base + $Staticoffset, $hOpen, 'dword') + 0x3c0
Takie coś zamienia mi na numer
ShowMessage(inttostr($001C0000 + $0033EC50 + $3c0));
Jak zrobić, by wynik też był hexem? xd
Tylko jak to ogarnąć w równaniu, bo zaczyna mi się robić takie coś:
Edit11.Text := IntToHex(BaseAddress,8) + IntToHex($0033EC50,8) ->> 013E00000033EC50. Client Base Address wynosi: 013E0000.
Pierw wolałbym to ogarnąć.
Powodzenia w ogarnianiu czegoś, czego nie ogarniesz bez chociażby podstawowej wiedzy.
Tak czy inaczej wychodzi mi jakieś g**no.
Wychodzi to co ma wychodzić - wynik jest jak najbardziej prawidłowy:
0x013E0000 + 0x0033EC50 = 0x0171EC50
Jak nie wierzysz to sprawdź w kalkulatorze.
@kAzek ma racje to jest pointer.
Oczytaj wartość z adresu $013E0000 + $0033EC50 +$3c0 a następnie z tej wartości odczytaj właściwe dane.
Poniżej pseudokod w pascalu.
var
addr: dword;
val: integer;
i: Longword;
begin
{...}
ReadProcessMemory(handleprocesu, Pointer($013E0000 + $0033EC50 +$3c0),@addr,i);
ReadProcessMemory(handleprocesu, Pointer(addr),@val,i);
{...}
end;
ProcessID
jaką ma wartość? Kodu sformatować nie potrafisz a bawisz się w hakiera...