Tento text vyžaduje základnú znalosť C/C++ alebo aspoň PHP
Ahoj, nato aby si mohol čítať/zapisovať data z procesu hry máš 2 možnosti:
a ) ĽAHŠIA - použiješ ReadProcessMemory/WriteProcessMemory - https://msdn.microsoft.com/en-us/library/windows/desktop/ms680553%28v=vs.85%29.aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms681674(v=vs.85).aspx
b ) ŤAŽŠIA - do procesu hry dostaneš svoje .DLL, ktore obsahuje kód na čítanie/zápis dát, volá sa to DLL injection a výhodou je že pracuješ s pamäťou priamo, ako keby si ty písal tu hru a nie cez R/WProcesMemory, ktoré je pomalé, lebo ide cez Windows.
Ďalej ku samotnej pamäti. Existuje statická, dynamická pamäť (halda) a stack. V základe sa dá povedať:
a ) statická pamäť - všetky premenné, ktoré dáš na začiatok programu (mimo main() a funkcií), pri spustení programu majú rovnakú adresu
b ) dynamická - všeky premenné / štruktúry/ barčo, vytvorene cez new, napr. int* premenna = new int();
c ) stack - tu sú uložené všetky premenné, vytvorené počas behu funkcie (keď do funkcie na začiatok dáš int premenná, tak bude v stacku a po skončení funkcie "zmizne")
Čo sú to pointery (ukazatele)?
napr.
int* pointer = new int();
Pointer je zvyčajne vytvorený v statickej alebo stacku, a je to ukazateľ na isté pamäťové miesto, to znamená, že nenesie priamo informáciu, ale len hovorí o mieste, kde tá informácia je
Čo je to offset
Predstav si, že máš takúto štruktúru:
struct Pozicia
{
int x,y,z;
}
Ďalej si predstav, že vieš na ktorom mieste v pamäti začína inštancia tej štruktúry (napr. 0xAABB)
Typ premennej integer berie 4 byty. Čiže ak chceš mať priamo prístup ku jednotlivým členom Pozicie, musíš preskočiť všetky členy pred ňou, tu je príklad:
0xAABB = štruktúra
0xAABB + 0x0 = x
0xAABB + 0x4 = y
0xAABB +0x8 = z
Čiže, v prípade z, hovoríme že BaseAddress (základná adresa) je 0xAABB a offset, teda jej vzdialenosť od základu je 0x8 bytov.
Pokiaľ je tento článok moc dlý na teba, tak sa vyser na programovanie, lebo toto je fakt základ od pamätiach
Samotné adresy a offsety môžeš v hre hladať cez memory searcher, napr. cez Cheat Engine (http://www.cheatengine.org)
Pokiaľ sa chceš dozvedieť viac, kľudne mi napíš na Skype (romop555).
Viem o týchto veciach veľa, keďže som zakladateľ www.lh-mp.eu
EDIT1:
Ohľadom meniacich sa adries, sú to premenné uložené v halde, teda dynamicky alokovanej pamäti (pamäť, ktorá sa načíta až za behu programu)
Ukážem to na príklade:
PlayerStruct* lokalnyHrac = NULL;
void kedSaNacitahra()
{
// tu sa vytvorí inštancie tej štruktúry a jej adresa (miesto v pamäti) sa zapíše
// ukazatelu(pointer) lokalnyHrac
lokalnyHrac = new PlayerStruct();
}
Z toho kódu vyplývajú 2 veci:
samotná štruktúra hráča sa nachádza vždy inde, na náhodnom mieste
nie je to ale problém, lebo program má statický ukazateľ (je vždy na tom istom mieste v pamäti) a skrz neho pristupuje ku pamäti
Teraz si predstavme príklad:
V hre je hráč, ktorý vrámci svojej štruktúry má premennú životy. Táto štruktúra je v dynamickej pamäti. Nájdi spôsob ako po každom spustení hry sa dostaneš na pozíciu životov.
Povedzme, že máme spustenú hru a vieme kde sa nachádzajú náboje (zistíš to napr. cez ten Cheat Engine).
Potrebujeme ale teraz zistiť, aký má offset, teda ako ďaleko sa nachádza od začiatku štruktúry.
Toto sa dá zistiť v Cheat Engine skrz právy klik-> Find out what writes to this address.
Tam pravdepodobne dostaneš riadok Assembler kódu, ktorý ukazuje adresu začiatku štruktúry + offset.
Zapamätáš si offset a dáš si vyhľadať ten začiatok štruktúrz skrz Cheat Engine. Pokiaľ ti nájde zelenú adresu (statický pointer), ktorej hodnota bude adresa štruktúry lokálneho hráča, tak máš vyhrané.
Teraz v skratke ako pracovať s takými datami, pokiaľ vieš kde je statický pointer a poznáš offsety premenných, ktoré chceš dosiahnuť.
Nech pointer (napr. 0xABBABBA) je ukazateľ na adresu začiatku štruktúry, napr. 0xDEADBABA a offset ku životu je 0x10 (16 bytov).
Pseudo kód v C++:
// získajme skrz pointer základnú/začiatočnú adresu štruktúry, tzv. base address
DWORD adresaStruktury = ReadProcessMemory(......,0xABBABBA,......);
// prirátajme k základu offset životov
DWORD adresaZivotov = adresaStruktury + 0x10;
// teraz napr. nastavme 100 zivotov (integer)
WriteProcessMemory(....,adresaZivotov,100);
DOPORUČUJEM PREJSŤ SI CHEAT ENGINE TUTORIAL (PRIAMO V PROGRAME), kde sa priamo naučíš ako získať offsety, atď.