--------------Zoom Grafix-------------- A 4am crack 2014-12-08 -------------------. updated 2019-04-08 |___________________ "Zoom Grafix" is a 1982 graphics printing program written by Dav Holle and distributed by Phoenix Software. My copy says it's the "second edition." Comments within the BASIC programs themselves claim this revision is from "05-MAY-83". COPYA fails miserably and immediately. EDD 4 bit copy works, and the copy boots and runs without complaint. This tells me that there is some structural protection (i.e. data is stored on the disk in a non-standard way) but probably no secondary protection (e.g. an assembly language routine that executes during the boot process to determine whether it's booting from the original disk). The original disk appears to boot a modified DOS 3.3. Listening to the disk drive, it quickly moves out to track 2, then back to track 1, then track 0, then swings out to track $11 to read the disk catalog and load the startup program (HELLO or similar). You can hear a lot just by listening. Turning to my trusty Disk Fixer sector editor, I go to "Input/Output Control" (press "O") and set CHECKSUM ENABLED = NO. This option ignores checksum bytes and epilogue sequences -- as long as the address and data prologue are standard ("D5 AA 96" and "D5 AA AD", respectively), this will allow me to read each sector. And lo and behold, it works! I can read the data from every sector on every track. Given the (relatively) weak structural protection, I used to turn to the DOS 3.3 master disk, patch the RWTS to ignore checksums and epilogue bytes (changing $B942 from "SEC" to "CLC"), and run COPYA. Then, one fine day, and completely by accident, I came across an original disk with a bad sector. I suppose this shouldn't surprise me. These floppies are decades old by now; it's amazing any of them work at all. The point is, I shouldn't be using tools that ignore potentially serious read errors. So no more COPYA+B942:18 patch. From now on, it's Super Demuffin or Advanced Demuffin to convert disks to a standard format. Let's see if AUTOTRACE can capture the RWTS from the original disk. If not, I'll have to resort to manual investigation. [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 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, this 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"), there's a good chance I'll be able to use a tool called Advanced Demuffin (written in 1983 by The Stack) to convert the disk from whatever weird format it uses to store its sector data into a standard disk readable by unprotected DOS 3.3 disks or any other third-party tools. In this case, 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". If anything looks fishy or non- standard, AUTOTRACE just stops, and I have to check the files it saved so far to determine why. But in this case, it ran all the way through, automatically capturing BOOT0, BOOT1, and RWTS files. Now I can use Advanced Demuffin to convert the disk to a standard format. It uses the disk's own RWTS to read the original (stored in the RWTS file, accessed via the IOB module), then a standard DOS 3.3-compatible RWTS to write out the data, sector by sector. [S6,D1=original disk] [S6,D2=blank disk] [S5,D1=my work disk] ]PR#5 ... ]BRUN ADVANCED DEMUFFIN 1.5 [press "5" to switch to slot 5] [press "R" to load a new RWTS module] --> At $B8, load "RWTS" from drive 1 [press "6" to switch to slot 6] [press "C" to 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.5 (C) 1983, 2014 ORIGINAL BY THE STACK UPDATES BY 4AM =======PRESS ANY KEY TO CONTINUE======= TRK:................................... +.5: 0123456789ABCDEF0123456789ABCDEF012 SC0:................................... SC1:................................... SC2:................................... SC3:................................... SC4:................................... SC5:................................... SC6:................................... SC7:................................... SC8:................................... SC9:................................... SCA:................................... SCB:................................... SCC:................................... SCD:................................... SCE:................................... SCF:................................... ======================================= 16SC $00,$00-$22,$0F BY1.0 S6,D1->S6,D2 --^-- The disk's own RWTS gave no read errors on any track. This is the power and the genius of Advanced Demuffin. Every disk must be able to read itself. So, let it read itself, then capture the data and write it out in a standard format. ]PR#5 ... ]CATALOG,S6,D2 C1983 DSR^C#254 000 FREE A 000 GRAFIX A 000 GRAFIX PART ][ A 000 GRAFIX SET-UP B 000 GRAFIX.INFO B 000 GRAFIX.OBJ B 033 PIC.APPLE B 033 PIC.BARBRA B 033 PIC.FLUTTER B 033 PIC.FRED B 033 PIC.GRAPH B 033 PIC.GREMLIN B 033 PIC.GRID B 033 PIC.HOPPY B 033 PIC.LADY B 033 PIC.PHOENIX B 033 PIC.WINDY B 033 PIC.ZOOM I 000 APPLESOFT Hmm, nothing named HELLO, but GRAFIX might be the autostart program. But the 000 file size tells me something funky is going on. ]RUN GRAFIX ...hangs. Rebooting from the DOS 3.3 master disk fares no better. OK, no big deal. It just means I need to deal with the original DOS on the disk instead of replacing it. Booting the demuffin'd disk directly just grinds endlessly, because it still has the original RWTS on it. That is, it still assumes that the data on the disk is stored in a non-standard format. But that's not true anymore, because Advanced Demuffin just normalized the disk format. So I need to patch the RWTS on my copy so it can read itself. A lot of disks need this sort of post- demuffin patching, and I got tired of doing it manually, so I wrote a program to do it for me. It is called, unsurprisingly, Post-Demuffin Patcher. It prompts you to select a slot and drive, then reads the demuffin'd disk, checks for a modified DOS 3.3-shaped RWTS, and applies the necessary patches so the disk can read itself. (It can also detect and bypass some nibble checks.) I've included a copy of Post- Demuffin Patcher on my work disk; the full source code is currently available at . [S6,D1=demuffin'd copy] ]PR#5 ... ]BRUN PDP T00,S03,$91 change DD to DE This is the actual output of the program. Post-Demuffin Patcher prints out the changes it is going to make before it writes them to the disk. It looks like the epilogue bytes (normally "DE AA") were changed to "DD AA". PDP had no problem switching them back. ]PR#6 Success! The disk boots and runs with no complaint. There doesn't appear to be any further protection. Hooray for automation. Quod erat liberand one more thing... ~ Oops This crack is incomplete; there is more copy protection, which I missed the first time around. The protection is very subtle, but unmistakeable: the setup program will not save your setup to disk. Instead, it goes back to the previous screen (without saving). To the things themselves! [S6,D1=incomplete crack] [S5,D1=my work disk] ]PR#5 ... ]CATALOG,S6,D1 C1983 DSR^C#254 000 FREE A 000 GRAFIX A 000 GRAFIX PART ][ A 000 GRAFIX SET-UP B 000 GRAFIX.INFO B 000 GRAFIX.OBJ B 033 PIC.APPLE B 033 PIC.BARBRA B 033 PIC.FLUTTER B 033 PIC.FRED B 033 PIC.GRAPH B 033 PIC.GREMLIN B 033 PIC.GRID B 033 PIC.HOPPY B 033 PIC.LADY B 033 PIC.PHOENIX B 033 PIC.WINDY B 033 PIC.ZOOM I 000 APPLESOFT "GRAFIX SET-UP" certainly sounds promising for a protection that affects the setup program. ]LOAD GRAFIX SET-UP ]LIST 100 ONERR GOTO 595: REM 2MAY83 105 DR = 36864: HIMEM: DR:CN = FRE (0): DIM CA$(40),CA(40),PR$( 40),PR(40,1):BE = 65338:CL = 64578:BO = 976:KB = 49152:KS = 49168:Q$ = CHR$ (34):ET$ = CHR$ (3):LM = PEEK (KB - 2058):ES$ = CHR$ (27):CR$ = CHR$ (13):BS$ = CHR$ (8):N A$ = CHR$ (21): IF PEEK (1 030) > 153 THEN ! 110 VTAB 22: PRINT : PRINT "CLO SE": PRINT "BLOADGRAFIX.OBJ" : PRINT "BLOADGRAFIX.INFO":C N = DR + 9:N0 = DR + 10:LO = PEEK (DR + 6) + PEEK (DR + 7) * 256:NC = - 1 ... ; this is where the setup program loops ; back to, instead of saving the ; configuration to disk 315 HOME : HTAB 16: INVERSE : PRINT "NOTICE": PRINT " TH IS DELAY IS FOR T HE PROTECTION OF YOUR PRINTE R. ": NORMAL : PRINT " YOU MAY WANT TO INCREASE IT": PRINT "WHEN PRINTING LARGE DARK AR EAS. 320 PRINT " DEFAULT END OF LINE DELAY, IN": PRINT "FOURTHS O F A SECOND (0..255) ? ";:N = 20: GOSUB 470: IF N < 0 THEN 290 325 IF N > 255 THEN CALL BE: GOTO 315 ... ; this is where it asks the question ; about whether to save to disk 405 INVERSE : PRINT " YES";: NORMAL : PRINT " TO MAKE THIS SET-U P PERMANENT ": PRINT " ";: INVERSE : PRINT "NO";: NORMAL : PRINT " TO TRY OUT THIS SET-UP,": PRINT " WITHOUT MAKING IT PERMA NENT 410 INVERSE : PRINT " <--";: NORMAL : PRINT " BACKSPACE TO MAKE CHANGES 415 PRINT " SAVE THIS SET-UP TO DISK";:YE = 0: GOSUB 550: IF YE < LM AND NOT PR THEN 130 420 IF YE < LM AND PEEK (DR + 16) THEN 315 425 IF YE < LM THEN 335 ; my non-working copy never gets this ; far 430 ONERR GOTO 450 435 IF YE THEN HOME : VTAB 9: POKE 47147 - LM,134: PRINT "TO CH ANGE THE SET-UP LATER,": PRINT " PRESS ";: INVERSE : PRINT " ESC";: NORMAL : PRINT " WHIL E BOOTING ZOOM GRAFIX.": PRINT "UNLOCKGRAFIX.OBJ": PRINT "B SAVEGRAFIX.OBJ,A"DR",L"LO + PEEK (DR + 8) - DR: ONERR GOTO 590 440 IF NOT PR THEN 130 Given the behavior, it appears that the IF statement on line 420 is failing: 420 IF YE < LM AND PEEK (DR + 16) THEN 315 "YE" is set by the subroutine at 550. ]LIST550, 550 PRINT "? (Y/N) N"BS$;: IF Y ES THEN PRINT "Y"BS$; 555 POKE KS,0: GET IN$: IF IN$ = ET$ OR IN$ = ES$ THEN ! 560 IF IN$ = CR$ OR IN$ = NA$ THEN 580 565 IF IN$ = BS$ THEN YE = - 1 : PRINT : RETURN 570 IF IN$ < > "Y" AND IN$ < > "N" THEN CALL BE: GOTO 555 575 YE = IN$ = "Y" 580 IF YE > LM THEN PRINT "YES ": RETURN 585 PRINT "NO": RETURN There's a bunch of stuff for handling going back (BS$ is CHR$(8), backspace) or beeping if you don't enter "Y" or "N", but the meat of it is on line 575: if you typed "Y" then YE = 1, otherwise YE = 0. Then there's this: 580 IF YE > LM THEN PRINT "YES ": RETURN What is LM? Way back on line 105, in the middle of the big mess-o-variables, we see this: 105 ... KB = 49152 LM = PEEK (KB - 2058) 49152 is $C000; 49152 - 2058 = 47094, which is $B7F6. That's... part of the DOS 3.3 RWTS parameter table. To be precise, it's the "volume number found" parameter, which is set after each RWTS call. What does that have to do with keyboard input? The answer: absolutely nothing, but it has everything to do with a devious form of secondary protection. You see, on the original disk, the disk volume number was 0. On my copy, it's 254 (the standard volume number). Thanks to Applesoft's loose typing, YE is (the number) 1 because it was set to what we would now call a boolean value TRUE. But treated as the number 1, it's now being compared to LM, which is 254. 1 is not, in fact, greater than 254, so this routine falls through and assumes I did not press "Y" for "YES". YE is still 1, though. But once we return to the caller, we check it again against the mysterious LM variable (still 254), on line 420: 420 IF YE < LM AND PEEK (DR + 16) THEN 315 1 is less than 254, and the PEEK ends up being non-zero, so we loop back to line 315 and go back to a previous configuration step. Because f--- you, that's why. The solution is to set LM to 0 somehow, to mirror the behavior of the original disk. There are a number of ways to do this. The least invasive way -- albeit not the most straightforward -- would be to change the offset from KB to change the memory location from which we initialize the LM variable. $B7F9 is unused and pre-initialized to 0, and just 3 bytes away from $B7F6. Instead of LM = PEEK(KB - 2058), I could change it to PEEK(KB - 2055) and be guaranteed to get a 0 value. Turning to my trusty Disk Fixer sector editor, pressing "D" for a directory and following the "GRAFIX SET-UP" file, I find this on track 5: T05,S03,$96: 38 -> 35 But wait! There's more! On a lark, I searched the disk for the byte sequence "32 30 35 38" (the number 2058 as it would be stored in Applesoft) and found that "GRAFIX PART ][" contains exactly the same trick! 190 X0 = 0:Y0 = 0:X1 = 279:Y1 = 191:DH = 1:DW = 1:CE = 1:NE = 1:LM = PEEK (KB - 2058):PT = ^^^^^^^^^^^^^^^^^^^^^^ PEEK (DR + 12):DL = PEEK ( DR + 14):PW = 8:MW = PW:DP = 72:DS = 6:WU$ = " INCHES": GOSUB 1750 They even use the same variable names! Let's patch that one too, the same way: T04,S0C,$D5: 38 -> 35 ]PR#6 ...works (I think)... ~ Further Oops Good news, everyone! It's 2019 and I'm still finding new and exciting details about this copy protection. This update comes courtesy of Passport, an automated disk cracking and verification program that I've been developing for the past few years since I first attempted to crack this lovely program. While investigating the possibility of automating the secondary disk volume check I detailed above, I discovered an unrelated RWTS patch that this disk shares with some other disks from other companies. (Many protection schemes were used by multiple companies who chose to outsource this highly technical skill.) While writing the printer configuration to your protected master disk, the RWTS on this disk jumps to a special routine at $B6B8 to burn a few extra CPU cycles after the data field prologue: --v-- T00,S02 ----------- DISASSEMBLY MODE ---------- 0048:A0 04 LDY #$04 004A:48 PHA 004B:68 PLA 004C:20 B9 B8 JSR $B8B9 004F:88 DEY 0050:D0 F8 BNE $004A 0052:A9 D5 LDA #$D5 0054:20 B8 B8 JSR $B8B8 0057:A9 AA LDA #$AA 0059:20 B8 B8 JSR $B8B8 005C:A9 AD LDA #$AD 005E:4C B8 B6 JMP $B6B8 <-- ! --^-- Here is the "extra" code at $B6B8: --v-- T00,S00 ----------- DISASSEMBLY MODE ---------- 00B8:AC B7 F6 LDY $F6B7 00BB:C1 EA CMP ($EA,X) 00BD:EA NOP 00BE:9D 8D C0 STA $C08D,X 00C1:1D 8C C0 ORA $C08C,X 00C4:A9 00 LDA #$00 00C6:A0 56 LDY #$56 00C8:EA NOP 00C9:4C 69 B8 JMP $B869 --^-- At the time (2016), most emulators were not emulating the Disk II correctly, so this extra routine made no difference. (I would have caught it if I had tested on real hardware, of course. Which, to be perfectly honest, I rarely do. It was 2016, not 1986.) On the bright side, emulators have improved, and at least some of them surface the fact that the disk write fails due to this extra routine. Even better, I added support for the secondary protection check that sets a variable to the last found disk volume and later fails if it's not 0. All of which is a roundabout way of saying that I have completely recracked this disk with Passport, and it looks like this: --v-- Reading from S6,D1 T00,S00 Found DOS 3.3 bootloader Using disk's own RWTS Writing to RAM disk T13,S0E Disk requires volume number 000 T13,S0E,$97: 38 -> 35 T10,S0C Disk requires volume number 000 T10,S0C,$D6: 38 -> 35 T02,S02 Volume name is DISK VOLUME 000 T00,S03,$91: DD -> DE T00,S03 RWTS accepts $D4 or $D5 for the first address prologue nibble. T00,S02,$5E: 4CB8B6 -> 20B8B8 Writing to S6,D2 Crack complete. Press any key --^-- More information and source code is available at https://archive.org/details/Passport4am Quod erat liberandum. ~ Changelog 2019-04-08 - recrack everything with Passport to catch additional RWTS modifications 2016-10-04 - patch secondary protection [thanks qkumba] --------------------------------------- A 4am crack No. 175 ------------------EOF------------------