-----------Practical Grammar----------- A 4am crack 2015-01-21 -------------------. updated 2015-12-21 |___________________ Name: Practical Grammar Genre: educational Year: 1988 Publisher: Queue, Inc. OS: DOS 3.3 Media: multiple single-sided 5.25" floppy disks Other versions: none (preserved here for the first time) I have 14 disks numbered 14 through 27. 14. The Tenses of Verbs 15. Verbs - Voice and Mood 16. Agreement of Subject and Verb 17. Prepositional Phrases 18. Compound Sentences 19. Complex Sentences 20. Adverbial Clauses 21. Noun Clauses 22. Participles 23. Gerunds 24. Infinitives 25. Problems in the Use of Infinitives 26. Punctuation Review 27. Comprehensive Grammar Review II I'll start with #14. ~ Chapter 0 In Which Various Automated Tools Fail In Interesting Ways COPYA immediate disk read error Locksmith Fast Disk Backup unable to read any track EDD 4 bit copy (no sync, no count) no errors, but copy grinds on boot Copy ][+ nibble editor modified address prologue "AB BF D5" modified address epilogue "F2 FF FF" --v-- COPY ][ PLUS BIT COPY PROGRAM 8.4 (C) 1982-9 CENTRAL POINT SOFTWARE, INC. ---------------------------------------- TRACK: 02 START: 3636 LENGTH: 10E3 3610: 96 96 96 96 96 96 96 96 VIEW 3618: 96 96 96 96 96 96 96 96 3620: 96 96 DE AA EB FC FE DE ^^^^^^^^ data epilogue 3628: EF FD BD BF FF E5 B5 FF 3630: AA CF EF DF BB FB D5 DB <-3636 3638: AF EB FE AA FF AB BF D5 ^^^^^^^^ address prologue 3640: FF FE AB AA AE AB FA FF ^^^^^ ^^^^^ ^^^^^ ^^^^^ v254 T02 S08 chksm 3648: F2 FF FF FF FB F9 FE FF ^^^^^^^^ address epilogue 3650: FF FF D5 AA AD 9B B3 96 ^^^^^^^^ data prologue ---------------------------------------- A TO ANALYZE DATA ESC TO QUIT ? FOR HELP SCREEN / CHANGE PARMS Q FOR NEXT TRACK SPACE TO RE-READ --^-- Disk Fixer ["O" -> "Input/Output Control"] set Address Prologue to "AB BF D5" set Address Epilogue to "F2 FF FF" T00 looks like a DOS 3.3 RWTS T11 looks like a DOS 3.3 disk catalog T01,S09 -> startup program is "HELLO" Why didn't COPYA work? modified prologue and epilogue Why didn't Locksmith FDB work? modified prologue and epilogue Why didn't my EDD copy work? I don't know. Maybe a nibble check during boot? Next steps: 1. capture RWTS with AUTOTRACE 2. convert disk to standard format with Advanced Demuffin 3. patch RWTS to read demuffin'd disk 4. find the nibble check & bypass it ~ Chapter 1 In Which We Attempt To Use The Original Disk As A Weapon Against Itself [S6,D1=original disk] [S6,D2=blank disk] [S5,D1=my work disk] ]PR#5 ... CAPTURING BOOT0 ]BLOAD BOOT0,A$800 ]CALL -151 *801L . . all normal until... . 084A- 4C F0 08 JMP $08F0 *8F0L 08F0- A9 AA LDA #$AA 08F2- 85 31 STA $31 <-- ? 08F4- A9 00 LDA #$00 08F6- 8D F1 B6 STA $B6F1 08F9- 4C 00 BB JMP $BB00 <-- ! I've seen this before. The RWTS uses zero page $31 to check some byte of the prologue or epilogue. In this case, probably the data epilogue, since the address prologue and epilogue are non- standard. *C500G ; reboot my work disk ... ]RUN 130 ; continue AUTOTRACE CAPTURING BOOT1 SAVING BOOT1 SAVING RWTS (Note to self: update AUTOTRACE so it can trace past a jump to $08F0.) Boot0 jumped to $BB00 (from $08F9), which is probably a nibble check. ]BLOAD BOOT1,A$2600 ]CALL -151 *FE89G FE93G ; disconnect DOS *B600<2600.2FFFM ; move RWTS into place *BB00L BB00- A9 59 LDA #$59 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 BB10- 4C 00 B7 JMP $B700 Hmm, not a nibble check. Just setting the reset vector. Now look at this code to match the data epilogue: *B92FL 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 B93E- C5 31 CMP $31 <-- ! B940- F0 5C BEQ $B99E B942- 38 SEC B943- 60 RTS There's zero page $31, initialized at $08F0 during boot. Solution: an IOB module that Advanced Demuffin calls before calling the original disk's RWTS. (Read the docs on my work disk.) *C500G ... ]CALL -151 ]BLOAD ADVANCED DEMUFFIN 1.5 ; standard Advanced Demuffin setup ; (unchanged) 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 zero page 1412- A9 AA LDA #$AA 1414- 85 31 STA $31 ; call RWTS 1416- A9 0F LDA #$0F 1418- A0 1E LDY #$1E 141A- 4C 00 BD JMP $BD00 *BSAVE IOB $31,A$1400,L$FB *BRUN ADVANCED DEMUFFIN 1.5 ["5" to switch to slot 5] ["R" to load a new RWTS module] --> At $B8, load "RWTS" from drive 1 [press "I" to load a new IOB module] --> load "IOB $31" from drive 1 ["6" to switch to slot 6] ["C" to convert disk] --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 --^-- ]PR#5 ]CATALOG,S6,D2 C1983 DSR^C#254 074 FREE *A 003 HELLO T 002 DN *A 059 TUT *A 025 ACSES B 002 XF1 T 003 SM B 021 L10 B 003 L101 B 019 L15 B 003 L151 B 019 L20 B 003 L201 T 002 TF1 T 002 IF1 T 002 SF1 B 016 L25 B 003 L251 B 019 L30 B 004 L301 B 002 UPFP B 020 L35 B 003 L351 B 018 L40 B 003 L401 B 018 L45 B 004 L451 B 019 L50 B 003 L501 B 014 L55 B 003 L551 *B 002 GS *A 002 BTUT B 024 FP+ B 005 CS I 006 APPLESOFT B 050 FPBASIC ]RUN HELLO ...works... ]PR#6 ...works... Wait, what? ~ Chapter 2 In Which We Angrily Investigate Why We Suddenly Have A Working Copy [S6,D1=mysteriously working copy] [S5,D1=my work disk] ]BLOAD RWTS,A$2800 ]CALL -151 *FE89G FE93G *B800<2800.2FFFM *B944L ; routine to find address prologue B944- A0 FC LDY #$FC B946- 84 26 STY $26 B948- C8 INY B949- D0 04 BNE $B94F B94B- E6 26 INC $26 B94D- F0 F3 BEQ $B942 ; find prologue nibble #1 B94F- BD 8C C0 LDA $C08C,X B952- 10 FB BPL $B94F B954- C9 D5 CMP #$D5 <-- ? B956- D0 F0 BNE $B948 B958- EA NOP I could have sworn the original disk's address prologue was "AB BF D5". ; and again? B959- BD 8C C0 LDA $C08C,X ; Wait, no BPL loop here! It only reads ; the data latch once. B95C- C9 D5 CMP #$D5 ; if data latch is (still) $D5, jump ; right to address field logic B95E- F0 12 BEQ $B972 ; otherwise continue and... look for ; the (standard) prologue nibble #2 B960- BD 8C C0 LDA $C08C,X B963- 10 FB BPL $B960 B965- C9 AA CMP #$AA B967- D0 DF BNE $B948 ; and the standard prologue nibble #3 B969- BD 8C C0 LDA $C08C,X B96C- 10 FB BPL $B969 B96E- C9 96 CMP #$96 B970- D0 D6 BNE $B948 ; decode address field (standard) B972- A0 03 LDY #$03 B974- A9 00 LDA #$00 B976- 85 27 STA $27 B978- BD 8C C0 LDA $C08C,X B97B- 10 FB BPL $B978 B97D- 2A ROL B97E- 85 26 STA $26 B980- BD 8C C0 LDA $C08C,X B983- 10 FB BPL $B980 B985- 25 26 AND $26 B987- 99 2C 00 STA $002C,Y B98A- 45 27 EOR $27 B98C- 88 DEY B98D- 10 E7 BPL $B976 B98F- A8 TAY B990- D0 02 BNE $B994 ; immediately exit -- no epilogue ; checking at all B992- 18 CLC B993- 60 RTS B994- 38 SEC B995- 60 RTS B996- 00 BRK | These are B997- 00 BRK | really on B998- 00 BRK | the disk, B999- 00 BRK | just taking B99A- 00 BRK | up space, B99B- 00 BRK | much like B99C- 00 BRK | this B99D- 00 BRK | comment. B99E- 18 CLC B99F- 60 RTS This RWTS will accept two different address prologues. If it finds a $D5 followed by a timing bit, that's it; that's the entire address prologue. Without the timing bit, it looks for the rest of a standard prologue. Turning back to the Copy ][+ nibble editor, I see the crucial detail that I missed the first time. The "D5" that I thought was the third nibble in the address prologue is actually the first, and it is displayed in inverse, meaning it has timing bits after it. (Sorry that doesn't show up in text.) The disk does happen to have a 3-nibble address prologue on every sector, but it only uses the one of them (plus a timing bit). Each address field also happens to have a consistent epilogue sequence, but the RWTS never checks it. I assume this accidental consistency is a side effect of the mastering process. Why didn't the EDD copy work? EDD preserved the original address prologue but not the timing bits. The prologue checker finds the $D5 (at $B954) but no timing bit after it (at $B95C), so the disk can't read itself. There was never any separate nibble check; the structure of the disk itself is designed to foil nibble copiers. Why did the demuffin'd copy work? Advanced Demuffin wrote out the data from each sector onto a standard disk that uses "D5 AA 96" prologue and "DE AA EB" epilogue. The RWTS finds the first $D5, doesn't find a timing bit, but it finds the remaining standard prologue (AA 96) and decides that it found a valid address field. Thus, no RWTS patches are necessary. All 14 disks use the same protection. Quod erat liberandum. ~ Chapter 3 In Which We Patch The RWTS Anyway, And Explain Why Emulators aren't perfect. Real hardware is complicated, and the Disk II is especially difficult to emulate (being, as it is, an analog device). Many edge cases are left as "an exercise for the reader." Many copy protection schemes rely on edge cases to work. You may see where this is going. My crack of this disk works perfectly on real hardware. It also works in most Apple II emulators that run on modern hardware. But it does not work in every emulator, so I set out to discover why. Here is the RWTS code from the original disk, which I have left untouched thus far: ; find address prologue #1 B94F- BD 8C C0 LDA $C08C,X B952- 10 FB BPL $B94F B954- C9 D5 CMP #$D5 B956- D0 F0 BNE $B948 ; kill 2 CPU cycles B958- EA NOP ; read data latch one more time B959- BD 8C C0 LDA $C08C,X ; if the data latch still has $D5 in it ; then we are reading an original disk ; which uses a single nibble + timing ; bit as the address prologue, so jump ; forward to start parsing the address ; field B95C- C9 D5 CMP #$D5 B95E- F0 12 BEQ $B972 ; otherwise we are reading a standard ; disk (like a data disk -- or, in my ; case, a cracked copy), so continue ; checking the prologue for the regular ; second and third nibbles B960- BD 8C C0 LDA $C08C,X B963- 10 FB BPL $B960 B965- C9 AA CMP #$AA B967- D0 DF BNE $B948 B969- BD 8C C0 LDA $C08C,X B96C- 10 FB BPL $B969 B96E- C9 96 CMP #$96 B970- D0 D6 BNE $B948 At $B95C, we're checking the data latch to see if it is still holding the $D5 value. On real Disk II hardware, this will only be true if there was an extra timing bit after the $D5. The timing bit causes the data latch to retain its value for 4 more CPU cycles. This is the crux of the entire copy protection. Here's the problem: some emulators will (incorrectly) retain the $D5 value in the data latch for longer than a real drive would. This makes the RWTS think that it's reading an original disk. Specifically, $B95E (incorrectly) branches to $B972 and tries to start parsing the address field. Of course, on my crack, the address field hasn't started yet -- there are still two more nibbles in the address prologue. The address field checksum fails because we're off by two nibbles, disks grind, programs crash, everything is terrible. The solution is tricky, because we're in the middle of RWTS code so timing is tight (even in misbehaving emulators). But if we change the code at $B958 to branch to $B960, we'll have enough time to catch the second and third nibbles of the standard address prologue. This should work on real hardware, faithful emulators, and misbehaving emulators (since we'll never execute the compare at $B95C that went awry). The patched RWTS code: B94F- BD 8C C0 LDA $C08C,X B952- 10 FB BPL $B94F B954- C9 D5 CMP #$D5 B956- D0 F0 BNE $B948 B958- F0 06 BEQ $B960 ------+ B95A- [8C C0] \ | B95C- [C9 D5] } never executed | B95E- [F0 12] / | B960- BD 8C C0 LDA $C08C,X <---+ B963- 10 FB BPL $B960 B965- C9 AA CMP #$AA B967- D0 DF BNE $B948 T00,S03,$58 change "EA BD" to "F0 06" ~ Changelog 2015-12-21 - apply and explain patch for legacy emulators --------------------------------------- A 4am crack No. 195 ------------------EOF------------------