(Nem látszanak a képek? Klikk ide.)
A kiszemelt játék az 1988-as Pandora (kalandjáték némi akcióval), amiben egy tékozló űrállomás visszatér földközelbe és a menetközben kissé megkattant fedélzeti kompjúter viccből szeretné megszórni a Földet némi mutáns spórával, lehetőleg még ebéd előtt. Főhősünk - valami noname zsoldos - azért érkezik az űrállomásra, hogy kiderítse, hogy mi a fene folyik itt, majd miután kiderítette, "levegőbe repítse" az egész űrállomást. (Ugye ez már repül és nem levegőben...)
Indítsuk el a játékot. Shift+F12-vel hívjuk be a debuggert.
Kezdetnek keressük meg az időt, mert az folyamatosan csökken, tehát azt rögtön tudjuk is keresni. A WinUAE debuggerében az "S"
paranccsal (Note: minden parancs case-dependent!) lehet kimenteni a memória egyes részeit, kezdőcímtől egy megadott hosszig. A játék 512 kB-os Amigákra volt fejlesztve, tehát nekünk a Chip RAM tartomány első 512 kB-ja kell. (A dump-ok a WinUAE könyvtárába kerülnek. Minden értéket hexában kell megadni.)
S pandora0 0 80000
Mivel a változást csak több dump-pal tudjuk vizsgálni, ezért tovább kell engedni a programot a "g"
paranccsal, majd miután az idő csökkent egy picit, megint Shift+F12-vel behívni, majd csinálni egy újabb dump-ot, mondjuk "pandora1"
néven. Aztán megismételni a folyamatot párszor.
A dumpok összehasonlítására mindenki olyan módszert használ, amilyet akar, én írtam magamnak a célra egy programot, aki akarja, használja, viszont én a leírásban ezt fogom használni.
Amint látszik a játékban, az idő 9999-ről mászik szépen visszafelé. Mivel egy byte-on 9999-et vajmi kevés eséllyel lehet eltárolni, így kézenfekvő, hogy 16-bites értékeket kell keresnünk, valamint - mivel Amigán vagyunk - big-endian értékekről beszélünk.
mdsc -b16b -dec pandora0 pandora1 pandora2 pandora3 pandora4 pandora5 pandora6 pandora7
Az eredmény:
00003c82: 39234, 39207, 39188, 39169, 39048, 38995, 38978, 38951
000586fe: 9773, 9711, 9660, 9609, 9555, 9419, 9372, 9314
00059480: 1453, 1439, 1391, 1339, 1291, 1191, 1105, 993
00059b76: 9773, 9711, 9660, 9609, 9555, 9419, 9372, 9314
00059dbe: 9773, 9711, 9660, 9609, 9555, 9419, 9372, 9314
0005b944: 9773, 9711, 9660, 9609, 9555, 9419, 9372, 9314
0005c216: 9773, 9711, 9660, 9609, 9555, 9419, 9372, 9314
Látunk összesen hét db címet, de ebből ötön ugyanaz a szekvencia látszik, aminek semmi értelme, tehát kizárhatjuk. Marad tehát a $3c82
-es és a $59480
-as cím, viszont egyik sem úgy néz ki, mintha 9800-9999 közti értékek lennének ott tárolva. Kivéve, hogy a régi gépeken nem volt ritka, hogy számlálókat BCD módon kezeltek. Egyrészt mert így egyszerű volt kiírni, másrészt meg mert a processzorok ezt hardware-ből támogatták. Tehát nézzük meg az értékeket hexában:
mdsc -hex -b16b -dec pandora0 pandora1 pandora2 pandora3 pandora4 pandora5 pandora6 pandora7
Eredmény:
00003c82: 9942, 9927, 9914, 9901, 9888, 9853, 9842, 9827
000586fe: 262d, 25ef, 25bc, 2589, 2553, 24cb, 249c, 2462
00059480: 05ad, 059f, 056f, 053b, 050b, 04a7, 0451, 03e1
00059b76: 262d, 25ef, 25bc, 2589, 2553, 24cb, 249c, 2462
00059dbe: 262d, 25ef, 25bc, 2589, 2553, 24cb, 249c, 2462
0005b944: 262d, 25ef, 25bc, 2589, 2553, 24cb, 249c, 2462
0005c216: 262d, 25ef, 25bc, 2589, 2553, 24cb, 249c, 2462
Így már mindjárt látszik, aminek látszania kell. Próbáljuk "megfagyasztani" a címet, ami úgy néz ki, hogy
w <a fagyasztott cím sorszáma> <cím> <hossz (egy cím esetén 1)> <művelet ("F" mint faggyá'le)> <érték[.b/.w/.l, attól függően, hogy milyen széles az érték, de egyértelmű esetekben elhagyható (pl. ami nagyobb, mint 65535 az tuti .l)]>
Tehát:
w 0 3c82 1 F ffff
Most már van örök időnk.
Nézzük most a másik rögtön szembetűnő tulajdonságot, az életerőt. Hogy megtaláljuk, csökkenteni kéne egy kicsit. Ehhez mondjuk keveredjünk bunyóba, az itt kolbászoló "szimpatikus" huligánnal, aki nem tudom, hogy került fel egy kutatóállomásra, de mindenesetre azt a szerepkört tölti be, hogy egy irídiumbuzogánnyal veri szét az állomás berendezését, meg azokat, akik az útjába kerülnek. (A Mir-en tuti rögtön agyonverték volna az oroszok...)
A harc kezdetén mentsünk dump-ot, majd tegyük ugyanezt minden ütése után. Ha agyonvert minket, akkor:
mdsc -dec pandora0 pandora1 pandora2 pandora3 pandora4 pandora5
00003ba9: 180, 135, 115, 91, 56, 18
0005c35f: 95, 74, 53, 32, 11, 0
00071bed: 169, 128, 32, 16, 1, 0
00071c15: 169, 128, 32, 16, 1, 0
00071f5c: 248, 195, 192, 144, 16, 7
Itt megint van kettő olyan cím, amin ugyanaz van, azokat azért zárhatjuk ki, viszont van két olyan is, ami nem nullával végződik, márpedig hagytuk magunkat kinyírni, tehát azzal kell. (Egyelőre feltételezvén, hogy a játék nem valami trükkös módon tárolja az életerőt.) Marad tehát a $5c35f
cím, ami mellett az is szól, hogy minden lépésben ugyanannyival - 21-gyel - csökkent; kivéve persze az utolsó lépést, dehát negatívba nem mehet az életerő. Fagyasszunk.
w 1 5c35f 1 F 7f
Fagyasztás után látszik, hogy még kinyiffanás után is azt írja ki, hogy "GOOD". (Induláskor, ha megmoccanunk, kinyúvadunk, mert nem mászkálhatunk az állomáson ID nélkül, mert agyonsokkol minket. Ezért meg kell várni, amíg a beléptetőtiszt odajön és a kezünkbe adja a sajátját. Beszélni már nem tud, mert az állomás ad neki pár Ampert, azt meg nem szeretik a beléptetőtisztek. Bezzeg, ha villanyszerelő lett volna...)
Most már van örök életünk is. (A játékban a maximum életerő 95 pont ($5f
), de maga a játék 127-ig ($7f
) kezeli; a 95 feletti érték ugyanúgy "GOOD"-ként jelenik meg, csak tovább tart, mire lemegy "FAIR"-be. Ha ennél nagyobb értéket adunk meg, akkor azonnal kinyúvadunk. (Negatívba ment az életerő.) Ha nullát, akkor csak kiírja, hogy "DEAD", de mászkálhatunk tovább, viszont, ha harcba keveredünk, akkor instant kámpec.)
A bunyó közben feltűnhetett a "HIT" feliratú doboz, meg a benne szaladgászó csík. A bunyó itt úgy megy, hogy az idővel megy felfele a hitpower, tehát minél később ütünk, annál nagyobbat ütünk, viszont az első két szakaszban még nem lehet ütni, az utolsó kettőben (vörös vagy sárga színnel jelöli a gép) meg már nem lehet ütni, csak a középső ötödben. Azt viszont minél tovább hagytuk futni, annál nagyobbat ütünk. Persze a fegyverünktől is függ, hogy végül mekkora lesz az ütés, mert egy fényszablyával nyilván nagyobbat lehet odasózni, mint egy Shakespeare kötettel (igen, mindkettő van a játékban); az utóbbiból inkább célszerű felolvasni az ellenfeleknek, garantált instant exitus lethalis... (Bár van olyan állat a játékban, aki direkt kéri.) Azonfelül a fegyver függvénye az is, hogy milyen gyorsan töltődik a csík, pl. az említett fényszablya baromi lassan, a "sokkostor" meg eszméletlen sebességgel; akinél ilyen van, az majdnem garantáltan agyon fog bennünket verni, mert hiába üt viszonylag kicsit (a többi fegyverhez képest, mert amúgy azért ez se piskóta), ha másodpercenként háromszor húz ránk vele...
Keressük tehát meg a hitpower-t. Miután újrakezdtünk, keveredjünk ismét bunyóba a huligánnal, most már amúgy sem fog tudni minket kinyúvasztani. Várjuk meg, amíg a csík felfut a maximumra, majd újrakezdi, akkor Shift+F12, dump, majd vissza és hagyjuk felfele futni, menetközben dump-okat készítve. Aztán:
mdsc -inc pandora0 pandora1 pandora2 pandora3
00003be3: 5, 7, 8, 9
00003cab: 4, 18, 30, 38
00003cad: 1, 5, 9, 11
00059939: 24, 156, 196, 220
00059aad: 24, 156, 196, 220
00059ab1: 18, 150, 194, 218
0005acbd: 17, 19, 37, 49
0005b3cf: 152, 174, 192, 204
0005b4a1: 152, 174, 192, 204
0005b4a5: 152, 174, 192, 204
0005b531: 172, 177, 195, 207
0005b541: 85, 90, 108, 120
0005b679: 172, 177, 195, 207
0005b67d: 172, 176, 194, 206
0005bb41: 54, 124, 142, 154
0005bb51: 25, 95, 113, 125
0005bb93: 78, 114, 132, 144
0005bc3d: 62, 106, 142, 158
0005bf01: 54, 124, 142, 154
0005bf05: 50, 124, 142, 154
0005bf3f: 78, 114, 132, 144
0005bf43: 76, 112, 130, 142
0005bfc1: 62, 106, 142, 158
0005bfc5: 60, 104, 140, 158
00072e58: 2, 4, 128, 132
00072f9c: 79, 97, 128, 193
Itt sok értéket találtunk (akinek jó reflexei vannak, az megpróbálkozhat sűrűbb "mintavétellel" is). Az ismétlődők nyilván itt se játszanak, amúgy meg a szokásos trial and error. Tróbáljuk meg az elsőt fagyasztani arra a maximumra, ami a listában látszik:
w 2 3be3 1 F 9
Nem nyert, ez valami offset volt, nem a hitpower. Nézzük a következőt:
w 2 3cab 1 F 26
Talált. A probléma csak az, hogy a vörösben már nem lehet ütni. Pár tipp és megvan a középső ötöd felső határa.
w 2 3cab 1 F 18
Lezúztuk a huligánt. Nem kár érte. Kultúrember amúgy sem járkál magentában.
Namármost, a játékban van még egy lézerpuska is, kemény öt darab töltettel. Ezzel bárkit ki lehet ugyan nyúvasztani, de van egyvalaki, akit csak ezzel: a tolvajt (az is mit keres egy űrállomáson), aki huligán kollégájától egy köpésnyire északra szaladgászik jobbról balra, majd vissza és ha keresztülmegy rajtunk, kimarja ami a kezünkben volt. Ha nem volt semmi, akkor nem történt semmi, ha az utolsó ID-nk volt, akkor megszívtuk. Nos, ő nem verekszik velünk (ha fegyver van nálunk, azt is ellopja), tehát csak a lézerfegyverrel lehet kinyírni. (Három lövés.) Ami érdekes, hogy amit ellop, az utána nem lesz nála, hiába nyírjuk ki. Varázslatosan eladta valami láthatatlan orgazdának menet közben, vagy megette, vagy átteleportálta az ettől a folyosótól északra levő szobában dekkoló bankárnak (és az mit keres egy űrbázison; pénzt?), vagy nem tudom mit csinált vele... (A bankárt feltétlen nyírjuk ki, egyrészt mert jól esik, másrészt meg mert ugyanúgy "becsületpont" jár érte, mint a tolvajért, ami számít egynémelyik karakternél, ha csereberélni akarunk velük. Nem, ez nem vicc. (A huligánért miért nem jár?))
De ez mellékes. Mint mondtam a puskát bárki ellen lehet használni. Először is menjünk be érte a biztonsági tiszthez és szedjük fel a kék asztalról.
Utána csináljunk dump-ot, majd minden lövés után egyet.
mdsc -dec pandora0 pandora1 pandora2 pandora3 pandora4 pandora5
0001924e: 5, 4, 3, 2, 1, 0
Ez gyors volt. Fagyasszunk.
w 3 01924e 1 F ff
Most már végtelen lézerünk van.
Nos, akkor megvannak a címeink és az értékeink. Itt az idő, hogy kódolni kezdjünk.
Az Amigának van kettő darab CIA chipje, fejenként kettő darab timerrel, továbbá van 7 szintű megszakításrendszere, aminek a vektorait $64
-től $7c
-ig találjuk a memóriában. Ha visszanézünk a legelső képre, ott pont a nullás lap van a dump window-ban és lehet látni, hogy a level 3-as interruptot leszámítva csupa olyan cím van beírva rájuk, ami KickStart címekre mutat, vagyis a játék nem használja őket. A CIA A tud 2-es szintű (alacsony prioritású) megszakítást generálni, a CIA B pedig 6-ost (magas prioritású); mivel ez egy trainer, aminek folyton írnia kell bizonyos címeket, így célszerű az utóbbit használni ($78
-as cím). (Működne a másik is, csak abba belerondíthatna a használt VBlank level 3-as interrupt, ami magasabb prioritású.)
Akkor tehát, vannak címeink és értékeink:
HitPowerAddr equ $00003cab
MaxHitPower equ $18
HealthAddr equ $0005c35f
MaxHealth equ $5f
TimeAddr equ $00003c82
MaxTime equ $999a
LaserShotsAddr equ $0001924e
MaxLaserShots equ $05
Ezeket kellene kódból a helyükre rakni:
move.b #MaxHitPower,HitPowerAddr
move.b #MaxHealth,HealthAddr
move.w #MaxTime,TimeAddr
move.b #MaxLaserShots,LaserShotsAddr
Tulajdonképpen a lényegi rész ennyi is, csak vissza kéne térni az interruptból, amihez törölni kell a CIA B megszakítás flagjét (olvasással), valamint törölni a chipset megszakítás kérelmét jelző flag-et is:
tst.b CIAB+CIAICR
move.w #EXTER,CUSTOM+INTREQ
rte
Ehhez persze kellenek a használt system konstansok is:
CUSTOM equ $DFF000
INTREQ equ $09C
EXTER equ $2000
CIAB equ $BFD000
CIAICR equ $D00
Na, első körben egy hunkless, nyers binárist fogunk forgatni, hogy teszteljük a koncepciót. Erre a célra ott van pl. a vasm
:
vasmm68k_mot pat.s -Fbin -nosym -o pat -L pat.txt
A kapott "pat"
binárist másoljuk be a WinUAE könyvtárába, indítsuk el a játékot, majd kérjük a debuggert. Ott töltsük be a binárisunkat a $100
-as címre:
L pat 100
Csekkoljuk le, hogy minden oké-e:
dg 100
A jelek szerint igen. Akkor most leheljük életre a timert, a debuggerből. Először is állítsuk be a 6-os megszakítási vektort a rutinunk címére.
W 78 100.l
Utána az INTENA
regiszterben engedélyezzük a külső megszakításokat (ebbe a regiszterbe úgy kell írni, hogy ha simán beírunk egy flag-et, akkor töröljük, ha viszont a legfelső flaggel együtt írjuk be, akkor épp engedélyezzük, tehát ez itt a $2000
-es + $8000
-es flag-eket jelenti):
W dff09a a000
Állítsuk be a CIA timert, mondjuk 2048 ciklusra:
W BFD400 0
W BFD500 8
Állítsuk be a timer megszakításait az A timerre:
W BFDD00 81
Végül indítsuk el a timert, folyamatos módban:
W BFDE00 1
A cucc működik.
Ami azt illeti, már túl jól, mert akkor sem halunk meg, ha belesétálunk az elektromos kerítésbe.
Ilyenkor, ha nálunk van az az ID, ami azt a kerítést nyitja, akkor space-szel átválthatunk a tárgyakhoz és kézbevehetjük, vagy marad az F7, ami újrakezdi a játékot. Mindenesetre, az sem ártana, ha a trainerünk funkcióit ki-be lehetne kapcsolgatni a játék alatt.
Erre mondjuk megfelelnek az F2-től F5-ig terjedő gombok (az F1 a pause). Bele lehet rakni egy billentyűzetfigyelőt a rutinunkba is, de egyszerűbb felhasználni a játékét. A billentyűzetről bejövő adatok a CIA A soros regiszterében kötnek ki ($bfec01
-es cím), viszont 68000-esen a mindenféle regiszterbe írkálásokat többnyire offsetekkel szokták használni, mert kevesebb helyet foglal és regiszterből gyorsabb is. Azaz, először ne erre a címre, hanem a CIA A báziscímére ($bfe001
) keressünk. A keresés a "s"
paranccsal történik:
s bfe001
Eredmény
000107F9 00010865 0005BFDC 0005D7E3 0005E3F1 0006D7E3 0006E3F1 001107F9 00110865 0015BFDC 0015D7E3 0015E3F1 0016D7E3 0016E3F1
Nézzük először az első címet. (Mivel a kapott címek magukat az értékeket jelölik, itt mindig célszerű levonni hármat, (vagy ötöt), hogy az utasítás kezdőértékét kapjuk meg.)
dg 107f6
Ennek köze nincs a billentyűzetfigyeléshez. Ez - ha jól látom - azt nézi, hogy az egér jobb gombja nyomva van-e, vagy sem, legalábbis, akkor állít be igazat (-1
) egy címre, ha a CIA A A portján a hetedik bit nulla, (pontosabban: ha, a regiszterben egy pozitív szám van).
Nézzük a következőt.
dg 10862
Megvan. Ez betölti a0
címregiszterbe a báziscímet, majd $c00
-val offsetelve (a CIA-k soros regisztere) olvas egyet, utána pedig dekódolja (jobbra forgatás egyel és negálás), majd kimenti a6
-ot $222
-val offsetelve. Ez pedig a $3c1e
-es címet jelenti. (a6
tartalma itt mindig ugyanannyi, valószínűleg a játék egyik adatterületének báziscíme.)
Ha kicsikét kaparászunk visszafele, akkor megtalálhatjuk $10858
-nál az egész billentyűzetfigyelő rutint:
move.w INTREQR(a5),d0
btst #bPORTS,d0
beq pKDAT
lea CIAA,a0
moveq #0,d0
lea $397c,a1
move.b CIASDR(a0),d0
ror.b #1,d0
not.b d0
bclr #7,d0
seq (a1,d0.l,0)
bne pKDAT
move.b d0,$222(a6)
pKDAT: move.b #SPMODE,CIACRA(a0)
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
mulu.w #1,d0
clr.b CIACRA(a0)
move.w #RBF|PORTS|TBE,INTREQ(a5)
rts
Ez az INTREQR
regiszterből lekéri, hogy van-e I/O megszakítás-e, vagy sincs és ha van, akkor egyrészt kiírja $3c1e
-re a leütött billentyű kódját, valamint beállítja -1
-re a $397c
báziscímet a kód értékével offsetelve. Utána pedig pulzáló kimeneti módba kapcsolja a soros regisztert, majd vár...processzorból. Szorzással. Aztán lekapcsolja a vonal rángatását, törli a flag-eket és kiszáll.
A kimenő értékeket le is csekkolhatjuk. Játékon belül tenyereljünk rá először a Shift-re, aztán mondjuk az F3-ra (így az F3 lesz az aktív, nem a Shift) és utána az F12-re. Utána nézzük meg az érintett memóriaterületeket.
mg 397c
$52
byte-tal (F3 kódja) odébb, ott van a -1
.
mg 3c1e
És ott van a kód is a helyén.
Akkor helyben vagyunk. Írjuk át a trainert, hogy csak akkor írja az értékeket, ha az van beállítva neki.
HitPowerHack: cmp.b #0,THitPowerAddr
beq HealthHack
move.b #MaxHitPower,HitPowerAddr
HealthHack: cmp.b #0,THealthAddr
beq TimeHack
move.b #MaxHealth,HealthAddr
TimeHack: cmp.b #0,TTimeAddr
beq LaserShotsHack
move.w #MaxTime,TimeAddr
LaserShotsHack: cmp.b #0,TLaserShotsAddr
beq KeyboardHnd
move.b #MaxLaserShots,LaserShotsAddr
Ehhez kellenek a változók is:
THitPower: dc.b 0
THealth: dc.b 0
TTime: dc.b 0
TLaserShots: dc.b 0
Valamint, mivel ez abszolút címen lesz, ezért a címeket is ki kéne számíttatni az assemblerrel.
TORG equ $00000100
THitPowerAddr equ THitPower+TORG
THealthAddr equ THealth+TORG
TTimeAddr equ TTime+TORG
TLaserShotsAddr equ TLaserShots+TORG
Akkor a trainer maga már tudja is, amit kell, most már csak azt kéne lekezelni, hogy a billentyűzettel ezt a négy címet írni lehessen, hogy ki-vagy-be. Illetve, akkor már F6-ra kinullázhatjuk az időt, hogy lássuk mi történik, ha lejár. (Egyébként semmi. Kiírja a gép, hogy megérkeztünk, Pandora teleszórta az atmoszférát mocsokkal és mingyán kipusztul az emberiség. A játék megy tovább. Ez csak akkor számít, ha sikerült elpusztítani a bázist, de időn túl, olyankor az a konklúzió, hogy az emberiség jövője bizonytalan.)
ReadKeyboard: move.l d0,-(a7)
move.b KeystrokeAddr,d0
CheckF2: cmp.b #BtnF2,d0
bne CheckF3
eor.b #1,THitPowerAddr
bra SetKbdWait
CheckF3: cmp.b #BtnF3,d0
bne CheckF4
eor.b #1,THealthAddr
bra SetKbdWait
CheckF4: cmp.b #BtnF4,d0
bne CheckF5
eor.b #1,TTimeAddr
bra SetKbdWait
CheckF5: cmp.b #BtnF5,d0
bne CheckF6
eor.b #1,TLaserShotsAddr
bra SetKbdWait
CheckF6: cmp.b #BtnF6,d0
bne RestoreD0
move.w #$0001,TimeAddr
Ehhez is kellenek a konstansok, hogy honnan is olvassa a billentyűzet kódját, meg az ellenőrizendő kódok.
KeystrokeAddr equ $00003c1e
BtnF2 equ $51
BtnF3 equ $52
BtnF4 equ $53
BtnF5 equ $54
BtnF6 equ $55
Ezen túl, a kiszálló kódot kell még módosítani, hogy egyrészt a d0
-át vissza is töltse, másrészt meg, hogy kitörölje a beolvasott kódot, nehogy ismétlés legyen.
RestoreD0: move.l (a7)+,d0
AckInterrupt: clr.b KeystrokeAddr
tst.b CIAB+CIAICR
move.w #EXTER,CUSTOM+INTREQ
rte
Itt biztos feltűnt pár embernek, hogy van két db. nem létező címke a kódban, a KeyboardHnd
és a SetKbdWait
. Az oka az, hogy a következő interruptig ugyanaz a kód még egyszer be fog jönni, azaz egy kört meg kell várni.
Ez felel az átugrásért:
KeyboardHnd: cmp.b #0,KeyboardWAddr
beq ReadKeyboard
subq #1,KeyboardWAddr
bra AckInterrupt
Ez pedig az acknowledge, hogy a következőt skippeljük:
SetKbdWait: move.b #$01,KeyboardWAddr
Kell a változó is
KeyboardW dc.b 0
És a címe is:
KeyboardWAddr equ KeyboardW+TORG
És így...
...már működik a ki-be kapcsolgatása a trainernek.
Ha viszont újrakezdjük a játékot (nem reset, csak game over), akkor azt vesszük észre, hogy nem működik többé. Hiába kapcsoljuk be, pl. az örök időt, az állhatatosan csökken. (Life in a nutshell.)
Ha kinyitjuk a debuggert, akkor látjuk, hogy az INTENA
regiszterben $4030
van $6030
helyett. Valami lekapcsolja a külső megszakításokat. (Ami nem meglepő, lévén a játék nem használja.)
Mint kitisztáztuk fentebb, a megszakítások regiszterébe úgy írunk, hogy ami flag-eket beleírunk, azt, ha a legfölső SET/CLR
flag-gel együtt írjuk be, akkor bekapcsoljuk, különben meg ki. Mit jelent ez? Azt, hogy ha $4030
van a regiszterben, azt $c030
-cal kapcsolták be.
s c030
000036DE 00010518 000109B1 0001771B 00019F3F 00022BDA 00022BF2 00030BF1 0003498E 0003E2C4 0003E560 0003E74F 0003E99F 0003F25F 000498C4 000498C6 0004BD20 0005390F 00053FDF 00053FEB 00053FED 0005444B 0005D989 000682B2 0006D989 00072C0A 00072DEA
...vagy hasonló lista; egy része minden keresésnél ugyanaz, egy része meg nem. Néha hosszabb, néha rövidebb... Nézzük az első címet.
dg 36dc
dg 36da
Hát itt valami marhaság van. Valószínűleg adat, vagy szemét. Next.
dg 10516
Meg is van. Írjuk át $e030
-ra:
W 10518 e0
Ezután a már ismertetett módszerrel a timert indítsuk újra.
És most már nem áll meg újrakezdés után.
Kell tehát a kódunk elejére egy patcher, ami figyeli ezt az értéket és ha a helyére került, akkor megpatcheli, majd utána átírja a megszakítás címét, mert patchelni csak egyszer kell.
InterruptCode: cmp.b #ChkPatchIRM,PatchAddr
bne AckInterrupt
move.b #PatchedIRM,PatchAddr
move.l #(HitPowerHack-InterruptCode)+TORG,L6IV
Ehhez persze kellenek az idevágó konstansok is:
L6IV equ $78
PatchAddr equ $10518
ChkPatchIRM equ (SETCLR|INTEN)>>8
PatchedIRM equ (SETCLR|INTEN|EXTER)>>8
SETCLR equ $8000
INTEN equ $4000
Miután kireseteltük a gépet, betöltöttük ismét a játékot, meg a debuggerben a helyére a kódot és elindítottuk a timert, minden működik. És nem áll le az első játékújrakezdésnél.
Itt az idő, hogy az eddig kézzel betöltött kódból önbetöltő trainert faragjunk.
Kezdetnek tegyünk az eddigi interrupt kód legelejére és legvégére egy-egy 32-bitre történő igazítást és a végére egy címkét is. Eleje:
align 2
InterruptCode: cmp.b #ChkPatchIRM,PatchAddr
Vége:
KeyboardW dc.b 0
align 2
InterruptEnd:
Erre azért van szükség, mert így lehet 32-bitenként másolni. Tegyük ezt a kód legelejére:
DoTheCopy: lea InterruptCode,a0
movea.l #TORG,a1
move.l #(InterruptEnd-InterruptCode)>>2,d0
RCopyLoop: move.l (a0)+,(a1)+
dbra d0,RCopyLoop
Most pedig felparaméterezzük a timert, ugyanúgy, mint a debuggerben, csak itt előtte tiltani kell a megszakításokat, utána meg engedni. Debuggerben a fagyott állapot miatt nem volt rá szükség:
move.l #CIAB,a1
move.w #EXTER,INTENA(a2)
move.b #$7f,CIAICR(a1)
move.b #0,CIACRA(a1)
tst.b CIAICR(a1)
move.w #EXTER,INTREQ(a2)
move.l #TORG,L6IV
move.b #CIAICR_SC|CIAICR_TA,CIAICR(a1)
move.b #$00,CIATAL(a1)
move.b #$08,CIATAH(a1)
move.b #1,CIACRA(a1)
move.w #SETCLR|EXTER,INTENA(a2)
Konstansok:
INTENA equ $09A
CIAA equ $BFE001
CIATAL equ $400
CIATAH equ $500
CIASDR equ $C00
CIAICR equ $D00
CIACRA equ $E00
CIAICR_SC equ $80
CIAICR_TA equ $01
Illetve még egy dolog hibádzik: ki is kell szállni a programból, kinullázva a d0
-át, mert különben a DOS közli, hogy elpusztult a program, a visszatérő hibakód meg valami marha nagy "véletlenszám".
moveq #0,d0
rts
És ezután jön az igazítás és az interrupt rutin.
Ezt most le kéne forgatni, de ezt már úgy, hogy programba, nem headless binárisba.:
vasmm68k_mot pat.s -Fhunkexe -kick1hunks -nosym -o pat -L pat.txt
Pakoljuk be az S:startup-sequence
-be a játék elé a programunkat, aztán uccu.
Hát, ez nem működik...
Nézzük meg, hogy a helyén van-e:
dg 00100
A kód a helyén van, de az interrupt le van tiltva.
dg 10516
Hát nem csoda. Nincs megpatchelve. Ez azt jelenti, hogy az interruptunk nem tudott lefutni akkor, amikor az már a helyén volt. Valami menetközben letiltotta, vagy race condition?
Nézzük meg, hogy a cracktro letilt-e valamit:
Nem. Itt még minden oké. Akkor a decruncher? Tudjátok, amikor össze vissza villódzik a kép:
Nocsak. Az interruptok ugyan le vannak tiltva, de globálisan, a mi flag-ünkhöz nem nyúlt. Disassembly és kérjünk egy breakpoint-ot, így látni fogjuk, amikor visszaadja a vezérlést:
dg 100
f 100
A decrunch lezárultával a flagek visszakapcsoltak és él a rutinunk.
Léptessük végig, amíg kiszáll, nézzük hova tér vissza.
A KickStartba. Köszi... Viszont az legalább látszik, hogy a megszakítási vektort ($78
) nem piszkálta el.
Itt, ha hagyjuk futni, akkor egyszer még visszajön, de akkor sem történik semmi, majd végleg kiszáll. Hova lett a patchelendő rész?
s c030
000104F3 00019AA8 0001D63C 00020518 000209B1 0002771B 00029F3F 00032BDA 00032BF2
Ha megnézzük disassemblyvel, az első két címen marhaság van, a harmadiknál meg az opkód része. De mi a helyzet a negyedikkel?
dg 00020516
Aha. Szóval betöltés közben ez még itt van, valószínűleg ide cruncholja ki, majd innen copyzza át a másik helyre. Tehát módosul patchelendő címünk is:
PatchAddr equ $20518
Assemble, reboot, és:
A trainerünk működik.
Akkor tkp. megvagyunk, legalábbis a dolog trainer részével. Hogy az örök klasszikussal éljek: "kb. így fest a dolog gatyában". Most jön az az "esztétikai" része, a menü. (Igazából, tekintve, hogy a funkciógombokkal a játékon belül is kapcsolgathatóak a cuccok, így ez tényleg csak azért van, hogy "traineresebb" legyen...)
Aki a múltkor nehezményezte, hogy assemblyben való hw-banging helyett C-s rendszerbarát programozás volt, az most örülhet, mert az előbbi következik. Ami egyébként - nem győzöm hangsúlyozni: - továbbra is kerülendő; itt is azért "engedhető meg", mert a trainer lefutása után a játék úgyis lezúzza az OS-t, akkor meg mindegy.
Mielőtt bármit csinálnánk, a programba ágyazott copperlistánkat át kell másolni valahova a Chip RAM-ba.
lea Copper(pc),a0
movea.l #CopperAddr,a1
move.w #CopperLength>>2,d0
CopyCopper: move.l (a0)+,(a1)+
dbra d0,CopyCopper
És akkor már egy screen clear is:
movea.l #FirstPlane,a0
move.w #(PlaneLength<<1)>>2,d0
moveq #0,d1
ScreenClr: move.l d1,(a0)+
dbra d0,ScreenClr
A copperlistát azért nem közvetlenül a programból címeztük be, mert ha van Fast RAM és a program oda töltődik be, akkor nem fog működni, mert a custom chipek - nomen est omen - csak a Chip RAM-ot látják, azaz a copperlistát se fogják.
A copperlista és a síkok cuccainak konstansai:
PlaneLength equ ((WIDTH*HEIGHT)/8)
CopperLength equ (CopperEnd-Copper)
SecondPlane equ ($7e800-PlaneLength)
FirstPlane equ (SecondPlane-PlaneLength)
CopperAddr equ (FirstPlane-CopperLength)
$7e800
-ig fogjuk használni a memóriát, mert az utolsó 6 kB a system supervisor stack.
Aztán, nyissuk meg a graphics.library
-t és rángassuk ki belőle a mostani copperlista címét, mert kiszálláskor kelleni fog.
lea CUSTOM,a2
move.l $4,a6
lea graphics_lib(pc),a1
jsr OldOpenLibrary(a6)
move.l d0,a1
move.l 38(a1),CopperBackup
jsr CloseLibrary(a6)
Ehhez kell a library nevének stringje és a backup változó (note the alignment!)
graphics_lib: dc.b "graphics.library",0
align 2
CopperBackup: dc.l 0
valamint a library nyitó és záró offsetek.
OldOpenLibrary equ -408
CloseLibrary equ -414
Ha ezzel megvagyunk, akkor tiltsuk le a multitaskot, majd írjuk felül a copperlistát.
jsr Forbid(a6)
move.l #CopperAddr,COP1LCH(a2)
Idevágó két konstans:
COP1LCH equ $080
Forbid equ -132
Eztán jön a DMA flagjeinek backupolása, majd beállítása a DMACON
és DMACONR
regisztereken keresztül.
move.w #SETCLR,d3
or.w DMACONR(a2),d3
move.w d3,DMABackup
move.w #$7fff,DMACON(a2)
move.w #SETCLR|DMA_ENABLED,DMACON(a2)
A backup változót szúrjuk be a másik mögé
DMABackup: dc.w 0
Konstansok:
DMACONR equ $002
DMACON equ $096
DMAEN equ $0200
BPLEN equ $0100
COPEN equ $0080
DMA_ENABLED equ DMAEN|BPLEN|COPEN
És akkor a copperlista (note the alignment!):
align 2
Copper: dc.w BPL1PTH,(FirstPlane>>16)
dc.w BPL1PTL,(FirstPlane&$ffff)
dc.w BPL2PTH,(SecondPlane>>16)
dc.w BPL2PTL,(SecondPlane&$ffff)
dc.w BPL1MOD,$0000
dc.w BPL2MOD,$0000
dc.w BPLCON0,(BPUx*2)|COLOR
dc.w BPLCON1,$0000
dc.w BPLCON2,$0000
dc.w DIWSTRT,X|(Y<<8)
dc.w DIWSTOP,((X+WIDTH)-256)|(((Y+HEIGHT)-256)<<8)
dc.w DDFSTRT,(X/2-RES)
dc.w DDFSTOP,(X/2-RES)+(8*((WIDTH/16)-1))
dc.w COLOR00,$0000
dc.w COLOR01,$00f0
dc.w COLOR02,$0080
dc.w COLOR03,$0fff
dc.w $ffff,$fffe
CopperEnd:
és konstansai:
WIDTH equ 320
HEIGHT equ 256
X equ 129
Y equ 44
RES equ 8 ;8 = lores, 4 = hires, 2 = super-hires
Kis magyarázat: a BPLxPTx
regiszterekbe kerülnek a bitsíkok kezdőcímei, a BPLxMOD
regiszterekbe a sorok modulói (hogy hány byte kell a sor végén, hogy a következő sor kezdőcímét megkapjuk), ami nulla, mert sorfolytonos. A BPLCON0
regiszterben állítjuk be, hogy 2-bites (4-színű) színes képet kérünk (COLOR
flag), noha emulátorból ez pont mindegy, de RGB használata esetén is, sőt, pont A500/A2000 gépeken, amikre a játék készült szintén mindegy, mert ott a kompozit is szürke lesz. Mindegy, kapcsoljuk be. :P A másik két BPLCONx
a prioritásokat szabályozza; itt érdektelen, nulla.
A DIWSTRT
és DIWSTOP
határozzák meg, hogy hány pixelt jelenítsen meg a képernyőn és hol. Az alsó nyolc bit a vízszintes koordináta, a felső a függőleges. Viszont a stop regiszterben a koordinátákból ki van vonva 256 pixel. Tehát a vízszintes felbontás az ($c1-$81)+256=320
, a függőleges meg ($2c-$2c)+256=256
. (Thx, Angry Retired Bastard.)
A DDFSTRT
és DDFSTOP
állítják be, hogy az elektronsugár melyik vízszintes pozíciójától kezdje olvasni az adatokat és meddig. A $38
(56) és $D0
(208) a PAL szabvány, 208-56=152 bit, per 8, az 19, plusz egy fetch az 16-bit 20x olvasva, az 320 pixel. (Thx, ross.)
A COLORXX
regiszterek meg nem szorulnak magyarázatra. (De a múltkor amúgy is ki lettek vesézve az Amiga színregiszterei.) A végén pedig a copperlista lezárója.
Idevágó regisztercím és flag konstansok:
BPL1PTH equ $0E0
BPL1PTL equ $0E2
BPL2PTH equ $0E4
BPL2PTL equ $0E6
BPLCON0 equ $100
BPLCON1 equ $102
BPLCON2 equ $104
BPL1MOD equ $108
BPL2MOD equ $10A
DIWSTRT equ $08E
DIWSTOP equ $090
DDFSTRT equ $092
DDFSTOP equ $094
COLOR00 equ $180
COLOR01 equ $182
COLOR02 equ $184
COLOR03 equ $186
COLOR equ $0200
BPUx equ $1000
Mi kell még? A billentyűzet és az egér. Billentyűzet:
lea CIAA+CIASDR,a1
clr.b (a1)
ReadKbd: move.b (a1),d0
ror.b #1,d0
not.b d0
bmi.b CheckMouse
clr.b (a1)
Ez ugyanúgy beolvassa a kódot a soros regiszterből, mint a játékban és ugyanúgy kell lekezelni és a változókat írni (kivéve az egy körös skip-et), ld. fentebb, nem copyzom be még egyszer.
Ha a billentyűzet lekezelése megvan, jöhet az egér, ami az A portot olvasgatja, aminek a hatodik bitje a left button. Ha lenyomódik, kiszáll.
CheckMouse: btst #6,-CIASDR(a1)
bne.b ReadKbd
Ez után jöhet az interrupt kódját copyzó rutin (DoTheCopy
), majd a timer felprogramozása, aztán végül, kiszállás előtt lehet visszaállítani a képernyőt és visszakapcsolni a multitaszkot. Ezt a legvégére kell írni, közvetlenül a d0
nullázása és az rts
előtt.
Exit: move.w #$7fff,DMACON(a2)
move.l CopperBackup,COP1LCH(a2)
move.w DMABackup,DMACON(a2)
jsr Permit(a6)
A Permit
címe:
Permit equ -138
Van még valami? Semmi, azon túl, hogy írkálunk a képernyőre. Ehhez kell egy fontset, amit a programba ágyazunk és vagy Blitterrel, vagy CPU-val a képernyőre hányunk betűnként (én ez utóbbit tettem). Írogathatunk üzeneteket, valamint, amikor a gombok hatására valamelyik flag bebillen, akkor lehet jelezni a változást (pl. On/Off, vagy ilyesmi).
Ezt vagy tíz éve rajzoltam, de sose használtam fel, mostanáig. Ebből még annyit, hogy csak 32-127-ig használtam a karaktereket, mert másra nem volt szükség. Mivel a múltkor már tisztáztuk, hogy hogy működik az Amiga videómemóriája és a képsíkok és nem a Blitterrel rajzoltam, hogy bármi új lenne benne, erre most nem pazarolnám már a helyet.
Még itt egy képernyőkép a már futó trainerről.
És nagyjából ennyi.
A trainer letölthető innen, a játékot inkább nem linkelem be, mert nem tudom, mennyire érzékeny trey az abandonware-re, de fent van az is a honlapon. (Use the searchbox, Luke.)
Köszöntem a figyelmet, remélem, aránylag kevés agykárosodással túléltétek.
- TCH blogja
- A hozzászóláshoz be kell jelentkezni
Hozzászólások
Ez nagyon élvezetes és tanulságos volt.
"Maradt még 2 kB-om. Teszek bele egy TCP-IP stacket és egy bootlogót. "
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
Amigára talán még nincs Pegazus, lehet azt kéne használni :) Kár hogy a 90-es évek elején eladtam :(
- A hozzászóláshoz be kell jelentkezni
SWp0rn! Még többet!
Sajnos az Amigával már csak kesőn találkoztam, mire a PC-k letarolták a világot. De szeretnék komolyabban megismerkedni vele. Szerencsére sikerült egy jó állapotban lévő 500+ gépet beszereznem a többi Commodore masinám mellé.
- A hozzászóláshoz be kell jelentkezni
lajk!
- A hozzászóláshoz be kell jelentkezni
nem tudom tudsz-e rola de nem latszanak a kepek, legyszi fixald!
- A hozzászóláshoz be kell jelentkezni
^^ a tokeletes szakmai hozzallas ^^
- A hozzászóláshoz be kell jelentkezni
Mindjárt a harmadik sorban be volt linkelve a komplett válasz a nem látszó képekre, de ha egyszer analfabéta vagy, azon sajnos semmilyen szakmai hozzáállás nem segít.
- A hozzászóláshoz be kell jelentkezni
a belinkelt oldalbol is messzemeno szakmai hozzaertest tudtam levonni, ne izgulj.
- A hozzászóláshoz be kell jelentkezni
Szakmai hozzáértés híján? Hogyan? Ha egy pirinyó szakmai hozzáértésed is lenne, már bekapcsoltad volna a mixed-contentet, vagy felraktál volna egy HTTPS-everywhere-t és problem solved. De te ehelyett inkább picsogsz, hogy nem látod a képeket, ami nem meglepő, mert tőled ennyi tellik. Valahányszor szakmai vitába keverednénk, te picsagyorsan kihátrálsz, hogy neked nem igazából a szakmai résszel volt bajod, abban egyetértesz velem, stb. Szerintem ne erőlködj.
BTW, ezt már rég meg akartam kérdezni: ha neked a nicked a nevedből van, akkor miért nem NagyArZ a nicked? Jobban passzolna.
- A hozzászóláshoz be kell jelentkezni
megint tul sokat irtal, a naplodba akartad irni ezeket, nem?
- A hozzászóláshoz be kell jelentkezni
Ennyi? Megint elfogytál. Loser.
- A hozzászóláshoz be kell jelentkezni
en fogytam el, igen, csak ez lehet. mr. https-az-ordogtol-valo istenseg, aki egy rendes https kepet nem kepes berakni. kezet razhattok pixelverzum haveroddal.
- A hozzászóláshoz be kell jelentkezni
Igen, elfogytál, mert semmi érdemi választ nem tudtál adni sem arra, hogy
a) miért nem kapcsolod be a mixed-contentet,
vagy
b) miért nem teszel fel egy HTTPS-everywhere-t,
ha te szakmailag akkora überszakértő vagy, ill. arra sem, hogy
a) miért nem illúzió a HTTPS által adott biztonság
és
b) miért nem vezet a netsemlegesség kinyírásához.
Ehelyett maradt ez a már hatvannyolcezerszer megcáfolt hazugsághalom, holott, ha eddig nem írtam le nem csak a belinkelt FAQ-ban, de hupos válaszkommentekben is hatvannyolcezerszer, hogy ha lenne hozzáférésem, már rég megcsináltam volna, hogy a biccsegés abbamaradjon, akkor egyszer sem.
Tehát te vagy egy retardált write-only analfabéta vagy, aki picsog, mert nem képes egy ilyen piszlicsáré problémát sem megoldani (erre mondtam, hogy: chluser 222 NagyArZ
), vagy egy figyelemkurwa troll, aki hazudozik.
- A hozzászóláshoz be kell jelentkezni
Ne pazarold rá a bötűt! Helyette inkább publikálj még pár ilyen cikket! ;)
- A hozzászóláshoz be kell jelentkezni
Köszi! Még amigás korszakom előtt c64-en csináltam hasonlókat kölyökként. Mivel nem volt emulátor, se action replay (még soha nem is hallottam ilyenekről), ezért a peccselendő játéknál a TV képcsövén jelöltem meg azt a karaktert vagy karaktereket filctollal, ahol pl. az életek száma volt, majd ez alapján már tudtam offszetcímet számolni, amely alapján már meg tudtam keresni a játék kódjában a releváns gépi kódú utasításokat, ami már elvezetett a peccselendő kódrészlethez. Ha minden összeállt, akkor készítettem el a játék "elé" a cracktro-t. Persze, ez a megoldás ingame nem műkdött. :) Aztán kijöttek olyan játékok, amelyekről már körülményesebb volt eltávolítani a decruncereket (risk rémlik), lévén a tömörítésen kívül védelmi funkciót is kezdtek ellátni, viszont a pure játék kódjának elemzéséhez szükség volt a kicsomagolásukra. Írtam egy crunchert is a cél érdekében, plusz egy olyan disassembler/debuggert, amely kvázi emulátor volt, mert az éppen végrehajtott gépi kódú utasítást kiemeltem a környezetéből és a debuggerem saját "testében" hajtottam végre egy malom nevezetű területen. Ezért lassú volt, de akkor újszerű és védelmek ellen kiváló. Ésígytovább...
- A hozzászóláshoz be kell jelentkezni
Köszi!
- A hozzászóláshoz be kell jelentkezni
Érdekes megoldás! :) Felmerült bennem pár kérdés:
Ez a trükk mennyire általános, hogy a változókat IT-ből időnként visszaállítják? (Számomra ez ilyen igazi "dirty hack" fíling. ;) ) Logikusabbnak hangzana az, hogy a változókat módosító kódot keresem meg / peccselem, hogy ne csinálják a dolgukat. Illetve ez a 2048 ciklusonként futtatott IT nem sűrű egy kissé? Nem lenne elég ennek mondjuk frémenként csak 1× futnia?
Aztán ami még érdekelne, hogy anno ezeket hogy csinálták? Amikor még nem volt kéznél egy emulátor, ahol szabadon garázdálkodok a gép belsejében, hanem volt az egy szem A500-am, azzal kellett / lehetett megoldani mindent. Én ugyan nem találkoztam vele, de mintha A500-hoz létezett volna ilyen "Action-Replay" szerű hardverbővítés, meg az újabb AMIGÁkban ha van a CPU-ban MMU, ott már szoftverből is lehet csinálni ezt-azt. De ha ezek nincsenek, csak egy sima alapgépem, hogyan álljak neki..? :) (A kérdés nyilván teoretikus; a mai eszközök mellett a régi megoldással minek is álla neki az ember...)
- A hozzászóláshoz be kell jelentkezni
Ez a trükk mennyire általános, hogy a változókat IT-ből időnként visszaállítják?
Azt nem tudom. Amigán egy raklap módon lehet ezt csinálni, mindenki válogathat.
Számomra ez ilyen igazi "dirty hack" fíling. ;)
Ez annak is készült. :) A legegyszerűbb megközelítést választottam.
Logikusabbnak hangzana az, hogy a változókat módosító kódot keresem meg / peccselem, hogy ne csinálják a dolgukat.
Azt is lehet, csak akkor az sokkal több reverse engineering-gel és átalakítással jár, feltéve, ha egy hasonló szintű trainert akar az ember kihozni belőle; nyilván, ha csak annyit akarok, hogy ne fogyjon az életerő/idő/lövés, azt egy-egy sub.w xxx,yyy
átírásával el lehet érni.
Illetve ez a 2048 ciklusonként futtatott IT nem sűrű egy kissé? Nem lenne elég ennek mondjuk frémenként csak 1× futnia?
A változók átírásához simán elég lenne, de a billentyűzetfigyelés kisebb mintavételezéssel "lagzani" fog és nem reagál azonnal; sokat próbálgattam, hogy mennyi lenne a célszerű. Többek közt ezért is járna sokkal több átalakítással a kódátírós dolog, hiszen meg kéne patchelni a billentyűzetfigyelő kódot úgy, hogy több kódot kéne belenyomni ugyanakkora adatterületbe, hiszen itt minden fix címen van, nem tologathatom el a végével a következő rutin elejét. Vagy kirakhatom az új rutint oda, ahol van elég hely és odaugraszthatom a régi billentyűzetfigyelő kód legelejéről, de ehhez szabad hely kell, ami nem mindig van, ez a játék is majdnem csurig írta a memóriát.
Aztán ami még érdekelne, hogy anno ezeket hogy csinálták? Amikor még nem volt kéznél egy emulátor, ahol szabadon garázdálkodok a gép belsejében, hanem volt az egy szem A500-am, azzal kellett / lehetett megoldani mindent. Én ugyan nem találkoztam vele, de mintha A500-hoz létezett volna ilyen "Action-Replay" szerű hardverbővítés, meg az újabb AMIGÁkban ha van a CPU-ban MMU, ott már szoftverből is lehet csinálni ezt-azt.
Igen, volt Action Replay, de ez csak egy volt a sok közül. Amigán a 7. szintű - nem maszkolható - megszakítást úgy lehetett kiváltani, ha alacsonyra húztad mindhárom IPL lábát a CPU-nak. Ekkor minden más megállt, lévén ez a legmagasabb szintű interrupt, őt nem szakíthatja meg semmi. Ilyenkor a rendszer kvázi "megfagy", csak az a kód működik, amire a $7c
címen található vektor ugrasztotta a processzort. Ha az a kód azzal nyit, hogy mindent is lement valahova (movem.l d0-d7/a0-a7,$add4e55
), meg kibányássza a veremből a pc
és az sr
megszakítás előtti értékét, akkor tkp. máris van egy monitorunk. Lehet a dolgot olyan fancy módon is csinálni, mint az AR és a hasonló freezerek, hogy ráül a buszra és egy raklap dolgot csinál, de igazából egy az IPL lábakat és a földet összekötő kapcsoló is elég, meg egy szoftveres monitor, mint pl. a WinUAE-be is beépített HRTmon.
De ha ezek nincsenek, csak egy sima alapgépem, hogyan álljak neki..? :) (A kérdés nyilván teoretikus; a mai eszközök mellett a régi megoldással minek is álla neki az ember...)
Hát így. :) Alacsonyra húzod a CPU IPL lábait és használsz egy szoftveres monitort.
Vagy, van a másik módszer: disassemblálod a bootblockot, megnézed mit, hogyan és hova tölt be, kigrabbeled azokat a részeket a lemezről, végrehajtod rajta azokat a műveleteket (pl. decrunch), amiket kell, majd utána azt is disassemblálod és így tovább. Csináltam ilyet is pár éve, igaz az nem trainer volt, hanem HD verzió egy játékból, mert trackloaderes volt és nem települt HD-re. Értelemszerűen, ha a cucc nem trackloaderes, akkor nem a bootblockot kell disassemblálni, hanem a programot. :)
- A hozzászóláshoz be kell jelentkezni
Köszi a magyarázást! :) (Gondoltam, hogy a jegyzőkönyv kedvéért leírom, hogy a 68000-nak nincs dedikált NMI lába, de valahogy átíródott azóta a poszt. :-D )
A "bootblock disass" és a többiek tényleg a logikus sorrend, csak én nem találkoztam ilyen szoftverekkel. (Az AMIGA programozása sajnos kimaradt eddig az életemből.) A kérdés (ki nem mondott része) inkább erre irányult volna, hogy mik voltak azok a programok, amikkel ilyent az átlag kréker elkövethetett?
(Szerk: válasz akart lenni, nem új hozzászólás.)
- A hozzászóláshoz be kell jelentkezni
Nincs mit. (Még az első 10 percben, miután leesett, hogy ez nem C64 és három darab multiplexelt IRQ láb van; 0.75 kecske voltam aznap, na. :P )
Szerintem a cracker bácsik ritkábban foglalkoztak a bootblock közvetlen disassembly-ével és inkább az NMI/monitor kombóval tolták (már csak azért is, mert a jobb monitorokban is volt disassembler), de ha régi disassemblert keresel, akkor AFAIK a ReSource volt a koronázatlan király, az amúgy elég népes tömegben (AmiNet-en továbbiakat is lehet találni). A lemezek egyes blokkjait pedig pl. a TransDisk nevű programmal lehetett írni/olvasni, vagy egy disk monitorral, pl. a DiskMon-nal.
De ma tényleg nem sok értelme van így csinálni, amikor ott a WinUAE debuggere, meg az IDA disassembler (igen, perfekt viszi az Amigás futtathatókat és a raw dump-ot is).
- A hozzászóláshoz be kell jelentkezni