Krátký kurs editace pozic 2

Minule jsme si ukázali několik způsobů jak hledat a měnit důležité hodnoty v pozicích pomocí porovnání několika pozic. Nyní budeme pokračovat v tažení proti sadistickým tvůrcům her a ukážeme si další techniky editace. Opět si vše vyzkoušíme na pozicích ze hry Diablo 2.
Minule jsme si ukázali několik způsobů jak hledat a měnit důležité hodnoty v pozicích pomocí porovnání několika pozic. Nyní budeme pokračovat v tažení proti sadistickým tvůrcům her a ukážeme si další techniky editace. Opět si vše vyzkoušíme na pozicích ze hry Diablo 2.

Nyní se pokusíme vyhledávat konkrétní hodnoty ze hry. K tomuto účelu budeme potřebovat postavu zcela bez vybavení. Předměty by totiž mohly ovlivnit některé hodnoty, a ty by se pak neshodovaly s uloženými. Většina her ukládá pouze základní hodnoty bez modifikátorů a skutečné dopočítá postupně jak na postavu „navléká“ vybavení. Podobně je tomu s kouzly- tyto experimenty je nutno provádět s postavou, která není žádným kouzlem ovlivněna (v Diablu 2 splněno vždy) a v ideálním případě i žádnou dovedností nebo příslušné modifikátory odečíst. Nyní si zapíšeme co nejvíce důležitých hodnot, které musí být v pozici uloženy (nelze je tedy odvodit ani vypočítat). K těmto hodnotám patří většinou základní vlastnosti postav, počet surovin a peněz a podobně. Naopak zbytečné jsou odvozené nebo pevně dané hodnoty jako síla útoku (postavy/jednotky), úspěšnost zásahu, rychlost výroby ve městě atd. V případě Diabla 2 si zapíšeme hodnoty dle tabulky a převedeme do šestnáctkové podoby.

Jméno vlastnosti Hodnota desítkově Hodnota šestnáctkově
Úroveň (Level) 70 46
Zkušenost (Experience) 285 212 699 11 00 00 1B
Síla (Str) 180 B4
Zručnost (Dex) 115 73
Vitalita (Vit) 90 5A
Energie (Energy) 45 2D
Životy (Life) 319 01 3F
Mana 47 2F
Zlato v batohu 12 345 30 39
Zlato v bedně 40 306 9D 72
Prozatím necháme být Staminu a odolnosti, protože mohou být ovlivněny dovednostmi Increased Stamina a Natural Resistance. Životy a mana má maximální i aktuální hodnotu. Zapíšeme si pouze maximální hodnoty a aktuální prozatím necháme stranou, jelikož mohou být zapsány různými způsoby (absolutně, procentuálně, číslem s plovoucí řádovou čárkou…). Další hodnoty jsou odvozené a s největší pravděpodobností je v uložené pozici nenalezneme. Otevřeme soubor ukazka2.d2s pomoci hexadecimálního editoru a pokoušíme se najít zaznamenané hodnoty. Už z minulého dílu víme, že zkušenost je zapsána v buňkách 261 až 264 a můžeme tedy předpokládat, že i ostatní hodnoty týkající se hlavní postavy budou poblíž. Opět si musíme uvědomit, že v souboru jsou důležitější číslice čísla vpravo, zatímco běžně je píšeme vlevo. Jednotlivé bajty tedy musíme číst i zapisovat pozpátku. Koukneme se na výše zmíněné bajty, což potvrdí náš předpoklad – vidíme tam hodnoty 1B 00 00 11. Ostatní hodnoty nalezneme snadno opticky v okolí nebo pomocí vyhledávání, protože jsou natolik malé, že jsou odděleny nulami. Většinou také odpovídá pořadí hodnot ve hře a v pozici, ale není tomu tak vždy.Pokud nalezneme dvě stejné hodnoty, musíme zjistit jejich význam experimentem. Zde je tabulka adres, kde jednotlivé hodnoty nalezneme:
Jméno vlastnosti Adresa (první bajt)
Úroveň (Level) 25D
Zkušenost (Experience) 261
Síla (Str) 235
Zručnost (Dex) 23D
Vitalita (Vit) 241
Energie (Energy) 239
Životy (Life) 24A
Mana 24E ,252
Zlato v batohu 265
Zlato v bedně 269
Číslo, které odpovídá počtu many, tedy nalezneme dvakrát. V takovém případě přistoupíme k časově nejnáročnější technice. Změníme podezřelou hodnotu v uložené pozici a sledujeme změny po načtení hry. Naštěstí teď máme k prozkoumání pouze dvě hodnoty. Dosazením jiných hodnot na adresy 24E a 252 zjistíme, že na první adrese je aktuální hodnota a na druhé je maximální hodnota many (Aktuální hodnota musí být menší nebo rovna maximální hodnotě. Pokud této podmínce nevyhoví – automaticky se sníží.). Nyní můžeme všechny čísla v rozumných mezích měnit.

Podívejme se nyní na blok 26F až 28C. Hodnoty tam uložené zcela evidentně mají velikost jeden bajt a pohybují se v rozmezí 0 až 20 (14 hexa). To nás může přivést na myšlénku, že jsou zde uloženy hodnoty jednotlivých dovedností. Pokud se pokusíme porovnat posloupnosti ve hře a v pozici narazíme na problém, že způsobů jak zapsat jednotlivé dovednosti,je mnoho. Pokud chceme zjistit, která pozice odpovídá za kterou dovednost, čeká nás spousta práce. Od adresy 26F zapíšeme do jednotlivých buněk 01, 02, 03,… až 14 (nezapomeneme na 0A, 0B atd.), zbytek bloku vyplníme nulami a pak si ve hře zapíšeme, kterému číslu odpovídá která dovednost. Zjistíme např., že dovednost Bash má jeden bod. Jedničku jsme zapsali na adresu 26F a tento bajt tedy za dovednost Bash odpovídá. Další dovednosti zjistíme stejným způsobem:

Dovednost Počet bodů Adresa
Bash 1 26F
Sword Mastery 2 270
Axe Mastery 3 271
Mace Mastery 4 272
Howl 5 273
Find Potion 6 274
Leap 7 275
Double swing 8 276
Teď si již jistě všimneme závislosti mezi zapsanou pozicí a polohou dovednosti na jednotlivých listech (Pro ty, co nedisponují hrou Diablo 2: dovednosti jsou zapsány na třech listech, čím níže se nalézají, tím vyšší je požadovaná úroveň k jejích dosažení.). Stačí slepit jednotlivé listy v opačném pořadí (zleva: Combat Skills, Combat Masteries, Warcries) a pak zjistíme, že jsou dovednosti zapsány v pořadí zleva doprava a seshora dolů (tak, jak čteme v knize). Dále tedy nemusíme pracně experimentovat a zbytek dovedností už odvodíme. Tak jednoduché rozdělení ale zdaleka nemusí být v každé hře. V takovém případě bychom výše zmíněným způsobem zjistili prvních dvacet dovedností. Pak bychom bajty 26F až 282 vynulovali a bajty 283 až 28C vyplnili hodnotami 01 až 0A a obdobným způsobem zjistili dalších deset dovedností.

Můžeme se pokusit zapsat do některého z bajtů zodpovědných za dovednosti zapsat hodnotu mimo mez. Napíšeme tedy na adresu 26F třeba 15 (tedy 21 decimálně, maximální hodnota ve hře je 20 decimálně). Načtení hry se nezdaří ale po přepnutí do Windows (Ctrl-Alt-Tab) uvidíme chybovou hlášku říkající, že rozmezí pro dovedností bylo překročeno. Pokud bychom nevěděli, za co je tento bajt zodpovědný – dověděli bychom se alespoň to, že se tato hodnota týká dovedností. Metodou cíleného vyvolávání chyb lze v nouzi zjistit mnoho informací, je však zdlouhavá a funguje jen v dobře napsaných hrách. Pokud ji chceme přesto použít je vhodné použít „univerzálních“ mezních hodnot (Většinou 00, FF, 80 pro jednobajtové hodnoty, 00 00, FF FF, 80 00 pro dvoubajtové hodnoty a podobně. Pokud nevíte proč 80 a 80 00 určitě si zopakujte první díl kurzu!).

Dále se budeme zabývat předměty. Opět si pro rychle pochopení datové struktury popisující předměty připravíme vhodnou pozici, měla by vlastnit pouze jeden (pro začátek nekouzelný) předmět umístěný v batohu. Parametry toho předmětu si pečlivě zaznamenáme. V našem případě se jedna o obyčejný Quilted Armor (defense 8, durability 20/20, Required STR 12). Již od minula víme, že jednotlivé předměty jsou zaznamenané na konci souboru vždy mezi bajty s hodnotou 4A 4D (Ve znakové reprezentaci jsou to písmena JM. V hexadecimálním editoru je vidíme v pravém pruhu.). Dále budeme používat relativní adresy, protože jsou výhodnější pro určování adresy v pohyblivém bloku. Musíme si uvědomit, že později bude naše postava mít více předmětů a pak bychom museli určovat absolutní adresy pro každý z nich. Vhodnější je tedy určit relativní adresu vůči začátku bloku. V našem případě budeme určovat adresy právě od sekvence 4A 4D uvozující každý předmět. Pokud tedy napíšeme adresa +5, máme na mysli adresu posledního bajtu uvozující sekvence (tedy bajtu s hodnotou 4D) plus pět. Tento způsob budeme velmi často používat, a proto je vhodné se s ním dobře seznámit. Relativní adresy budeme moci vztáhnout k uvozující sekvenci každého předmětu stejného druhu. V jiných hrách budeme podobně určovat adresy hodnot určujících vlastnosti měst, vojenských jednotek a podobně. Nyní bude pro nás bázová adresa rovna 28E. Když analyzujeme tento úsek, ihned nám padnou do oka bajty na adrese 29E (relativně +0C) a 29F (relativně +0D) oba s hodnotou 28 (40 decimálně). Tato hodnota sice neodpovídá žádné hodnotě, kterou jsme si poznamenali, přesto je patrné, že se bude jednat o výdrž (Durability) předmětu. Zapíšeme třeba 36 (60 decimálně) na adresu 29E a 46 (70 decimálně) na adresu 29F a zjistíme, že máme brnění s výdrží 30/35 z čehož vyplývá, že první bajt je aktuální a druhý maximální hodnotou. Je také zřejmé, že se jedná o dvojnásobek výdrže, která se zobrazuje ve hře. Dále se podíváme na sekvenci na adrese +6 až +9 (absolutně 298 až 29B). Měnění bajtu +6 (absolutně 298) nepřináší žádné změny. Pouze metodou cílené chyby (hodnota 00) se dozvíme, že se jedná o nlevelID. Tato hodnota bude mít později význam především pro kouzelné předměty (prozatím stačí vědět, že jsou lepší vyšší hodnoty). Několik pokusů napoví, že následující (+7 a +8) bajty spolu souvisí a mají vliv na typ předmětu. Když tam napíšeme FF 0D, dostaneme helmu Casque (armor 63), FF 0E odpovídá Embossed Plate, FF 0F odpovídá Sharkskin Boots... Zde je možností opravdu nepřeberně a experimenty nechám na vás. Hodnoty můžete samozřejmě opsat z jiných pozic. Další bajt +9 (absolutní adresa 29B) je opět velmi důležitý a má následující význam (zjistíme postupným vyzkoušením):

Hodnota Význam
00 Předmět je vzácný (Rare)
01 Předmět je vzácný (Rare), v ruce
02 Poškozený předmět
03 Poškozený předmět, v ruce
04 Obyčejný předmět
05 Obyčejný předmět, v ruce
Nyní si můžeme všimnout, že každá druhá hodnota znamená, že předmět je v ruce a ne v batohu. Z toho můžeme okamžitě usoudit, že bajt +9 je rozdělen minimálně na dvě části: nultý bit určuje, jestli je předmět v ruce (hodnota 1) či v batohu (hodnota 0) a ostatní bity (první až sedmý) mají jiný význam (Pozn.: bity číslujeme zprava doleva. Nultý bit je tedy nejméně významným bitem.). S touto technikou se setkáme při editaci pozic velmi často (většinou je ale části více) a je velmi vhodné takové závislosti brzy odhalit. Nyní nám stačí testovat pouze každou druhou hodnotu. Pokud budeme chtít pak dostat předmět v ruce – přičteme jedničku. Pokud máme podezření, že je bajt rozdělen do několika významově odlišných části potupujeme tak, že testujeme postupně tyto hodnoty (dvojkově): 00000001 (01 hex), 00000010 (02 hex), 00000100 (04 hex) až 10000000 (80 hex), tedy přetestujeme zvlášť význam každého bitu. Uveďme si zde imaginární (Pozor, nemá s Diablem 2 nic společného!) příklad jak by takový test mohl probíhat:
Testovaná hodnota (hex) Číslo testovaného bitu Efekt
01 0 Předmět lehce poškozen
02 1 Předmět středně poškozen
04 2 Kouzelný předmět
08 3 Prokletý předmět
10 4 Váha předmětu 1 jednotka
20 5 Váha předmětu 2 jednotky
40 6 Váha předmětu 4 jednotky
80 7 Váha předmětu 8 jednotek
Pokud předpokládáme, že předmět muže být zároveň kouzelný i prokletý, zjistíme, že tento bajt je rozdělen do čtyř částí. První dva bity (bit 0 a 1) zodpovídají za poškození předmětů, bit 2 zodpovídá za to, zda je předmět kouzelný, bit 3 říká jestli je předmět prokletý, bity 4 až 7 určují váhu předmětu (je zapsána normálně v přímém kódu, ale na posledních bitech). Pokud chceme mít jistotu, vyzkoušíme ještě hodnotu 11001111, což dá těžce poškozený předmět s váhou 15 jednotek, a to naše předpoklady potvrzuje. První dva bity mají tedy tento význam:
Hodnota (bin) Význam
00 Bez poškození
01 Lehké poškození
10 Střední poškození
11 Těžké poškození
Pokud např. chceme nepoškozený kouzelný předmět s váhou pět jednotek, postupujeme následovně: převedeme 5 do dvojkové soustavy (0101) zprava přilepíme 0 protože nechceme prokletý předmět (01010), přilepíme jedničku, protože chceme kouzelný předmět (010101), a podle tabulky přilepíme dvě nuly, protože chceme nepoškozený předmět (01010100), a nakonec číslo převedeme do šestnáctkové podoby (54) a tuto hodnotu zapíšeme na příslušnou adresu v pozici. Nyní můžeme pokračovat v zjišťování dalších hodnot v Diablu 2:
Hodnota Význam
06 Předmět je kvalitní (superior)
08 Předmět je kvalitní (superior) nebo kouzelný dle typu
0A Kouzelný předmět
0C Předmět je vzácný (Rare)
0E Předmět je unikátní (Dostaneme chybovou hlášku jelikož unikátní předmět musí mít správně nastaveny ještě další hodnoty. Především se jedná o typ předmětu.)
Ostatní hodnoty nemají žádný význam. Pro různé typy předmětů se uvedené hodnoty můžou lišit. To, že má hodnota 01 a 0C stejný význam, je podezřelé a budeme muset později zjistit pravý význam.

Poslední je sekvence hodnot na adresách +14 až +1C. Několika pokusy zjistíme, že tyto hodnoty mají vliv jen na vzácné a kouzelné předměty, a proto pro další experimenty zapíšeme na adresu +9 hodnotu 00 a typ předmětu změníme tak, aby mohl být kouzelný (třeba na brnění). A zde jsou opět obrovské možnosti pro experimentátory. Prvních osm bajtů této sekvence je totiž číslem, podle kterého se vlastnosti generují. Dle mého názoru se jedná o počáteční hodnotu generátoru náhodných čísel (random seed), ale když někdo najde nějaké přesnější závislosti, budu velmi rád. Devátý bajt (adresa +1C) sekvence se pohybuje v rozmezí 00 až 06. Dle mého názoru se ze zvyšujícím číslem zvyšuje i kvalita předmětu zdaleka si tím ale nejsem jist.

K editaci předmětů je nutno poznamenat, že editace „oblečených“ předmětů může být mnohem problematičtější, a proto se snažíme vždy editovat předmět v batohu umístěný tak, aby měl kolem sebe dostatek místa (2x5 políček), abychom mohli bez obav měnit jeho typ.

Pro majitele Diabla 2 zde mám ještě na procvičení jeden snadný domácí úkol – zjistit, kde jsou v pozici zaznamenány hodnoty nepřidělených bodů (k zvyšování základních vlastnosti i dovednosti) a stamina.

V tomto díle jsme si ukázali, jak se přímým způsobem hledají a mění uložené hodnoty, jak použít metodu vynucené chyby, jak se interpretují rozdělené bajty a jak se používají relativní adresy. Příště budeme v našem snažení pokračovat už na příkladech jiných her.

Diskuze (3) Další článek: Pásku přes oko a papouška na rameno - staňte se cvokem!

Témata článku: , , , ,