---Reading & Writing! with The Boars--- A 4am crack 2014-12-20 --------------------------------------- "Reading & Writing! with The Boars" is a 1989 educational program distributed by McGraw-Hill, Inc. The program comes on one double-sided disk. Only side A is bootable. COPYA reads both sides, but the copy does not work. It loads ProDOS, prints "Please wait while loading...", briefly shows a graphical title screen, then prints "Unauthorized Duplicate found" and hangs. And I really have to applaud them for their spot-on diagnosis. Booting from my ProDOS hard drive and running BASIC.SYSTEM, I can start to investigate by cataloging the disk. [S6,D1=non-working copy, side A] ]CAT,S6,D1 /PLCP NAME TYPE BLOCKS MODIFIED TITLESCRN BIN 5 27-MAY-89 PRODOS SYS 32 17-APR-87 WRITEIT.SYSTEM SYS 1 17-DEC-88 ANM.SUBS BIN 3 16-DEC-88 BACK.PIC BIN 17 14-MAR-89 CONFIG.DATA BIN 6 28-NOV-93 CREDITS1.PIC BIN 6 26-MAY-89 CREDITS2.PIC BIN 7 11-DEC-88 DUMP.COLR BIN 4 30-NOV-88 DUMP.HIRES.96 BIN 5 17-DEC-88 DUMP.NORM BIN 5 6-DEC-88 FORMATTER BIN 8 3-JAN-89 FRONT.PIC BIN 17 14-MAR-89 *I.DRIVERS BIN 7 24-JAN-85 I.DVRS BIN 8 30-NOV-88 MTW BIN 8 17-DEC-88 MTW.PATTERNS BIN 1 17-DEC-88 MULTIPAGE BIN 4 2-DEC-88 OPEN.PIC1 BIN 9 10-JAN-89 OPEN.PIC2 BIN 9 10-JAN-89 *P.DRIVERS BIN 13 12-FEB-85 P.DVRS BIN 14 30-NOV-88 PRTR.DATA BIN 5 16-DEC-88 READ.PIC BIN 6 20-DEC-88 THEEND.PIC BIN 8 6-DEC-88 TITLE.PIC BIN 3 20-DEC-88 WRITE.PIC BIN 4 6-DEC-88 WRITEIT BIN 21 28-APR-89 HELP.FONT $07 4 28-APR-89 MENU.FONT $07 7 28-APR-89 STORY.FONT $07 11 27-APR-89 THE.RABBIT $F2 7 18-DEC-88 CONFIG.DATA.S TXT 5 25-MAY-89 BLOCKS FREE: 3 BLOCKS USED: 277 ]PREFIX /PLCP ProDOS always loads the first .SYSTEM file at $2000 and jumps to it. ]BLOAD WRITEIT.SYSTEM,A$2000,TSYS ]CALL -151 *2000L ; initialize system and clear screen 2000- D8 CLD 2001- 8D 00 C0 STA $C000 2004- 8D 0C C0 STA $C00C 2007- 8D 54 C0 STA $C054 200A- 20 58 FC JSR $FC58 ; print carriage returns 200D- A0 0C LDY #$0C 200F- A9 8D LDA #$8D 2011- 20 F0 FD JSR $FDF0 2014- 88 DEY 2015- 10 F8 BPL $200F ; this is just a print routine 2017- A9 F5 LDA #$F5 2019- A0 20 LDY #$20 201B- 20 A2 20 JSR $20A2 ; another carriage return 201E- A9 8D LDA #$8D 2020- 20 F0 FD JSR $FDF0 ; don't know what this does yet 2023- A9 B5 LDA #$B5 2025- A0 20 LDY #$20 2027- A2 18 LDX #$18 2029- 20 51 20 JSR $2051 202C- D0 03 BNE $2031 ; but it appears to load something from ; disk, because $1800 didn't have ; anything loaded yet 202E- 4C 00 18 JMP $1800 Let's put an RTS there and see what ends up at $1800. *202E:60 *2000G *1800L 1800- 8D 00 C0 STA $C000 1803- 2C 54 C0 BIT $C054 1806- A9 F4 LDA #$F4 1808- 85 06 STA $06 180A- A9 1D LDA #$1D 180C- 85 07 STA $07 180E- A9 00 LDA #$00 1810- 85 09 STA $09 ; this appears to read a file via MLI ; commands, then print a period 1812- 20 72 1B JSR $1B72 ; my best guess is that this routine is ; an image unsquasher (all the .PIC ; files on disk are compressed images) 1815- A2 20 LDX #$20 1817- 20 69 1C JSR $1C69 ; show the graphical title screen 181A- 2C 50 C0 BIT $C050 181D- 2C 57 C0 BIT $C057 1820- 2C 54 C0 BIT $C054 1823- 2C 52 C0 BIT $C052 ; wait loop 1826- A9 10 LDA #$10 1828- 85 08 STA $08 182A- A9 FF LDA #$FF 182C- 20 A8 FC JSR $FCA8 182F- C6 08 DEC $08 1831- D0 F7 BNE $182A ; hmm 1833- 20 00 1D JSR $1D00 1836- 90 4D BCC $1885 ; clear screen 1838- 2C 51 C0 BIT $C051 183B- 20 58 FC JSR $FC58 183E- AD 84 18 LDA $1884 1841- 8D F4 03 STA $03F4 1844- 8D DB 1D STA $1DDB ; print something 1847- A2 00 LDX #$00 1849- BD 5C 18 LDA $185C,X 184C- 20 F0 FD JSR $FDF0 184F- E8 INX 1850- 8A TXA 1851- CD DB 1D CMP $1DDB 1854- D0 F3 BNE $1849 1856- 20 8B FD JSR $FD8B ; and hang 1859- 18 CLC 185A- 90 FD BCC $1859 My ears are ringing. The birds are singing. My Spidey sense is tingling. *1838G [clears screen and prints "Unauthorized Duplicate found"] That routine at $1D00 is a nibble check that clears the carry on exit if the check passed. [...reboot and replay my steps back to this point...] *1D00L 1D00- A9 60 LDA #$60 1D02- 8D D9 1D STA $1DD9 1D05- A9 05 LDA #$05 1D07- 8D DA 1D STA $1DDA 1D0A- AE D9 1D LDX $1DD9 ; turn on the drive motor manually ; (always suspicious) 1D0D- BD 8E C0 LDA $C08E,X 1D10- BD 89 C0 LDA $C089,X 1D13- A9 00 LDA #$00 1D15- 8D DB 1D STA $1DDB ; wait 1D18- A0 00 LDY #$00 1D1A- C8 INY 1D1B- D0 FD BNE $1D1A 1D1D- EE DB 1D INC $1DDB 1D20- D0 F6 BNE $1D18 1D22- A9 00 LDA #$00 1D24- 8C DB 1D STY $1DDB ; get a raw nibble from disk 1D27- 20 CD 1D JSR $1DCD ; increment the death counter 1D2A- C8 INY 1D2B- D0 08 BNE $1D35 1D2D- EE DB 1D INC $1DDB 1D30- D0 03 BNE $1D35 ; if we fall through here, give up and ; jump to the failure exit 1D32- 4C C8 1D JMP $1DC8 ; look for a specific nibble sequence ; to start the madness 1D35- C9 D5 CMP #$D5 1D37- D0 EE BNE $1D27 1D39- 20 CD 1D JSR $1DCD 1D3C- C9 AA CMP #$AA 1D3E- D0 F5 BNE $1D35 1D40- 20 CD 1D JSR $1DCD 1D43- C9 BB CMP #$BB 1D45- D0 EE BNE $1D35 ; skip over address field 1D47- A0 00 LDY #$00 1D49- 20 CD 1D JSR $1DCD 1D4C- 38 SEC 1D4D- 2A ROL 1D4E- 8D DB 1D STA $1DDB 1D51- 20 CD 1D JSR $1DCD 1D54- 2D DB 1D AND $1DDB 1D57- 99 DC 1D STA $1DDC,Y 1D5A- C8 INY 1D5B- C0 02 CPY #$02 1D5D- D0 EA BNE $1D49 ; skip over epilogue 1D5F- A0 00 LDY #$00 1D61- 20 CD 1D JSR $1DCD 1D64- C8 INY 1D65- C0 04 CPY #$04 1D67- D0 F8 BNE $1D61 ; require self-sync byte 1D69- BD 8C C0 LDA $C08C,X 1D6C- 10 FB BPL $1D69 1D6E- C9 FF CMP #$FF 1D70- D0 4E BNE $1DC0 ; kill some time to get out of sync ; with the "proper" start of nibbles) 1D72- BD 8D C0 LDA $C08D,X 1D75- A0 10 LDY #$10 1D77- A5 09 LDA $09 ; now start looking for nibbles that ; don't really exist (except they do, ; because we're out of sync and reading ; timing bits as data) 1D79- BD 8C C0 LDA $C08C,X 1D7C- 10 FB BPL $1D79 1D7E- 88 DEY 1D7F- F0 3F BEQ $1DC0 1D81- C9 EE CMP #$EE 1D83- D0 F4 BNE $1D79 1D85- A0 00 LDY #$00 1D87- BD 8C C0 LDA $C08C,X 1D8A- 10 FB BPL $1D87 1D8C- 99 DE 1D STA $1DDE,Y 1D8F- C8 INY 1D90- C0 04 CPY #$04 1D92- D0 F3 BNE $1D87 ; compare the out-of-sync nibbles to ; the expected sequence 1D94- AD DC 1D LDA $1DDC 1D97- CD D3 1D CMP $1DD3 1D9A- D0 24 BNE $1DC0 1D9C- AD DD 1D LDA $1DDD 1D9F- CD D4 1D CMP $1DD4 1DA2- D0 1C BNE $1DC0 1DA4- A0 00 LDY #$00 1DA6- B9 DE 1D LDA $1DDE,Y 1DA9- 49 87 EOR #$87 1DAB- 38 SEC 1DAC- E9 01 SBC #$01 1DAE- D9 D5 1D CMP $1DD5,Y ; if the out-of-sync nibbles are wrong, ; fail 1DB1- D0 0D BNE $1DC0 1DB3- 99 DE 1D STA $1DDE,Y 1DB6- C8 INY 1DB7- C0 04 CPY #$04 1DB9- D0 EB BNE $1DA6 ; success path falls through to here -- ; clear carry and exit 1DBB- BD 88 C0 LDA $C088,X 1DBE- 18 CLC 1DBF- 60 RTS ; decrement the death counter, give up ; when it hits 0 1DC0- CE DA 1D DEC $1DDA 1DC3- F0 03 BEQ $1DC8 1DC5- 4C 22 1D JMP $1D22 ; failure path is here -- set carry and ; exit 1DC8- BD 88 C0 LDA $C088,X 1DCB- 38 SEC 1DCC- 60 RTS ; subroutine to read a single nibble ; (used throughout) 1DCD- BD 8C C0 LDA $C08C,X 1DD0- 10 FB BPL $1DCD 1DD2- 60 RTS This nibble check is entirely self- contained, and the only "side effect" per se is setting or clearing the carry flag. I can bypass the entire thing by having $1D00 unconditionally clear the carry and exit. Turning to my trusty Disk Fixer sector editor, I found the nibble check on track $01, sector $0A. T01,S0A,$00 change "A9" to "18" (Ironically, the byte at $1D01 is already $60, which functions as an RTS once I change $1D00 to the one-byte CLC instruction.) The game boots and runs without complaint. Side B doesn't appear to require any changes. There doesn't appear to be any further protection. Quod erat liberandum. --------------------------------------- A 4am crack No. 181 ------------------EOF------------------