-------------Un Dia Tipico------------- A 4am crack 2014-07-21 --------------------------------------- "Un Dia Tipico" is a 1985 educational game distributed by D.C. Heath & Co. Despite the name, the program is primarily in English. The original program comes on three single-sided disks. Disk 1 boots, loads DOS, displays a (slightly delayed) BASIC prompt, then runs a HELLO program of some sort. Disk 2 and 3 simply boot to a text message saying "INSERT DISK 1 AND PRESS ANY KEY". COPYA fails miserably and immediately with a disk read error. EDD 4 bit copy gives no read errors, but the copy grinds the disk drive on boot and never gets any further. Turning to my trusty Copy ][+ sector editor, I can read track 0 and every even track without any problem. But the odd-numbered tracks are opaque. If I switch to the nibble editor, it appears that the odd-numbered tracks use a non-standard address prologue, "D4 AA 96" instead of the usual "D5 AA 96". [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 ... 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. --v-- 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 $B8, 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). --v-- 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 106 FREE El Mundo Hispanico *A 002 HELLO A 013 HELLO.A *B 002 HEATH LOGO UNPACK *B 009 HEATH LOGO PACKED *B 007 CAP 20.6.OBJ-T *B 005 PANEL2.B *B 002 TILES.B *B 016 HRCG.SP *B 006 UPPERCASE(B *B 005 LOWERCASE(B A 028 MENU B 031 INTRO ART.B *B 014 CREDITS.B *B 002 STAR.S *A 007 TITLE *A 042 ACTIVITY2 T 002 MAKE TEXT B 009 KIDSROOM.B B 009 DRESSPACO.B B 016 GRACIELA.B B 014 PACOWAKES.B B 028 BATHROOM.B *A 033 ACTIVITY1 B 010 BIGSINK.B B 002 RARROW-DOT.S *A 047 ACT1QUIZ *A 010 CONTINUE *B 003 NUMBER(B ]RUN HELLO The game loads and runs without complaint. All further disk access is done through standard DOS functions. (It even runs from drive 2!) There doesn't appear to be any kind of nibble check or other copy protection, beyond the custom DOS. This is weird. I put the demuffin'd copy in drive 1 and try booting it... and it works! But I haven't touched the RWTS; it's still the original RWTS that expects a modified address prologue on every other track. So there's no way this RWTS can read a disk that uses standard address prologue on every track. How is that possible? Here's how: the original RWTS doesn't actually check for a specific address prologue. It does some bit math on the first byte in the sequence and allows a certain result. [S6,D1=my work disk] ]PR#6 ... ]BLOAD BOOT1,A$2600 ]CALL -151 *FE89G FE93G *B600<2600.2FFFM *B94FL ; first byte does bit math (matches ; either "D4" or "D5") B94F- BD 8C C0 LDA $C08C,X B952- 10 FB BPL $B94F B954- 4A LSR B955- C9 6A CMP #$6A B957- D0 EF BNE $B948 ; second byte is in zero page (grr) B959- BD 8C C0 LDA $C08C,X B95C- 10 FB BPL $B959 B95E- C5 31 CMP $31 B960- D0 F2 BNE $B954 B962- A0 03 LDY #$03 ; third byte is just a constant B964- BD 8C C0 LDA $C08C,X B967- 10 FB BPL $B964 B969- C9 96 CMP #$96 B96B- D0 E7 BNE $B954 Disks 2 and 3 have no RWTS, but they use the same modified disk structure as disk 1, and the RWTS file I captured from disk 1 also works to convert disks 2 and 3. Quod erat liberandum. --------------------------------------- A 4am crack No. 87 ------------------EOF------------------