------------Water in the Air----------- A 4am crack 2014-06-14 --------------------------------------- "Water in the Air" is a 1985 educational program programmed by Frank R. Salamon and distributed by E.M.E. (Educational Materials and Equipment Corporation). [Note: option #2 on the main menu asks for a quiz disk, which I do not have. If you have it or find it, please use this write-up as a guide to preserve it as well.] The original disk is uncopyable by COPYA or Locksmith Fast Disk Backup. EDD 4 bit copy gives no read errors, but the copy just grinds a few times and reboots. Some manual inspection with the Copy ][+ nibble editor reveals that every odd track has a non-standard address prologue: Track | Address | Data ------+----------+---------- $00 | D5 AA 96 | D5 AA AD $01 | D4 AA 96 | D5 AA AD $02 | D5 AA 96 | D5 AA AD $03 | D4 AA 96 | D5 AA AD $04 | D5 AA 96 | D5 AA AD $05 | D4 AA 96 | D5 AA AD &. The address epilogue also varies from track to track. The data prologue and epilogue appear to be standard. This is too complicated for a tool like Super Demuffin, which assumes the same structure on each track. But based on the information I've gathered so far, it shouldn't be difficult to capture the RWTS and load it into Advanced Demuffin. [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 much 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 ... I've seen a lot of boot0 code from different copy-protected (and not copy-protected) disks, so I've kind of developed a sense of what a "normal" boot looks like. I can look at almost- but-not-quite normal boot0 code and hone in pretty quickly on the part that's unusual. Maybe it calls a subroutine that isn't normally called, or it does things in a strange order, or it jumps to an unusual place after loading the boot1 code. 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- 4C 00 BB JMP $BB00 Highly suspect. I definitely want to see what evil lurks at $BB00. 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 $BB00 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 code at $BB00), 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). The only reason it didn't run already is that the instruction at $084A is non- standard. But the boot0 code is close enough to standard that AUTOTRACE1 should be able to patch it. (I mean, we *are* patching assembly language code here. There's a very low tolerance for error.) ]BRUN AUTOTRACE1 ...reboots slot 6... ...reboots slot 5... SAVING BOOT1 SAVING RWTS Well, that worked flawlessly. Not only did I get the rest of the boot1 code, but the RWTS is apparently in as standard location too. So before I investigate the nibble check at $BB00, I'm going to load that RWTS into Advanced Demuffin to convert the disk to a standard format. Advanced Demuffin will only load RWTS files from a drive in slot 6, which is annoying since mine is in slot 5. Note to self: patch that someday. In the meantime, I'm swapping floppy disks like some kind of 20th century peasant. [S6,D1=my work disk] ]PR#6 ]BRUN ADVANCED DEMUFFIN 1.1 --> LOAD NEW RWTS MODULE At $B8, load "RWTS" from drive 1 [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. ADVANCED DEMUFFIN 1.1 - COPYRIGHT 1983 WRITTEN BY THE STACK -CORRUPT COMPUTING =======PRESS ANY KEY TO CONTINUE======= TRK:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR +R5: 0123456789ABCDEF0123456789ABCDEF012 SC0:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC1:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC2:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC3:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC4:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC5:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC6:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC7:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC8:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SC9:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCA:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCB:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCC:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCD:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCE:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR SCF:RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR ======================================= 16 SC $00,$00 TO $22,$0F BY $01 TO DRV2 Those "R" flags? Read errors. Every track, every sector. Remember when I said the default options don't need to be changed unless something goes horribly wrong? (Seriously, I just said that, like, a minute ago.) This is what "horribly wrong" looks like. The RWTS on this disk can't read... the disk. Seriously, RWTS, you had one job... Let's back up. [S6,D1=my work disk] ]PR#5 ... ]BLOAD BOOT1,A$2600 ]CALL -151 ; disconnect DOS *FE89G FE93G *B600<2600.2FFFM *BB00L ; set reset vector BB00- A9 5D LDA #$5D BB02- 8D F2 03 STA $03F2 BB05- A9 B7 LDA #$B7 BB07- EA NOP BB08- 8D F3 03 STA $03F3 BB0B- 49 A5 EOR #$A5 BB0D- 8D F4 03 STA $03F4 ; oh, this is probably important BB10- A9 AA LDA #$AA BB12- 85 31 STA $31 ; relatively harmless initialization, ; then it jumps right back to $B700 BB14- AD E9 B7 LDA $B7E9 BB17- 4A LSR BB18- 4A LSR BB19- 4A LSR BB1A- 4A LSR BB1B- 09 C0 ORA #$C0 BB1D- 8D 95 BA STA $BA95 BB20- 4C 00 B7 JMP $B700 Hmm. I was sure that was going to be a nibble check. But it's not. But I'm guessing that it's still important, although it's not obvious why. But I think I've seen something like this on other disks. Let me see if I'm right... *B92FL ; check for epilogue bytes (part of the ; standard DOS 3.3 RWTS) B92F- BD 8C C0 LDA $C08C,X B932- 10 FB BPL $B92F B934- C9 DE CMP #$DE B936- D0 0A BNE $B942 B938- EA NOP B939- BD 8C C0 LDA $C08C,X B93C- 10 FB BPL $B939 ; there it is! B93E- C5 31 CMP $31 B940- F0 5C BEQ $B99E B942- 38 SEC B943- 60 RTS This RWTS is doing something sneaky to make my job harder: it's putting one of the epilogue bytes into a zero page address, then reading the value from there instead of using a constant. Why? Because f--- you, that's why. Because it makes the extracted RWTS useless without initializing the magic zero page location with the right magic number. Automated RWTS extraction programs wouldn't find this (as I just saw when Advanced Demuffin failed to read the original disk with the RWTS from the original disk). Everything is a countermeasure to something. This calls for an IOB module. What's an IOB module? Well, the author of Advanced Demuffin anticipated that he couldn't anticipate everything, so he made the program extensible. Quoting from the Advanced Demuffin softdocs (included on my work disk): --v-- An IOB module is an interface for the source RWTS. Advanced Demuffin uses the IOB module to set up the IOB table and jump to RWTS. The IOB module is stored from $1400-$14FB. When Advanced Demuffin loads in a IOB module, it reads the first sector of the file off the track-sector list and stores it at $13FC-$14FB. When Advanced Demuffin wants to read a sector it JSRs to the IOB module with the phase number, sector number, and the page number stored in the A, Y and X registers respectively. Since the source drive always has to be drive one, Advanced Demuffin can make the IOB module very compact. After it gets the page,track and sector Advanced Demuffin sets up the IOB for RWTS using this infor- mation, and JMPs to RWTS. (It jumps instead of JSRing, because it lets the RWTS do the RTS.) Here is a list of the IOB module that is built in to Advanced Demuffin: ; Convert phase # to track # 1400- 4A LSR ; Store track number 1401- 8D 22 0F STA $0F22 ; Store sector number 1404- 8C 23 0F STY $0F23 ; Store page number ; [note: original docs have incorrect ; hex opcode on this line] 1407- 8E 27 0F STX $0F27 140A- A9 01 LDA #$01 ; Store the drive number 140C- 8D 20 0F STA $0F20 ; Store the read code 140F- 8D 2A 0F STA $0F2A ; With high byte of IOB 1412- A9 0F LDA #$0F ; With low byte of IOB 1414- A0 1E LDY #$1E ; Goto RWTS 1416- 4C 00 BD JMP $BD00 --^-- Basically, Advanced Demuffin only knows how to call a custom RWTS if it 1. is loaded at $B800..$BFFF 2. uses a standard RWTS parameter table 3. has an entry point at $BD00 that takes the address of the parameter tables in A and Y 4. doesn't require initialization As it turns out, that covers a *lot* of copy protected disks, but it doesn't cover this one because the RWTS relies on the value of zero page $31. So, let's make an IOB module. ]CALL -151 ; Most of this is identical to the ; standard IOB module that comes with ; Advanced Demuffin (explained above). 1400- 4A LSR 1401- 8D 22 0F STA $0F22 1404- 8C 23 0F STY $0F23 1407- 8E 27 0F STX $0F27 140A- A9 01 LDA #$01 140C- 8D 20 0F STA $0F20 140F- 8D 2A 0F STA $0F2A ; initialize the magic zero page value 1412- A9 AA LDA #$AA 1414- 85 31 STA $31 ; get the address of the RWTS parameter ; table at $0F1E and call the RWTS 1416- A9 0F LDA #$0F 1418- A0 1E LDY #$1E 141A- 4C 00 BD JMP $BD00 *BSAVE IOB,A$1400,L$1D Now let's tell Advanced Demuffin to use this custom IOB as well as the RWTS we captured from the original disk. [S6,D1=my work disk] ]BRUN ADVANCED DEMUFFIN 1.1 --> LOAD NEW RWTS MODULE At $38, load "RWTS" from D1 --> LOAD NEW IOB MODULE load "IOB" from D1 [S6,D1=original disk] [S6,D2=blank disk] --> CONVERT DISK --> CHANGE DEFAULT VALUES? N 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 (again). ADVANCED DEMUFFIN 1.1 - COPYRIGHT 1983 WRITTEN BY THE STACK -CORRUPT COMPUTING =======PRESS ANY KEY TO CONTINUE======= TRK:................................... +.5: 0123456789ABCDEF0123456789ABCDEF012 SC0:................................... SC1:................................... SC2:................................... SC3:................................... SC4:................................... SC5:................................... SC6:................................... SC7:................................... SC8:................................... SC9:................................... SCA:................................... SCB:................................... SCC:................................... SCD:................................... SCE:................................... SCF:................................... ======================================= 16 SC $00,$00 TO $22,$0F BY $01 TO DRV2 Hooray! IOB saves the day! [S6,D1=my work disk] [S6,D2=fully demuffin'd copy] ]PR#6 ... ]CATALOG,S6,D2 C1983 DSR^C#254 136 FREE A 002 HELLO B 018 EME-ESS LOGO A 005 WATER IN THE AIR B 002 WA ROUTINES B 029 WA MENUS B 026 WA TITLES A 004 EVCO B 023 EVCO REVIEW#1 B 092 EVCO REVIEW#2 A 004 LH B 009 LH REVIEW#1 B 076 LH REVIEW#2 A 003 SWV B 067 SWV REVIEW ]RUN HELLO Success! The program loads and runs without complaint. It appears that, once DOS is loaded, all further disk access is done through DOS commands. (It even runs from drive 2.) 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 DOS 3.3 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 [S6,D1=demuffin'd copy] [S6,D2=newly formatted DOS 3.3 disk] ...read read read... ...write write write... Quod erat liberandum. --------------------------------------- A 4am crack No. 75 ------------------EOF------------------