Index du Forum
IDENTIFICATION SERVEUR : 10.0.97.1 - CLIENT : 23.22.50.12

 FAQFAQ   RechercherRechercher   Liste des MembresListe des Membres   Groupes d'utilisateursGroupes d'utilisateurs   S'enregistrerS'enregistrer 
 ProfilProfil   Se connecter pour vérifier ses messages privésSe connecter pour vérifier ses messages privés   ConnexionConnexion 

David's Midnight Magic (Broderbund, 1982)

 
Poster un nouveau sujet   Répondre au sujet     Index du Forum -> PROTECTION MALEFIQUE
Voir le sujet précédent :: Voir le sujet suivant  
Auteur Message
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Ven 06 Jan 2017, 18:17    Sujet du message: David's Midnight Magic (Broderbund, 1982) Répondre en citant

This is an pinball game that is incredibly addictive if you love pinball games. Otherwise you'll hate it because it's also soooo difficult! :-)
I spent more time playing it than deprotecting it, but that's certainly not because of the lack of protection.

We start with a hybrid boot-sector. This disk can be booted on old 5-and-3 drives as well as 6-and-2 ones.

Code:
0801                 LDX     #0
0803                 LDA     $0800,X
0806                 STA     $0200,X
0809                 INX
080A                 BNE     $0803
080C                 JMP     $020F


Copy self out of the way, and then jump to that copy.

Code:
020F                 LDY     #$AB
0211                 TYA
0212                 STA     $3C
0214                 LSR
0215                 ORA     $3C
0217                 CMP     #$FF
0219                 BNE     $0224
021B                 CPY     #$D5
021D                 BEQ     $0224
021F                 TXA
0220                 STA     $800,Y
0223                 INX
0224                 INY
0225                 BNE     $0211


Build 5-and-3 translation table.

Code:
0227                 STY     $3D
0229                 STY     $26
022B                 LDA     #03
022D                 STA     $27


Prepare to load 5-and-3 sector 0 to $0300.

Code:
022F                 LDX     $2B
0231                 JSR     $025D


Load.

Code:
0234                 JSR     $02D1


Decode. The decoder also checks that $300=#$99 (and crashes if not), and returns Y=#$99. This is important.

Code:
0237                 JMP     $0301


Run it.

Code:
0301                 STY     $0200
0304                 LDY     $2B
0306                 LDX     #$00
0308                 LDA     $0300,X
030B                 EOR     $0200
030E                 STA     $00,X
0310                 DEX
0311                 BNE     $0308


Decode onto zpage, using the Y value from previously. If we didn't bother to set it, then it will decode garbage instead.

Code:
0313                 STY     $2B
0315                 TXA
0316                 PHA
0317                 PHA
0318                 LDA     $A2
031A                 EOR     $0200
031D                 PHA


Obfuscated entrypoint decodes to $0069.

Code:
031E                 LDA     $0323
0321                 STA     $FF
0323                 RTS


So let's go there.


Dernière édition par qkumba le Ven 06 Jan 2017, 18:44; édité 2 fois
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Ven 06 Jan 2017, 18:20    Sujet du message: Répondre en citant

Code:
0069                 LDA     $C083
006C                 LDA     $C083
006F                 TXA
0070                 TAY
0071                 TXS
0072                 STA     $0300,X
0075                 DEX
0076                 BNE     $72
0078                 STA     $FFFC
007B                 LDA     $2B
007D                 LSR
007E                 LSR
007F                 LSR
0080                 LSR
0081                 ORA     #$C0
0083                 STA     $FFFD
0086                 STA     $03F3
0089                 EOR     #$A5
008B                 STA     $03F4


Set up reset vector.

Code:
008E                 LDA     #$08
0090                 STY     $00
0092                 STA     $01
0094                 LDA     #$A0
0096                 STA     ($00),Y
0098                 INY
0099                 BNE     $96
009B                 INC     $01
009D                 LDA     $01
009F                 CMP     #$0C
00A1                 BNE     $94
00A3                 LDA     $C051
00A6                 LDA     $C055


Erase text screen 2 and then display it (because first text screen is about to be filled with code).

Code:
00A9                 LDX     #$04
00AB                 STX     $40
00AD                 STX     $3D
00AF                 STY     $3C
00B1                 PHA
00B2                 TXA
00B3                 PHA
00B4                 PHA
00B5                 PHA
00B6                 LDX     $2B
00B8                 LDA     $C08C,X
00BB                 BPL     $B8
00BD                 CMP     #$D4
00BF                 BNE     $B8
00C1                 LDA     $C08C,X
00C4                 BPL     $C1
00C6                 CMP     #$DB
00C8                 BNE     $BD
00CA                 LDA     $C08C,X
00CD                 BPL     $CA
00CF                 CMP     #$AF
00D1                 BNE     $C6
00D3                 LDA     $C08C,X
00D6                 BPL     $D3
00D8                 ROL
00D9                 STA     $3F
00DB                 LDA     $C08C,X
00DE                 BPL     $DB
00DE                 BPL     $DB
00E0                 AND     $3F
00E2                 STA     ($3C),Y
00E4                 INY
00E5                 BNE     $D3
00E7                 INC     $3D
00E9                 DEC     $40
00EB                 BNE     $D3
00ED                 LDA     $C08C,X
00F0                 BPL     $ED
00F2                 CMP     #$AE
00F4                 BNE     $A9
00F6                 LDA     $C08C,X
00F9                 BPL     $F6
00FB                 CMP     #$EE
00FD                 BNE     $A9


Read prologue D4 DB AF, then 1024 bytes in 4-and-4 encoding to $400+, and epilogue AE EE. No checksum.

Code:
00FF                 RTS


Then return to $405.

Code:
0405                 PHA
0406                 PHA
0407                 PHA
0408                 PHA
0409                 PHA
040A                 PHA


These are important later.

Code:
040B                 STX     $08
040D                 LDX     #$03
040F                 LDA     $0400,X
0412                 STA     $00,X
0414                 DEX
0415                 BPL     $040F
0417                 JSR     $04F0
041A                 NOP
041B                 LDA     #$40
041D                 PHA
041E                 LDX     #$0C
0420                 JSR     $0500
0423                 LDA     $30
0425                 CLC
0426                 ADC     #$02
0428                 JSR     $0572


Full-track stepping. For now.

Code:
042B                 PLA
042C                 CLC
042D                 ADC     #$0C
042F                 CMP     #$B8
0431                 BCC     $041D


Read 4-and-4 data to $4000-B7FF. The step routine is at $572, nothing special, but the read routine at $500...

Code:
0500                 STX     $5E
0502                 STA     $5A
0504                 LDX     $5E
0506                 STX     $40
0508                 LDY     #$00
050A                 LDA     $5A
050C                 STY     $5C
050E                 STA     $5D
0510                 LDX     $08
0512                 JSR     $056C
0515                 CMP     $00
0517                 BNE     $0512
0519                 JSR     $056C
051C                 CMP     $01
051E                 BNE     $0515
0520                 JSR     $056C
0523                 CMP     $02
0525                 BNE     $051C


Variable prologue bytes.

Code:
0527                 LDA     $C08C,X
052A                 BPL     $0527
052C                 ROL
052D                 STA     $5F
052F                 LDA     $C08C,X
0532                 BPL     $052F
0534                 AND     $5F
0536                 STA     ($5C),Y
0538                 INY
0539                 BNE     $0527
053B                 ASL     $C000
053E                 LDA     $C08C,X
0541                 BPL     $053E
0543                 CMP     $03
0545                 BNE     $0504
0547                 INC     $5D
0549                 DEC     $40
054B                 BNE     $0527


Each sector has a 1-byte variable epilogue.

Code:
054D                 JSR     $056C
0550                 STA     $02
0552                 JSR     $056C
0555                 STA     $01
0557                 JSR     $056C
055A                 STA     $00
055C                 JSR     $056C
055F                 STA     $03
0561                 JSR     $056C


The prologue and epilogue are part of the sector data!

Code:
0564                 CMP     $00
0566                 BNE     $0569


And there's even an epilogue check for the epilogue.
Nothing much to see until we get here:

Code:
0457                 PLA
0458                 PLA
0459                 PLA
045A                 PLA
045B                 EOR     #$65
045D                 PHA
045E                 EOR     #$31
0460                 PHA
0461                 RTS


Obfuscated entrypoint decodes to $8BBB.

Code:
8BBB                 EOR     #$7A
8BBD                 STA     $E7
8BBF                 TXA
8BC0                 EOR     #$88
8BC2                 STA     $E6
8BC4                 JSR     $8B20


Looks okay. It's a strange place to start but okay.

Code:
8B20                 LDX     #$07
8B22                 LDA     $00,X
8B24                 STA     $90,X
8B26                 DEX
8B27                 BPL     $8B22
8B29                 LDA     #$90
8B2B                 PHA
8B2C                 PHA
8B2D                 LDY     #$08
8B2F                 LDX     #$20
8B31                 DEX
8B32                 BNE     $8B31
8B34                 BIT     $C030
8B37                 DEY
8B38                 BNE     $8B2F
8B3A                 RTS


Plays a sound and then returns. Oh, those PHAs are easy to overlook.
We return to $9091 instead.

Code:
9091                 LDY     #$00
9093                 LDA     $9000,Y
9096                 EOR     #$EE
9098                 STA     $0200,Y
909B                 INY
909C                 BNE     $9093
909E                 JMP     $02DD


More decoding.

Code:
02DD                 LDY     #$00
02DF                 LDA     $9000,Y
02E2                 EOR     $0400,Y
02E5                 EOR     $0500,Y
02E8                 EOR     $0600,Y
02EB                 EOR     $0700,Y
02EE                 EOR     #$EE
02F0                 STA     $9000,Y
02F3                 INY
02F4                 BNE     $02DF
02F6                 JMP     $9004


This one is super annoying. The RWTS is at $400-7FF. Any change that we make to it causes this routine to decode garbage.
That includes after we've put our own RWTS and then found bugs in it that we have to fix. :-(
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Ven 06 Jan 2017, 18:22    Sujet du message: Répondre en citant

Code:
9004                 LDX     $2B
9006                 LDA     $C08C,X
9009                 BPL     $9006
900B                 CMP     $00
900D                 BNE     $9006
900F                 LDA     $C08C,X
9012                 BPL     $900F
9014                 CMP     $01
9016                 BNE     $900B
9018                 LDA     $C08C,X
901B                 BPL     $9018
901D                 CMP     $02
901F                 BNE     $9014
9021                 NOP
9022                 LDA     $C08C,X
9025                 BPL     $9022
9027                 SEC
9028                 ROL
9029                 STA     $FF
902B                 LDA     $C08C,X
902E                 BPL     $902B
9030                 AND     $FF
9032                 NOP
9033                 STA     $905B
9036                 LDA     $C08C,X
9039                 BPL     $9036
903B                 SEC
903C                 ROL
903D                 STA     $FF
903F                 LDA     $C08C,X
9042                 BPL     $903F
9044                 AND     $FF
9046                 STA     $905C
9049                 NOP
904A                 LDA     $C08C,X
904D                 BPL     $904A
904F                 SEC
9050                 ROL
9051                 STA     $FF
9053                 LDA     $C08C,X
9056                 BPL     $9053
9058                 AND     $FF
905A                 STA     $FFFF
905D                 CMP     #$FF
905F                 BNE     $9022
9061                 LDA     $C08C,X
9064                 BPL     $9061
9066                 CMP     #$FF
9068                 BEQ     $906D
906A                 JMP     $0609
906D                 RTS


Decode 4-and-4 data that are the *address and value to write*. Yes, the sector data hold both the address and the value.
This routine can't be bypassed because it's used to set critical values that are used everywhere in the game.

Code:
8BC7                 LDY     #00
8BC9                 LDA     ($E6),Y
8BCB                 LDY     #01
8BCD                 LDA     $4E
8BCF                 PHA
8BD0                 JSR     $9150
8BD3                 JSR     $85B4
8BD6                 LDY     #01
8BD8                 LDA     ($E6),Y
8BDA                 LDY     #$0C
8BDC                 JSR     $85A8
8BDF                 DEY
8BE0                 BNE     $8BDC
8BE2                 JSR     $8F30


Eventually we return. Not much to see here, but it displays the title sequence that almost no-one ever saw before.
Press "ctrl-u" during boot to make it display faster.
There's also a credit and copyright notice in a region of the screen that no-one ever saw before because there's a bug in the title code that never shows it (technically, it's shown but so quickly that it's too hard to read. We learn from it that "David" is "David Snider").

Code:
8F30                 JSR     $8F80
8F33                 LDY     #$07
8F35                 STY     $82
8F37                 JSR     $8F00
8F3A                 LDA     $80
8F3C                 BEQ     $8F47
8F3E                 LDA     $C081,X
8F41                 LDA     $C081,X
8F44                 JSR     $8F90
8F47                 LDY     $82
8F49                 DEY
8F4A                 BPL     $8F35
8F4C                 JSR     $8F80
8F4F                 NOP
8F50                 JSR     $8EA0


Nothing here.

Code:
8EA0                 LDY     $FFFC
8EA3                 LDA     $FFFD
8EA6                 LDX     #$8C
8EA8                 CPY     #$62
8EAA                 BNE     $8EB2
8EAC                 EOR     #$FA
8EAE                 BNE     $8EF5
8EB0                 BEQ     $8EBD
8EB2                 CPY     #$59
8EB4                 BNE     $8EF5
8EB6                 CMP     #$FF
8EB8                 BNE     $8EF5
8EBA                 INX
8EBB                 LDA     #$50
8EBD                 STA     $00
8EBF                 STX     $01
8EC1                 LDY     #$02
8EC3                 LDA     ($00),Y
8EC5                 STA     $02,Y
8EC8                 DEY
8EC9                 BPL     $8EC3
8ECB                 LDA     #$03
8ECD                 CLC
8ECE                 ADC     $00
8ED0                 STA     $00
8ED2                 BCC     $8ED6
8ED4                 INC     $01
8ED6                 LDY     $04
8ED8                 BEQ     $8EF3
8EDA                 LDA     ($00),Y
8EDC                 CMP     ($02),Y
8EDE                 BNE     $8EF4


Ah. This code checks ROM for certain values, because the ROM code will never change, right?
That is, until the enhanced IIe came out. Oops, some of those bytes are different, and the game can't run there.
It's the same mistake that exists in Choplifter. Anyway, if we pass that check, we get here:

Code:
8BFB                 JMP     ($0028)


The value comes from the routine earlier. If we didn't run it, the game would reboot instead.

Code:
0400                 LDA     #$00
0402                 JSR     $FCA8
0405                 LDA     #$16
0407                 JSR     $0572
040A                 LDY     #$00
040C                 STY     $09
040E                 LDA     $04A2,Y
0411                 BEQ     $0438
0413                 CLC
0414                 ADC     $30
0416                 JSR     $0572
0419                 LDY     $09
041B                 LDA     $04A0,Y
041E                 LDX     $04A1,Y
0421                 JSR     $0500
0424                 LDY     $09
0426                 INY
0427                 INY
0428                 INY
0429                 BNE     $040C


Read more data, but this time the stepping comes from a table.
It's full tracks for the first eight, but then it reads from five consecutive half-tracks.
Finally, we get here:

Code:
0438                 JMP     $0300


This routine reads the high-scores, also 4-and-4 encoded, and then runs the game.

What to do about all of that?


Dernière édition par qkumba le Ven 06 Jan 2017, 18:26; édité 1 fois
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
qkumba



Inscrit le: 29 Jan 2012
Messages: 165

MessagePosté le: Ven 06 Jan 2017, 18:25    Sujet du message: Répondre en citant

We know that the game reads and writes to the disk, so we need to do the same.
The boot sector looks the same up to this point:

Code:
0831                 JSR     $023A


That goes here now:

Code:
023A                 LDX     #$16
023C                 STX     $00
023E                 TXA
023F                 ASL
0240                 BIT     $00
0242                 BEQ     $025A
0244                 ORA     $00
0246                 EOR     #$FF
0248                 AND     #$7E
024A                 BCS     $025A
024C                 LSR
024D                 BNE     $024A
024F                 TYA
0250                 STA     $BF40,X
0253                 TXA
0254                 ORA     #$80
0256                 STA     $BFC0,Y
0259                 INY
025A                 INX
025B                 BPL     $023C


This routine generates 6-and-2 tables for both reading and writing at the same time.
Then we reach our 6-and-2 read routine, and let the boot continue like before.
For the routine that runs in zpage, we have to make some changes.

Code:
00B8                 LDA     $C08C,X
00BB                 BPL     $B8
00BD                 CMP     #$D4
00BF                 BNE     $C1
00C1                 LDA     $C08C,X
00C4                 BPL     $C1
00C6                 CMP     #$DB
00C8                 BNE     $CA
00CA                 LDA     $C08C,X
00CD                 BPL     $CA
00CF                 CMP     #$AF
00D1                 BNE     $D3
00D3                 LDA     $C08C,X
00D6                 BPL     $D3
00D8                 ROL
00D9                 STA     $3F
00DB                 LDA     $C08C,X
00DE                 BPL     $DB
00E0                 AND     $3F
00E2                 JSR     $025D
00E5                 INC     $27
00E7                 INC     $3D
00E9                 DEC     $40
00EB                 BNE     $D3
00ED                 LDA     $C08C,X
00F0                 BPL     $ED
00F2                 CMP     #$AE
00F4                 BNE     $F6
00F6                 LDA     $C08C,X
00F9                 BPL     $F6
00FB                 CMP     #$EE
00FD                 BNE     $FF
00FF                 RTS


It looks very similar except that the prologue check doesn't branch on mismatch, and we've inserted a JSR at $E2 to read a regular sector.
Here are the only differences that we needed:

Code:
AE: A4->BE
B0: A5->BF
C0: 6E->99
C9: 6A->99
D2: 6A->99
E2: 08->B9
E3: A5->C4
E4: 51->9B
E5: 49->7F
E6: 75->BE
F5: 2A->99
FE: 33->99


Yes, we patch the new values directly into the encrypted data to avoid having to decode everything first.
Very surgical. :shock:

Code:
0519                 JSR     $056C
051C                 CMP     $01
051E                 BNE     $0520
0520                 JSR     $056C
0523                 CMP     $02
0525                 BNE     $0527
0527                 LDA     $C08C,X
052A                 BPL     $0527
052C                 ROL
052D                 STA     $5F
052F                 LDA     $C08C,X
0532                 BPL     $052F
0534                 AND     $5F
0536                 STA     ($5C),Y
0538                 JSR     $0621
053B                 ASL     $C000
053E                 LDA     $C08C,X
0541                 BPL     $053E
0543                 CMP     $03
0545                 INC     $5E
0547                 INC     $5D
0549                 DEC     $40
054B                 BNE     $0527


We make similar changes to this routine. The prologue check doesn't branch on mismatch, and we've inserted a JSR at $538 to read a regular sector.

Code:
9004                 LDY     #$00
9006                 CLC
9007                 BCS     $9041 ;hides a SEC instruction to set carry for second pass
9009                 LDA     $9023
900C                 STA     $901C,Y
900F                 INC     $900A
9012                 INY
9013                 BCC     $9008
9015                 BMI     $901B
9017                 LDY     #$80
9019                 BCS     $9009
901B                 STA     $0000 ;self-modifying
901E                 CMP     #$FF
9020                 BNE     $9004
9022                 RTS
9023                 .BYTE   $4E, $00, $62
9026                 .BYTE   $4F, $00, $F8
9029                 .BYTE   $20, $00, $6C
902C                 .BYTE   $21, $00, $4E
902F                 .BYTE   $22, $00, $00
9032                 .BYTE   $3E, $00, $00
9035                 .BYTE   $3F, $00, $07
9038                 .BYTE   $3C, $00, $E8
903B                 .BYTE   $3D, $00, $A8
903E                 .BYTE   $28, $00, $40
9041                 .BYTE   $29, $00, $91
9044                 .BYTE   $90, $00, $D5
9047                 .BYTE   $91, $00, $FD
904A                 .BYTE   $92, $00, $F5
904D                 .BYTE   $93, $00, $D4
9050                 .BYTE   $16, $05, $90
9053                 .BYTE   $1D, $05, $91
9056                 .BYTE   $24, $05, $92
9059                 .BYTE   $44, $05, $93
905C                 .BYTE   $5B, $05, $90
905F                 .BYTE   $56, $05, $91
9062                 .BYTE   $51, $05, $92
9065                 .BYTE   $60, $05, $93
9068                 .BYTE   $65, $05, $90
906B                 .BYTE   $23, $00, $A0
906E                 .BYTE   $24, $00, $1D
9071                 .BYTE   $FF, $FF, $FF


We replace the special sector routine with a load/store sequence that does the same thing.

Code:
8ED8                 BNE     $8EF3


We change the ROM check so that it exits immediately.
We change the stepping table so it reads from whole tracks.

Code:
0311                 LDA     #$02
0313                 STA     $5D
0315                 JSR     $0621


Load the scores from a regular sector, and the game runs.
As for saving, we replace the existing write routine with the one from DOS.
We have the write table prepared from long ago, and there's a spare page of memory that we can use for encoding the data.
No problem.
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web de l'utilisateur
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet     Index du Forum -> PROTECTION MALEFIQUE Toutes les heures sont au format GMT + 1 Heure
Page 1 sur 1

 
Sauter vers:  
Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum


Powered by phpBB © 2001, 2005 phpBB Group
Traduction par : phpBB-fr.com