CPC-POWER : CPC-SOFTS - CPCArchives 
Options de Recherche :
 
 
 

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
 
 

CPC-POWER/CPCArchives, projet maintenu par Fredouille.
Programmation par Kukulcan © 2007-2024 tous droits réservés.
Reproduction sans autorisation interdite. Tous les titres utilisées appartiennent à leurs propriétaires respectifs.