Avevo gia' fatto una sorta di articolo per quanto riguarda l'espansione
dei programmi compressi, in risposta ad una
domanda analoga a questa,
ma proviamo a rispiegarci con questo nuovo esempio.
Innanzitutto bisogna SEMPRE evitare che il programma parta, che sia un intro
o un gioco o altro, non e' detto che sia possibile farlo ripartire una seconda
volta. Inoltre ritrovare l'indirizzo iniziale e' sicuramente difficile, occorre
studiarsi il disassemblato completo della memoria dumpata su file.
Quindi e' meglio che questo indirizzo ce lo facciamo dire dal depacker
direttamente. Per far cio' bisogna tracciare il depacker finche' non vediamo
che venga eseguita la JMP che attiva il programma decompresso.
Normalmente i depacker funzionano cosi': copiano il codice di decompressione
in un area bassa in memoria, compresa tra $0001 e $07ff, poi li' avviene tutta
la decompressione del resto dei dati da $0800 in poi, e infine esegue una JMP
al programma decompresso.
Usiamo il monitor di Vice, e settiamo un layout utile, aprendo le finestre
dei registri e del disassembly. Questo ci evita di dover usare i comandi
"d" e "r" continuamente come dovremmo fare con un monitor tradizionale.
(uscire dal monitor e salvare i settaggi dopo aver sistemato il layout)
Carichiamo il gioco ma non lanciamolo, entriamo nel
monitor e diamo:
un e144
"un" sta per until, aspetta finche' non viene eseguito del codice a $e144,
che e' la parte finale della routine del Kernal che esegue il comando basic SYS.
In questo modo ci fermeremo esattamente su
e144 jmp ($0014)
andiamo avanti di uno step con "z" e ci ritroviamo a $080d, (2061) che e' guarda
caso la SYS di partenza.
Qua cosa vediamo dal disasm: che fa alcuni trasferimenti e una:
.C:083A 4C 00 01 JMP $0100
bene, facciamoglielo fare:
un 100
e ci ritroviamo all'interno del depacker. Qua avviene un altro trasferimento
e scorrendo il codice non si nota altro che jsr a routine in memoria "bassa"
andiamo ad esempio a tracciare quella a $0334
un 334
scorrendo un pochino cosa notiamo qua?
.C:0364 A9 37 LDA #$37
.C:0366 85 01 STA $01
.C:0368 58 CLI
.C:0369 4C 00 10 JMP $1000
cioe' "setta di nuovo la configurazione RAM/ROM normale, ripristina l'IRQ e
fai partire il programma ora decompresso con una JMP $1000"
L'operazione e' pressoche' invariata con qualsiasi depacker, cambiano solo
indirizzi del depacker e ovviamente il codice, ma la sostanza e' questa.
Ora che sappiamo l'indirizzo di partenza possiamo anche salvare la memoria:
un 1000
> 1 0
s "allmem" 0 800 ffff
quit
Io uso in questo esempio "un", si potrebbe usare il comando "break" ma serve
per settare break point fissi e fermarsi ogni volta che passa di li', a noi
serve solo arrivarci una volta sola a quell'indirizzo.
Una volta imparato a far tutto cio' manualmente... possiamo evitare tutto cio'
usando il mio UNP64, programma di decompressione generico per PRG C64 :D
L'ho realizzato perche' fare questa operazione ogni tanto non e' molto
faticoso, mentre se si devono elaborare centinaia di programmi ogni giorno
per isolarne l'intro o la musica, diventa davvero noioso.
Una volta estratto il prg dal D64 basta darlo in pasto ad unp64:
C:\temp\>unp64 "SKI JUMP.prg"
Time Cruncher/2061, depacker=$0100
Entry point: $080d
pass1, find depacker: $0100
pass2, return to mem: $1000
saved $0801-$f3ff as SKI JUMP.prg.1000
Caso vuole che il codice di decompressione sia tra quelli riconosciuti, quindi
sa esattamente dove si trova il depacker, l'indirizzo di partenza, e gli estremi
di inizio e fine memoria una volta decompressa.
Nel caso il depacker sia ancora sconosciuto, semplicemente salva tutto da $0800
a $ffff e sta all'utente disassemblarlo per capirne gli estremi.
Ovviamente il programma e' sul mio sito.
Ultima nota: l'intro dei TWA e' gia' presente su intros.c64.org, ha una musica diversa ma in ogni caso entrambe le musiche sono comunque gia' in HVSC