-------------Delta Drawing------------- A 4am crack 2015-11-25 --------------------------------------- Name: Delta Drawing: Introduction to Graphics Programming Version: 3.33 Genre: graphics Year: 1984 Author: Tom Kalt Publisher: Spinnaker Software, Inc. Media: single-sided 5.25-inch floppy OS: DOS 3.3 with custom bootloader Previous cracks: none ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA no errors; copy boots, displays text title screen, then hangs with drive motor on Locksmith Fast Disk Backup ditto EDD 4 bit copy (no sync, no count) no errors, but copy boots to text title screen then clears screen and prints "DEFECTIVE DISK" and exits to a BASIC prompt Copy ][+ nibble editor nothing suspicious Disk Fixer T00 -> DOS 3.3 bootloader but no sign of a full DOS T11 -> DOS 3.3 disk catalog with data files (no program code) Why didn't any of my copies work? Given the behavior of my failed bit copy, I'm going to guess there's a runtime protection check. Disks do not declare themselves defective unless someone tells them to. Next steps: 1. Trace the boot 2. ??? ~ Chapter 1 In Which Our Automated Tools Are Useful But Not Sufficient [S6,D1=original disk] [S5,D1=my work disk] ]PR#5 ... CAPTURING BOOT0 ...reboots slot 6... ...reboots slot 5... SAVING BOOT0 CAPTURING BOOT1 ...reboots slot 6... ...reboots slot 5... SAVING BOOT1 SAVING RWTS ]BLOAD BOOT1,A$2600 ]CALL -151 *FE89G FE93G ; disconnect DOS *B600<2600.2FFFM ; move RWTS into place *B700L B700- 8E E9 B7 STX $B7E9 B703- 8E F7 B7 STX $B7F7 B706- A9 01 LDA #$01 B708- 8D F8 B7 STA $B7F8 B70B- 8D EA B7 STA $B7EA ; load $50 sectors (5 tracks) B70E- A9 50 LDA #$50 B710- EA NOP B711- 8D E1 B7 STA $B7E1 ; start on T05,S0F B714- A9 05 LDA #$05 B716- 8D EC B7 STA $B7EC B719- A9 0F LDA #$0F B71B- 8D ED B7 STA $B7ED ; load into $8F00 (down to $4000) B71E- A0 8F LDY #$8F B720- EA NOP B721- EA NOP B722- 8C F1 B7 STY $B7F1 B725- A9 01 LDA #$01 B727- 8D F4 B7 STA $B7F4 B72A- 8A TXA B72B- 4A LSR B72C- 4A LSR B72D- 4A LSR B72E- 4A LSR B72F- AA TAX B730- A9 00 LDA #$00 B732- 9D F8 04 STA $04F8,X B735- 9D 78 04 STA $0478,X B738- 20 93 B7 JSR $B793 B73B- A2 FF LDX #$FF B73D- 9A TXS B73E- 8E EB B7 STX $B7EB ; and jump there B741- 4C 00 40 JMP $4000 I can interrupt the boot and capture that entire chunk in one shot. *9600 *C500G ... ]BSAVE BOOT1,A$4000,L$5000 ~ Chapter 2 In Which That Which Was Hidden Is Finally Revealed ]CALL -151 *4000L ; subroutine at $455D initializes some ; zero page values (not shown) 4000- 20 5D 45 JSR $455D 4003- 20 DD 83 JSR $83DD *83DDL ; manually pushing values to the stack ; (maybe an address? $518F would be in ; the chunk we just read) 83DD- A9 51 LDA #$51 83DF- 48 PHA 83E0- A9 8E LDA #$8E 83E2- 48 PHA ; now this 83E3- A9 1B LDA #$1B 83E5- 20 5D 6A JSR $6A5D *6A5DL ; ignore branch, since we just loaded ; the accumulator with this value 6A5D- C9 1B CMP #$1B 6A5F- D0 02 BNE $6A63 ; remove the return address (this was ; called via JSR) -- so now we're left ; with the values we manually pushed ; to the stack at $83DD 6A61- 68 PLA 6A62- 68 PLA ; harmless (not shown) 6A63- 20 86 40 JSR $4086 ; now exit via RTS 6A66- 60 RTS Execution continues at $518F (because of the $51/$8E that was manually pushed to the stack at $83DD). Tricky! *518FL ; and round and round we go 518F- 20 20 41 JSR $4120 *4120L ; set up reset vector to go to the ; routine at $518F (which just called ; this one) 4120- A9 8F LDA #$8F 4122- 8D F2 03 STA $03F2 4125- A9 51 LDA #$51 4127- 8D F3 03 STA $03F3 412A- 49 A5 EOR #$A5 412C- 8D F4 03 STA $03F4 412F- A9 00 LDA #$00 4131- 8D 2C 0F STA $0F2C 4134- 8D 5F 0F STA $0F5F ; $B7E8 is the RWTS parameter table 4137- A0 E8 LDY #$E8 4139- A9 B7 LDA #$B7 413B- 84 93 STY $93 413D- 85 94 STA $94 ; get some values from the main RWTS ; parameter table and copy them to ; another table that starts at $8F52 413F- A0 01 LDY #$01 4141- B1 93 LDA ($93),Y 4143- 8D 53 8F STA $8F53 4146- A0 02 LDY #$02 4148- B1 93 LDA ($93),Y 414A- 8D 54 8F STA $8F54 414D- A0 0F LDY #$0F 414F- B1 93 LDA ($93),Y 4151- 8D 61 8F STA $8F61 4154- A0 10 LDY #$10 4156- B1 93 LDA ($93),Y 4158- 8D 62 8F STA $8F62 ; harmless (not shown) 415B- 20 08 41 JSR $4108 ; prints text title screen based on the ; strings that follow, then returns to ; the next instruction after the data 415E- 20 1A 74 JSR $741A . . [strings] . 4264- 4E 67 42 LSR $4267 4267- 41 9C EOR ($9C,X) 4269- 7C ??? Aha! Self-modifying code! Neatly tucked in there, immediately after a bunch of data. Just in case you thought we were going to make it easy for you to find. *300:4E 67 42 60 *300G *4267L 4267- 20 9C 7C JSR $7C9C Revealed: a cleverly hidden JSR! *7C9CL 7C9C- 4E 9F 7C LSR $7C9F 7C9F- 71 6E ADC ($6E),Y 7CA1- A3 ??? Revealed: more self-modifying code! ~ Chapter 3 In Which Progress Is Slow But Steady First, I'm going to make a copy of the pristine code, before I start mucking with it too severely. *3C00<7C00.7CFFM 2000- A0 00 LDY #$00 2002- B9 00 3C LDA $3C00,Y 2005- 99 00 7C STA $7C00,Y 2008- C8 INY 2009- D0 F7 BNE $2002 ; the first mucking 200B- 4E 9F 7C LSR $7C9F 200E- 60 RTS *2000G Progress? *7C9FL 7C9F- 38 SEC 7CA0- 6E A3 7C ROR $7CA3 Progress! But not enough. *200E:38 6E A3 7C 60 *2000G Progress? *7CA3L 7CA3- A0 F8 LDY #$F8 7CA5- 6E A8 7C ROR $7CA8 Progress! But not enough. *2012:A0 F8 6E A8 7C 60 *2000G Progress, not enough, more to do, &c. *7CA8L 7CA8- 6E B4 7C ROR $7CB4 7CAB- 6E AE 7C ROR $7CAE *2017:6E B4 7C 6E AE 7C 60 *2000G *7CAEL 7CAE- 6E B7 7C ROR $7CB7 7CB1- 6E BE 7C ROR $7CBE 7CB4- B9 C0 7C LDA $7CC0,Y *201D:6E B7 7C 6E BE 7C B9 C0 7C 60 *2000G *7CB7L 7CB7- 59 00 B8 EOR $B800,Y 7CBA- 99 C0 7C STA $7CC0,Y 7CBD- 88 DEY 7CBE- D0 F4 BNE $7CB4 Finally some serious progress. But I'm going to need part of the original boot1 code in place, since it serves as the decryption key. *BLOAD BOOT1,A$A600 *B800