--------Montana Reading Program-------- A 4am crack 2015-12-12 --------------------------------------- Name: The Montana Reading Program: Learning Sight Words Genre: educational Year: 1984 Credits: Developed by: Professional Software Services Programmed by: Dick Dramstad, Tom O'Sullivan, and Kirk Wennerstrom Illustrations by: Dee and Jerry Williams "Developed under a grant from the Foundation for the Advancement of Computer-aided Education." Publisher: Program Design, Inc. Media: single-sided 5.25-inch floppy OS: DOS 3.3 Previous cracks: none This disk was so dirty when I got it, I had to clean it (and my disk drive) 11 times before it would even boot. I don't often write about this part, but newly acquired floppies rarely boot on the first try. If you're holding on to any rare or unique floppies, the best time to digitize them was 20 years ago. The second best time is today. ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA disk read error on first pass Locksmith Fast Disk Backup reads every track except $03; copy hangs on boot EDD 4 bit copy (no sync, no count) no errors, but copy boots DOS and exits to prompt Oddly, DOS commands still work at this point, but the files are gibberish. ]CATALOG DISK VOLUME 254 *T 009 HTWORDS1 *T 012 HTWORDS2 *T 010 HTWORDS3 *T 011 HTWORDS4 *T 010 HTWORDS5 *T 009 HTSET1A *T 012 HTSET2A *T 010 HTSET3A *T 011 HTSET4A *T 010 HTSET5A *T 009 HTSET1B *T 012 HTSET2B *T 010 HTSET3B *T 011 HTSET4B *T 010 HTSET5B *A 007 HELLO *B 002 LOMEM: *A 004 PROG.S *B 026 DK.GEN *B 002 PICMOVE *B 033 INTRO *B 012 P3.K *B 016 P1.K *B 011 P2.K A 034 PROG.G ]LOAD HELLO ...hangs... ]LIST A 034 PROG.G ]LOAD HELLO ]LIST 20746 SQR eghk HCOLOR= HGR2 o vf CHR$ ONERR kth}e lPs9yw LEN O A OUT OF MEMORY C THEN ROT= TIKXB#42*E&$%,#UNW CLEAR SAVE "%.$&rv LOMEM: STRING TOO L ONG 4)+8"CTRJ%N@&NKA.7 IN# 4 NOTRACE 2C8} ILLEGAL QUANTITY RND d TYPE MISMATCH SPC( | ERROR * CAN'T CONTINUE PEEK LEFT$ STRING TOO LONG SYNTAX TRACE OVERFLOW = BAD SUBSCRIPT RIGHT$ TYPE MISMATCH VAL INVERSE TRACE ASC ' RIGHT$ REDIM'D ARRAY UNDEF'D STATEMENT RETURN WITHOUT GOSUB h TEXT ILLEGAL QUANTITY . ASC ERROR VAL TYPE MISMATCH GOSUB SCRN( COS AT EXP DIVISION BY ZERO ...and so on... I viewed some of the text files in Copy II Plus, and they seem OK. Also, the binary files load without hanging, and they appear to be relatively normal. But all of the BASIC files are garbage. Copy ][+ nibble editor T03 appears to be almost entirely sync bytes (all $FF, no data, no sectors per se, no structure at all) Disk Fixer T00,S00 -> DOS 3.3 bootloader T01,S09 -> startup program is blank?! T11 -> DOS 3.3-style disk catalog can't read T03 under any combination of parameters Why didn't COPYA work? T03 is unreadable because it does not have a standard sector structure Why didn't Locksmith FDB work? probably a nibble check during boot, looking for some nibble sequence on track $03 that wasn't copied Why didn't my EDD copy work? I have no idea. Next steps: 1. Capture bootloader with AUTOTRACE 2. Find nibble check and disable it 3. Figure out what's up with the garbled BASIC programs ~ Chapter 1 In Which We Get Nothing For Free, And Our Adventure Begins In Earnest [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 ; move RWTS into place, except the one ; page at $BF00 that Diversi-DOS 64K ; uses *B600<2600.2EFFM *B700L . . [nothing suspicious, until...] . B730- A9 00 LDA #$00 B732- 9D F8 04 STA $04F8,X B735- 9D 78 04 STA $0478,X B738- 20 03 BB JSR $BB03 <-- ! B73B- A2 FF LDX #$FF B73D- 9A TXS B73E- 8E EB B7 STX $B7EB B741- 4C C8 BF JMP $BFC8 B744- 20 89 FE JSR $FE89 ; cold-start DOS B747- 4C 84 9D JMP $9D84 Having a JSR at $B738 is not unusual, but it is supposed to call $B793 to execute the multi-sector read loop that reads the rest of DOS into memory. And there isn't usually any code at all in $BB00..$BC55. (That range is used for scratch space during RWTS operations.) *BB03L BB03- 4E 06 BB LSR $BB06 Uh oh. Self-modifying code. The 6502 processor has no instruction cache, so one instruction can literally change the next instruction in memory, and the CPU will execute the new instruction. Which is what's happening here. This may take some patience. ~ Chapter 2 In Which We Learn The True Meaning Of Patience To capture this self-modifying code, I need to reproduce the modifications without running the modified code. I'll start with a pristine copy (at $2B00), copy it into place (at $BB00), then reproduce the modifications and inspect the results. Lather, rinse, repeat. *2B00 and hangs until you press something else. That part is skipped for now, but I'm guessing it's called later. Location | Description | Value -------------+------------------+------ $B474 | length of data | $03 $B475/$B476 | starting address | $A502 $B477..$B479 | data The 3 bytes at $B477 end up at $A503, which is the tail end of the RUN entry point. It's just a JMP to the code that was just patched earlier: A503- 4C 36 9E JMP $9E36 Thus, trying to break to the prompt during boot will hang until you press something else. (Even if you did manage to get to the prompt, the RUN flag would ensure you couldn't do anything useful. Defense in depth!) Location | Description | Value -------------+------------------+------ $B47A | length of data | $30 $B47B/$B47C | starting address | $B5FF $B47D..$B4AC | data The $30 bytes at $B47D end up at $B600. The new code looks like this: B600- 60 RTS B601- A0 20 LDY #$20 B603- B9 0F B6 LDA $B60F,Y B606- 99 00 03 STA $0300,Y B609- 88 DEY B60A- 10 F7 BPL $B603 B60C- 4C 00 03 JMP $0300 B60F- A9 BF LDA #$BF B611- 85 01 STA $01 B613- A0 00 LDY #$00 B615- 84 00 STY $00 B617- 91 00 STA ($00),Y B619- C8 INY B61A- D0 FB BNE $B617 B61C- C6 01 DEC $01 B61E- A5 01 LDA $01 B620- C9 08 CMP #$08 B622- B0 F3 BCS $B617 B624- AD 81 C0 LDA $C081 B627- 20 93 FE JSR $FE93 B62A- 20 89 FE JSR $FE89 B62D- 4C 00 E0 JMP $E000 Looks like this is going to be The Badlands routine that wipes main memory and exits. Location | Description | Value -------------+------------------+------ $B4AD | length of data | $01 $B4AE/$B4AF | starting address | $B7C1 $B4B0 | data | $60 This puts an RTS instruction at $B7C2, which would normally set up the RWTS parameters for writing DOS after INIT. Location | Description | Value -------------+------------------+------ $B4B1 | length of data | $03 $B4B2/$B4B3 | starting address | $9E72 $B4B4..$B4B6 | data This modifies DOS's image of the page 3 jump vectors so that will jump to $B601, a.k.a. The Badlands. Location | Description | Value -------------+------------------+------ $B4B7 | length of data | $02 $B4B8/$B4B9 | starting address | $A396 $B4BA..$B4BB | data | 18 60 This patch neutralizes the SAVE handler at $A397 so it does nothing but claims to have succeeded. That's it. The next byte is $00, so the BEQ at $B583 branches and the patch loop exits gracefully via RTS. (There appear to be more patches to decrypt binary files, but this disk does not use them.) The result is a really messed up DOS that is maximally unfriendly to prying eyes and maximally incompatible with any other version of DOS. It decrypts BASIC files on the fly, traps , traps , sets the RUN flag, and disables the SAVE command. It does not, however, hinder copying the disk itself. (So why did I bother documenting it? Don't ask me; you're the one who read this far.) The only patch I need to bypass the protection is at $BB03: 1. push $B5/$19 to the stack 3. jump to $B793 T00,S05,$03 old: "4E 06 BB 71 6E 0A BB 40 27" new: "A9 B5 48 A9 19 48 4C 93 B7" --v-- T00,S05 ----------- DISASSEMBLY MODE ---------- 0003:A9 B5 LDA #$B5 0005:48 PHA 0006:A9 19 LDA #$19 0008:48 PHA 0009:4C 93 B7 JMP $B793 --^-- ]PR#6 ...works, and it is glorious... Quod erat liberandum. --------------------------------------- A 4am crack No. 517 ------------------EOF------------------