------------Treasure Hunter------------ A 4am crack 2014-06-06 --------------------------------------- "Treasure Hunter" is a 1984 educational game programmed by Byrd Kranish and Ann Worden; written by Susan Christie Thomas, Ira Wood, Bob Stickgold, George Sullivan, and Peter Cook; artwork by Marjean Stear; distributed by Intentional Educations, Inc. [The copy protection is identical to "MasterType," distributed by Scarborough Systems, Inc. This write-up is therefore quite similar to that one, with a few corrections.] COPYA fails miserably and immediately with a disk read error. EDD 4 bit copy gives no read errors, but the copy does not work. Almost immediately after booting, it displays "ERR1" in the upper-left corner of the screen, then fills the screen with garbage and reboots. Turning to my trusty Copy ][+ sector editor, I press "P" to enter the Sector Editor Patcher, then I select "DOS 3.3 PATCHED" to see if I can read the sector data by ignoring address and data epilogues. That works for sectors 0-9 on track 0. Beyond that, things get weird. Pressing "P" again, I select "CUSTOM", then turn off the checksum of the data field. Now I can read the sectors on the rest of the tracks... but they're all garbage. Like they're encrypted or something. The original sounds like a DOS 3.3 boot (track $02 --> $01 --> $00 --> $11 &c.) But here's what Copy ][+ thinks is on T11,S0F: --v-- SECTOR EDITOR DRIVE 1 00- FC ED F2 FC 03 FF 00 FC |mr|...| 08- 00 FC 00 12 0F 02 C8 C5 .|....HE 10- CC 30 CF A0 5C A0 5F A3 L0O \ _# 18- 5F A3 5F A0 5C A0 5C A0 _#_ \ \ 20- 5C A0 5F A3 5F A3 5F A3 \ _#_#_# 28- 5F A3 5C A0 02 FC EF F0 _#\ .|op 30- 7B 22 2C 32 3E 33 CF A3 {",2>3O# 38- C5 CC 31 2B 5F A3 5C A0 EL1+_#\ 40- 5C A0 5C A0 5C A0 5C A3 \ \ \ \# 48- 5F A3 5F A0 5C A0 5C F5 _#_ \ \u 50- FC EB F0 7B 2C 3C 2E 33 |kp{,<.3 58- CC 30 5F 32 3D 2C 52 2C L0_2=,R, 60- 3D 37 5C A0 5C A0 5C A0 =7\ \ \ 68- 5C A0 5C A0 5F A3 5F A3 \ \ _#_# 70- 5F A0 16 00 15 0F 84 CD _ .....M 78- C2 DB AD C2 CD 32 38 2D B[-BM28- 80- 3A 5C A0 5C A0 5F A3 5F :\ \ _#_ TRACK $11 SECTOR $0F CUSTOM --^-- That... is not a disk catalog. Or is it? If you squint, it kind of looks like one. "HEL0O" could be a file name. But what's the following sequence of $A0 and $5C alternating? It feels like that *could* be an encrypted version of "HELLO" followed by spaces. Or maybe I'm just imagining it, seeing patterns where none exist. Time for boot tracing with AUTOTRACE. [S6,D1=original disk] [S5,D1=my work disk] ]PR#5 CAPTURING BOOT0 ...reboots slot 6... ...reboots slot 5... SAVING BOOT0 For those of you just tuning in, my work disk uses a custom program that I affectionately call "AUTOTRACE" to automate the process of boot tracing as far as possible. For some disks (like this one, apparently), it just captures track 0, sector 0 (saved in a file called "BOOT0") and stops. For other disks that load in the same way that an unprotected DOS 3.3 disk loads, it captures the next stage of the boot process as well (in a file called "BOOT1"). BOOT1 contains sectors 0-9 on track 0, which are loaded into memory at $B600..$BFFF. This generally contains the RWTS routines which the program uses to read the rest of the disk. If the RWTS is fairly normal as well (and my AUTOTRACE program just spot- checks a few memory locations to guess at its "normalcy"), AUTOTRACE extracts the RWTS routines (generally loaded from track 0, sectors 2-9 into $B800.. $BFFF) and saves *that* into a third file called "RWTS". There's a good chance I'll be able to load that "RWTS" file into a tool called Advanced Demuffin (written in 1983 by The Stack) to convert the disk into a standard disk readable by unprotected DOS 3.3 disks or any other third-party tools. If anything looks fishy or non- standard, AUTOTRACE just stops, and I have to check the files it saved so far to determine why. In this case, it stopped after capturing T00,S00. So I need to look at that sector and figure out why. ]CALL -151 *800<2800.28FFM *801L ... Everything here looks pretty normal (i.e. just like an unprotected DOS 3.3 disk), until it goes to jump to the boot1 code. Usually that happens with an indirect JMP ($08FD), which, in a normal boot0, will end up continuing execution at $B700 which is stored in track 0, sector 1. But in this case, I see: 084A- 6C FE BB JMP ($BBFE) Highly suspect. I definitely want to see what evil lurks at whatever address $BBFE is pointing to. That area of memory is normally reserved for the denibblizing process when reading data from a sector. It's scratch space, essentially. It's overwritten every time the disk reads itself (after boot1 is loaded). But $BBFE isn't loaded yet, because I interrupted the boot process before it could be loaded. So now I need to trace the boot again, but a little bit further -- far enough for boot0 to load boot1 (including the suspicious pointer at $BBFE), but no further. My work disk has another program, unimaginatively named AUTOTRACE1, which does just that. It loads track 0, sector 0, then patches the boot0 code at $084A to call back to a routine under my control (instead of jumping to the original disk's boot1 code). ]BRUN AUTOTRACE1 CAPTURING BOOT1 ...reboots slot 6... ...reboots slot 5... SAVING BOOT1 SAVING RWTS Let's see what we have. ]CALL -151 *B600<2000.29FFM *BBFE.BBFF BBFE- 00 BB *BB00L BB00- A9 FF LDA #$FF BB02- 85 D6 STA $D6 ; check that disk is write-protected ; (this is probably where my copy is ; failing -- it doesn't even get to ; the nibble check or whatever follows) BB04- BD 8D C0 LDA $C08D,X BB07- BD 8E C0 LDA $C08E,X BB0A- 30 05 BMI $BB11 BB0C- A2 B1 LDX #$B1 BB0E- 4C F0 BB JMP $BBF0 ; check that the low-level reset vector ; at ($FFFC) has not been tampered with BB11- AD FD FF LDA $FFFD BB14- C9 FA CMP #$FA BB16- F0 05 BEQ $BB1D BB18- A2 B2 LDX #$B2 BB1A- 4C F0 BB JMP $BBF0 ; now search for a nibble sequence BB1D- BD 8C C0 LDA $C08C,X BB20- A9 00 LDA #$00 BB22- 8D 00 02 STA $0200 BB25- BD 8C C0 LDA $C08C,X BB28- 10 FB BPL $BB25 BB2A- C9 EB CMP #$EB BB2C- D0 F7 BNE $BB25 BB2E- BD 8C C0 LDA $C08C,X BB31- 10 FB BPL $BB2E BB33- C9 D5 CMP #$D5 BB35- D0 EE BNE $BB25 BB37- BD 8C C0 LDA $C08C,X BB3A- 10 FB BPL $BB37 BB3C- C9 AA CMP #$AA BB3E- D0 E5 BNE $BB25 ; wipe most of main memory ; ($0800..$95FF) BB40- A9 4C LDA #$4C BB42- A0 00 LDY #$00 BB44- 99 00 95 STA $9500,Y BB47- 88 DEY BB48- D0 FA BNE $BB44 BB4A- CE 46 BB DEC $BB46 BB4D- AD 46 BB LDA $BB46 BB50- C9 07 CMP #$07 BB52- D0 EC BNE $BB40 ; fiddle with RWTS to ignore epilogue ; bytes?! BB54- A9 18 LDA #$18 BB56- 8D 42 B9 STA $B942 ; read T00,S0A into $4000 BB59- A9 0A LDA #$0A BB5B- 8D ED B7 STA $B7ED BB5E- D0 05 BNE $BB65 ... BB65- A9 00 LDA #$00 BB67- 8D EC B7 STA $B7EC BB6A- 8D F0 B7 STA $B7F0 BB6D- A9 40 LDA #$40 BB6F- 8D F1 B7 STA $B7F1 BB72- A9 01 LDA #$01 BB74- 8D F4 B7 STA $B7F4 BB77- 8D F8 B7 STA $B7F8 BB7A- 8D EA B7 STA $B7EA BB7D- 8E E9 B7 STX $B7E9 BB80- 8E F7 B7 STX $B7F7 ; more RWTS fiddling, so sector reads ; save raw nibble data in $6C00 range BB83- A0 6C LDY #$6C BB85- 8C 10 B9 STY $B910 BB88- 8C CE B8 STY $B8CE BB8B- 8C D2 B8 STY $B8D2 BB8E- 88 DEY BB8F- 8C 21 B9 STY $B921 ; another sector read, with modified ; RWTS BB92- 20 E7 BB JSR $BBE7 ; copy the raw nibble data elsewhere BB95- A0 55 LDY #$55 BB97- B9 00 6C LDA $6C00,Y BB9A- 99 00 5C STA $5C00,Y BB9D- 88 DEY BB9E- 10 F7 BPL $BB97 BBA0- AD 02 6B LDA $6B02 BBA3- 85 06 STA $06 ; another sector read BBA5- 20 E7 BB JSR $BBE7 BBA8- AD 02 6B LDA $6B02 BBAB- 85 07 STA $07 BBAD- 20 E7 BB JSR $BBE7 BBB0- AD 02 6B LDA $6B02 BBB3- 85 08 STA $08 ; compare this read's nibble data to ; the previous read's nibble data BBB5- A0 55 LDY #$55 BBB7- B9 00 6C LDA $6C00,Y BBBA- D9 00 5C CMP $5C00,Y BBBD- D0 2F BNE $BBEE BBBF- 88 DEY BBC0- 10 F5 BPL $BBB7 ; some more comparisons, just because BBC2- A5 06 LDA $06 BBC4- C5 07 CMP $07 BBC6- D0 04 BNE $BBCC BBC8- C5 08 CMP $08 BBCA- F0 17 BEQ $BBE3 ; success path is here -- ; first, restore the RWTS code BBCC- A9 38 LDA #$38 BBCE- 8D 42 B9 STA $B942 BBD1- A0 BC LDY #$BC BBD3- 8C 10 B9 STY $B910 BBD6- 8C CE B8 STY $B8CE BBD9- 8C D2 B8 STY $B8D2 BBDC- 88 DEY BBDD- 8C 21 B9 STY $B921 ; then continue with boot1 as normal BBE0- 4C 00 B7 JMP $B700 BBE3- 4C 54 BB JMP $BB54 ... BBE7- A9 B7 LDA #$B7 BBE9- A0 E8 LDY #$E8 BBEB- 4C B5 B7 JMP $B7B5 ; failure path is here BBEE- A2 B3 LDX #$B3 BBF0- 20 58 FC JSR $FC58 BBF3- 20 2D FF JSR $FF2D BBF6- 8E 03 04 STX $0403 BBF9- 4C 5B B7 JMP $B75B The important takeaway here is that there don't appear to be any long-term side effects to this copy protection. If it succeeds, it restores everything that it modified (in the RWTS code), then it just jumps to $B700 to start the boot1 phase. But that's it; nothing else seems to rely on some magic number that it pulls from the raw nibbles or anything. It doesn't decrypt anything. It doesn't even clear the carry flag. With that knowledge, I can safely ignore it and focus on getting the disk decrypted and into a standard format, using Advanced Demuffin and the "RWTS" file that my AUTOTRACE1 program saved. [S6,D1=my work disk] ]PR#6 ]BRUN ADVANCED DEMUFFIN 1.1 --> LOAD NEW RWTS MODULE At $B8, load "RWTS" from D1 [S6,D1=original disk] [S6,D2=blank disk] --> FORMAT TARGET DISK ...grind grind grind... --> CONVERT DISK This disk is 16 sectors, and the default options (copy the entire disk, all tracks, all sectors) don't need to be changed unless something goes horribly wrong. --v-- ADVANCED DEMUFFIN 1.1 - COPYRIGHT 1983 WRITTEN BY THE STACK -CORRUPT COMPUTING =======PRESS ANY KEY TO CONTINUE======= TRK:................................... +.5: 0123456789ABCDEF0123456789ABCDEF012 SC0:R.................................. SC1:R.................................. SC2:R.................................. SC3:R.................................. SC4:R.................................. SC5:R.................................. SC6:R.................................. SC7:R.................................. SC8:R.................................. SC9:R.................................. SCA:................................... SCB:................................... SCC:................................... SCD:................................... SCE:................................... SCF:................................... ======================================= 16 SC $00,$00 TO $22,$0F BY $01 TO DRV2 --^-- Well, the disk's own RWTS can't read the boot1 code on track 0 (sectors 0-9), but that's OK. I captured that separately (in the "BOOT1" file), and I can replace it manually if I need to. Everything else appears to have gone as well as could be expected. The real question is... did it work? Was copying the disk with its own RWTS enough to decrypt the data? Or am I still left with garbage? [S6D1=demuffin'd copy] [S5D1=my work disk] ]PR#5 ... ]CATALOG,S6,D1 C1983 DSR^C#254 026 FREE A 002 HELLO *B 009 ]SMALL FONT *B 022 SCROLL MAP.PAK *B 011 MAX.ANMGRF *B 004 MR LIGHT.PAK *B 012 MAP12.PAK *B 008 MAP13.PAK *B 006 MAP14.PAK *B 011 MAP15.PAK T 006 PLAYER NAMES *B 006 MAP11.PAK *B 027 PLANE.ANMGRF *B 005 PEOPLE.ANMGRF *B 011 GAUGE.PAK *B 003 CORNER.SHAPE *B 009 MAP21.PAK *B 010 MAP22.PAK *B 008 MAP23.PAK *B 010 MAP24.PAK *B 009 MAP25.PAK *B 009 MAP26.PAK *B 006 MAP31.PAK *B 009 MAP32.PAK *B 008 MAP33.PAK *B 011 MAP34.PAK *B 008 MAP35.PAK *B 009 MAP36.PAK *B 008 MAP37.PAK *B 007 MAX *B 010 GROLIER.ANMGRF *B 009 AIRPORT.PAK *B 012 ]LARGE FONT *B 006 QUEST11.TXT *B 008 INTRO1.TXT *B 007 INTRO2.TXT *B 004 STANDARD.TXT *B 005 QUEST12.TXT *B 004 QUEST13.TXT *B 005 QUEST14.TXT *B 005 QUEST15.TXT *B 005 QUEST21.TXT *B 005 QUEST22.TXT *B 004 QUEST23.TXT *B 005 QUEST24.TXT *B 004 QUEST25.TXT *B 005 QUEST26.TXT *B 004 QUEST31.TXT *B 005 QUEST32.TXT *B 005 QUEST33.TXT *B 004 QUEST34.TXT *B 005 QUEST35.TXT *B 005 QUEST36.TXT *B 005 QUEST37.TXT *B 009 THIEF.TXT *B 009 EXTRA$$$.TXT *A 052 GAMEH.BAS ]RUN HELLO Good news, everyone! The game loads and runs without complaint. All further disk access is done through standard DOS functions. Now to make the disk be able to read itself (remember, it still has the original RWTS on it)... Using Copy ][+, I can "copy DOS" from a freshly initialized disk onto the demuffin'd copy. This function of Copy ][+ just sector-copies tracks 0-2 from one disk to another, but it's easier than setting that up manually in some other copy program. Copy ][+ --> COPY --> DOS --> from slot 6, drive 2 --> to slot 6, drive 1 [S6D1=demuffin'd copy] [S6D2=newly formatted DOS 3.3 disk] ...read read read... ...write write write... Quod erat liberandum. --------------------------------------- A 4am crack No. 65 -------------------EOF-----------------