ARTICLES
![]() | ![]() | 26 / 31 | ![]() | ![]() |
Amsoft Disc Protection System by EXOPAL Software Services : SPITFIRE 40
CRACK de SPITFIRE (MIRRORSOFT – 1985) par ALEX/FDLC
La Disquette est formatée en DATA des pistes 0 à 2 et 28 à 39 ET les pistes 3 à 27 sont formatées en 9 secteurs &D8 à &E0 (25 pistes). Aucune donnée à partir de la piste 19 !
Il s'agit de l'Amsoft disc protection system by EXOPAL Software Services version 3 (piste 3, secteur &D8). Les trois fichiers du jeu sont cachés dans les pistes 5 à 18 mais le loader est lisible à la piste 4 (voir image ci-dessous). Piste 3, secteur &D8, nom du fichier-loader caché : spitfire2.bin mais pas de données.
L'analyse du loader nous montre qu'il y a trois fichiers chargés mais nous allons traiter la disquette originale comme une version sectorielle !
La faiblesse de cette protection est d'aligner les données non cryptées secteur après secteur, piste après piste avec des secteurs vides pour marquer la fin d'un fichier. Ainsi, l'image est stockée sur les pistes 5,6,7 et 8 (5 secteurs seulement) = 32 secteurs puis on passe au fichier data1 stocké des pistes 9 à 13 et prog1 stocké des pistes 14 à 17 (4 secteurs seulement).
1) Ecrire une routine qui charge l'image de présentation en &C000-&FFFF, soit &400 octets à partir de la piste 5 sur une longueur de 32 secteurs (soit 17Ko) de l'original placé dans le drive 1 et on sauvegarde le fichier sur le drive 0. Voir routine Spit1.asm
Avec la protection sur l'original, le fichier s'appelle PICKY
2) Ecrire une routine qui charge en &1200, &55FF octets à partir de la piste 9 sur une longueur de 45 secteurs (soit 22Ko=> &1200-&67FF) de l'original placé dans le drive 1 et on sauvegarde le fichier sur le drive 0. Voir routine Spit2.asm
Avec la protection sur l'original, le fichier s'appelle DATA1
Problème : comment déterminer la quantité de données à lire, ici &55FF octets ? Avec un peu de logique et de chance ! En effet, le 3e chargement de l'original (&C000-1FCFF) est suivi d'un transfert de ces données de &6800-&A4FF. On peut donc en déduire que cette routine charge &55FF octets à partir de &1200 jusqu'à &67FF ainsi le programme complet occupe la zone &1200-&A4FF.
3) Ecrire une routine qui charge en &4000, &3D00 octets à partir de la piste 14 sur une longueur de 31 secteurs (soit 16Ko=> &4000-&7CFF) de l'original placé dans le drive 1 et on sauvegarde le fichier sur le drive 0. Voir routine Spit3.asm
Avec la protection sur l'original, le fichier s'appelle PROG1
4) Ecrire un loader qui met le mode 0, les couleurs et le border qui conviennent, qui charge les 3 fichiers et qui transfère la zone &4000-&7CFF en &6800-&A4FF. En fait, on charge le 3e fichier en zone &C000-FCFF puis on transfère les données vers &6800. Voir loader.asm
1 : mode 0
2 : border 1
3 : boucle pour initialiser les 16 couleurs du mode 0
4 : chargement de l'image (PICKY)
5 : chargement du fichier DATA1
6 : chargement du fichier PROG1
7 : transfert des données de PROG vers la zone &6800
decodeur.asm
;; programme de decryptage des quatre sections codees du loader disc2.bin
;; 1) prendre une copie de la D7 originale
;; 2) enlever la protection en lecture et en écriture du fichier DISC2.BIN
;; 3) taper MEMORY &9FFF:LOAD"DISC2.BIN"
;; 4) taper ERA,"DISC2.BIN
;; 5) charger la routine decodeur.asm sous Winape
;; 6) l'assembler sous WINAPE Assembler
;; 7) CALL &8000
;; 8) SAVE"DISC2.BIN",B,&A000,&648
;; 9) RUN"DISC" => le jeu démarre avec un loader décrypté
org &8000
;; decryptage
.debut
ld de,liste
.start
ld hl,&a018
ld a,(&a000)
.decode
xor (hl)
ld (hl),a
inc l
jp nz,decode
ld hl,&a004
.plus
inc (hl)
jp z,fin
ld hl,start+4 ; on modifie aussi notre code pour reussir le decryptage !
inc(hl)
ld hl,&a004
ld a,(hl)
cp #18
jp z,plus
jp start
;; efface la routine de decodage interne a chacune des quatre sections
.fin
ld hl,&a000
.cls
ld(hl),0
inc l
ld a,l
cp #18
jr nz,cls
;; apres la 1e partie en &A000, 2e partie en &A400, 3e partie en &A200 et 4e partie en &A300
ld hl,start+4
ld a,0
ld (hl),a
ld a,(de)
cp #FF
jp z,fini
ld hl,start+&02 ; automodification de notre prgramme
ld (hl),a
ld hl,start+&05 ; automodification de notre prgramme
ld (hl),a
ld hl,start+&0E ; automodification de notre prgramme
ld (hl),a
ld hl,start+&19 ; automodification de notre prgramme
ld (hl),a
ld hl,start+&25 ; automodification de notre prgramme
ld (hl),a
inc e
jp start
;; retour au BASIC ==> SAVE"disc2.bin",b,&A000,&648
.fini
ret
liste:
defb &A4,&A2,&A3,&FF
.fliste
spit_loader.asm
;; ROUTINE chargement jeu Spitfire 40
org &800
ld c,7
ld de,&70
ld hl,&B0FF
call &BCCE
ld a,0
call &BC0E;; mode 0
ld bc,&0000
call &bc38 ;; border 0
ld b,01
ld c,b
call &BC38 ;; border 1
ld hl,couleurs ;; mise en place des 16 couleurs du mode 0
ld a,0
.plus
push af
push hl
ld b,(hl)
ld c,(hl)
call &BC32
pop hl
inc hl
pop af
inc a
cp 17
jr nz,plus
ld b,fin-nom ; taille nom fichier
ld hl,nom ; adresse nom fichier
ld de,&C000 ; 2k buffer
call &BC77 ; cas_in_open = ouvrir en lecture
ld hl,&C000 ; adr CHARGEMENT
call &BC83 ; cas_in_direct = lire
call &BC7a ; cas_in_close = fermer
ld b,fin1-nom1 ; taille nom fichier
ld hl,nom1 ; adresse nom fichier
ld de,&C000 ; 2k buffer
call &BC77 ; cas_in_open = ouvrir en lecture
ld hl,&1200 ; adr CHARGEMENT
call &BC83 ; cas_in_direct = lire
call &BC7a ; cas_in_close = fermer
ld b,0
ld c,b
call &BC38 ;; border 0
ld a,0
.cls
push af
ld bc,&0000
call &BC32
pop af
inc a
cp 16
jr nz,cls ;; on met tout en noir
ld b,fin2-nom2 ; taille nom fichier
ld hl,nom2 ; adresse nom fichier
ld de,&C000 ; 2k buffer
call &BC77 ; cas_in_open = ouvrir en lecture
ld hl,&C000 ; adr CHARGEMENT
call &BC83 ; cas_in_direct = lire
call &BC7A ; cas_in_close = fermer
di
ld hl,&C000
ld de,&6800
ld bc,&3D00
ldir ;; transfert des données vers la zone &6800-&A4FF
jp &6800 ;; lancement du jeu !
ret
;; filename = maximum of 12 char, 8 for name, "." & 3 for extension
.nom
defb "SPIT.SCR"
.fin
.nom1
defb "DATA.BIN"
.fin1
.nom2
defb "PROG.BIN"
.fin2
.couleurs
defb &00,&06,&06,&1A,&0D,&14,&01,&02,&0E,&1A,&0C,&09,&12,&13,&03,&0A
SPIT1.asm
;; copie du jeu de la version secteurs a la version fichiers
;; drive A (0)= D7 destination
;; drive B (1)= D7 originale !
;; chargement de l'image, fichier PICKY
;; 32 secteurs (soit &4000 octets) à partir de la piste 5 chargés en &C000-&FFFF
org &8000
ld hl,cmd_bios_read_sector
call &bcd4 ; firmware function to find a RSX
ret nc
;; command found
ld (bios_read_sector),hl ;; store address of command
ld a,c
ld (bios_read_sector+2),a
;; store "rom select" of command
;;------------------------------------------------------------------
;; read 512 bytes of data from track D, sector C from disc drive e
ld hl,&C000 ;; HL = address of buffer
ld e,&01 ;; E = drive number (0 or 1)
ld d,&05 ;; D = track number
ld c,&D8 ;; C = sector id
ld b,&20 ;; number of sectors
.charge
push de
;; execute command
rst 3
defw bios_read_sector
ld de,&200
add hl,de
pop de
inc c
ld a,c
cp &E1
jr nz, net
ld c,&D8
inc d
.net
djnz charge
call &bb18
ld b,fin-nom ; taille nom fichier
ld hl,nom ; adresse nom fichier
ld de,&C000 ; 2k buffer
call &BC8C ; cas_in_open = ouvrir en ecriture
ld hl,&C000 ; adr CHARGEMENT
ld de,&4000 ; taille en octets *512 (&200 octets), &20*&200 = &4000
ld bc,&0000 ; adr execution
ld a,2 ; file type 2 = binaire
call &BC98 ; cas_in_direct = ecrire
call &BC8F ; cas_in_close = fermer
ret
;; filename = maximum of 12 char, 8 for name, "." & 3 for extension
.nom
defb "SPIT.SCR"
.fin
;;------------------------------------------------------------------
;; this is initialised when the "BIOS: READ SECTOR" RSX has been found.
.bios_read_sector
defw 0 ;; address of function
defb 0 ;; "rom select" for function
.cmd_bios_read_sector
defb 4+&80 ;; this is the "BIOS: READ SECTOR" RSX
SPIT2.asm
;; copie du jeu de la version secteurs a la version fichiers
;; drive A (0)= D7 destination
;; drive B (1)= D7 originale !
;; chargement du contenu du fichier DATA1
;; chargement à partir de la piste 9 de 45 secteurs (soit &55FF octets) dans la zone &1200-&67FF
org &8000
ld hl,cmd_bios_read_sector
call &bcd4 ; firmware function to find a RSX
ret nc
;; command found
ld (bios_read_sector),hl ;; store address of command
ld a,c
ld (bios_read_sector+2),a
;; store "rom select" of command
;;------------------------------------------------------------------
;; read 512 bytes of data from track D, sector C from disc drive e
ld hl,&1200 ;; HL = address of buffer
ld e,&01 ;; E = drive number (0 or 1)
ld d,&09 ;; D = track number
ld c,&D8 ;; C = sector id
ld b,045 ;; number of sectors
.charge
push de
;; execute command
rst 3
defw bios_read_sector
ld de,&200
add hl,de
pop de
inc c
ld a,c
cp &E1
jr nz, net
ld c,&D8
inc d
.net
djnz charge
call &bb18
ld b,fin-nom ; taille nom fichier
ld hl,nom ; adresse nom fichier
ld de,&C000 ; 2k buffer
call &BC8C ; cas_in_open = ouvrir en ecriture
ld hl,&1200 ; adr CHARGEMENT
ld de,&55FF ; taille en octets *512
ld bc,&0000 ; adr execution
ld a,2 ; file type 2 = binaire
call &BC98 ; cas_in_direct = ecrire
call &BC8F ; cas_in_close = fermer
ret
;; filename = maximum of 12 char, 8 for name, "." & 3 for extension
.nom
defb "DATA.BIN"
.fin
;;------------------------------------------------------------------
;; this is initialised when the "BIOS: READ SECTOR" RSX has been found.
.bios_read_sector
defw 0 ;; address of function
defb 0 ;; "rom select" for function
.cmd_bios_read_sector
defb 4+&80 ;; this is the "BIOS: READ SECTOR" RSX
SPIT3.asm
;; copie du jeu de la version secteurs a la version fichiers
;; drive A (0)= D7 destination
;; drive B (1)= D7 originale !
;; chargement du contenu du fichier PROG
;; chargement à partir de la piste 14 de 31 secteurs (soit &3D00 octets) dans la zone &4000-&7D00
;; ce contenu est ensuite à transférer dans la zone &6800-&A4FF (voir loader)
org &8000
ld hl,cmd_bios_read_sector
call &bcd4 ; firmware function to find a RSX
ret nc
;; command found
ld (bios_read_sector),hl ;; store address of command
ld a,c
ld (bios_read_sector+2),a
;; store "rom select" of command
;;------------------------------------------------------------------
;; read 512 bytes of data from track D, sector C from disc drive e
ld hl,&4000 ;; HL = address of buffer
ld e,&01 ;; E = drive number (0 or 1)
ld d,14 ;; D = track number
ld c,&D8 ;; C = sector id
ld b,31 ;; number of sectors
.charge
push de
;; execute command
rst 3
defw bios_read_sector
ld de,&200
add hl,de
pop de
inc c
ld a,c
cp &E1
jr nz, net
ld c,&D8
inc d
.net
djnz charge
call &BB18
ld b,fin-nom ; taille nom fichier
ld hl,nom ; adresse nom fichier
ld de,&C000 ; 2k buffer
call &BC8C ; cas_in_open = ouvrir en ecriture
ld hl,&4000 ; adr CHARGEMENT
ld de,&3D00 ; taille en octets *512
ld bc,&0000 ; adr execution
ld a,2 ; file type 2 = binaire
call &BC98 ; cas_in_direct = ecrire
call &BC8F ; cas_in_close = fermer
ret
;; filename = maximum of 12 char, 8 for name, "." & 3 for extension
.nom
defb "PROG.BIN"
.fin
;;------------------------------------------------------------------
;; this is initialised when the "BIOS: READ SECTOR" RSX has been found.
.bios_read_sector
defw 0 ;; address of function
defb 0 ;; "rom select" for function
.cmd_bios_read_sector
defb 4+&80 ;; this is the "BIOS: READ SECTOR" RSX
Article rédigé par : Alexandre OLLIER
Article créé le : | Lundi 23 Janvier 2023 à 21 h 36 |
Dernière mise à jour le : | Lundi 23 Janvier 2023 à 21 h 55 |