2 CRACKING 101 - 1990 edition Lesson 3 ZDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD? 3 CHAMBER OF THE SCI-MUTANT PREISTEST 3 @DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDY Oh shit, I have finally found a newer program that has on disk copy protection. Good, you'all need a refresher course on so here it is (YO JB study hard, you might learn something). CHAMBER of the SCI-MUTANT PREISTEST (CSMP) is a really fucked up game but was simple to unprotect. So, lets dive right in. We will be using DEBUG here (although I used periscope but then shit I'm special) to do the crack. Lets dive in. When we first load CSMP (the file ERE.COM) and unassemble it here is what we get. Come on... Ain't Got All Day!! u 100 10B 119A:0100 8CCA MOV DX,CS 119A:0102 81C2C101 ADD DX,01C1 119A:0106 52 PUSH DX 119A:0107 BA0F00 MOV DX,000F 119A:010A 52 PUSH DX 119A:010B CB RETF I included the register listing for a reason. NOTICE that this piece of code just seem to stop (the RETF) statement. Well, what is really does is place the address (segment and offset) of the real starting point on to the stack and the execute a far return to that location. Now this might fool a real beginner (or at least make him worry a bit but us...no way). If you take the current CS value and add 1C1 to it (in segment addition) you will get the segment address 135B (that is if you are using my example of 119A. If not then you will not get 135B but trust me, it's the right value). So since we want to be at the real program, execute the code until 10B (ie use the command "G 10B") then trace Come on... Ain't Got All Day!! through the next instruction. If you now unassemble the code, here is what it should look like. -u 000f 36 135B:000F 9C PUSHF 135B:0010 50 PUSH AX 135B:0011 1E PUSH DS 135B:0012 06 PUSH ES 135B:0013 0E PUSH CS 135B:0014 1F POP DS 135B:0015 0E PUSH CS 135B:0016 07 POP ES 135B:0017 FC CLD 135B:0018 89260B00 MOV [000B],SP 135B:001C C70600000102 MOV WORD PTR [0000],0201 135B:0022 B013 MOV AL,13 135B:0024 A23500 MOV [0035],AL 135B:0027 A2FF01 MOV [01FF],AL 135B:002A A22F02 MOV [022F],AL 135B:002D A23901 MOV [0139],AL 135B:0030 B280 MOV DL,80 Come on... Ain't Got All Day!! 135B:0032 B408 MOV AH,08 135B:0034 CD21 INT 21 135B:0036 7232 JB 006A Since we are looking for a disk based copy protection, it might be a good time to look for INT 13. So search the current segment for INT 13 with the command S 135B:0 FFFF CD 13 But shit, nothing. You mean this program doesn't use int 13. Be real. Reread the first lesson. You know the one that talks about self modifing code. This is what we have here. Let's take a closer look at the last bit of code but this time, with my comments added. -u 000f 36 ; The first part of the code simple sets up for the return to ; dos as well as sets ES and DS 135B:000F 9C PUSHF 135B:0010 50 PUSH AX Come on... Ain't Got All Day!! 135B:0011 1E PUSH DS 135B:0012 06 PUSH ES 135B:0013 0E PUSH CS 135B:0014 1F POP DS ; Set DS to CS 135B:0015 0E PUSH CS 135B:0016 07 POP ES ; Set ES to DS 135B:0017 FC CLD 135B:0018 89260B00 MOV [000B],SP ; The next instruction sets up a variable that is used in the ; routine that reads in the sectors from the disk. More on ; later. 135B:001C C70600000102 MOV WORD PTR [0000],0201 ; Now, here is the self modifing code. Notice at AL is 13 ; (INT 13h ... Get it). Look at the first memory location ; (35h) and remember that DS = CS. With this in mind, when ; then instuction at 135B:0024 is executed byte at 135B:0035 ; will be changed to 13h. That will in fact change the ; INT 21h at 135B:0034 to an INT 13h. And so on, and so on. 135B:0022 B013 MOV AL,13 ; New value Come on... Ain't Got All Day!! 135B:0024 A23500 MOV [0035],AL ; Change to INT 13h 135B:0027 A2FF01 MOV [01FF],AL ; Change to INT 13h 135B:002A A22F02 MOV [022F],AL ; Change to INT 13h 135B:002D A23901 MOV [0139],AL ; Change to INT 13h ; If you lookup DOS function 08 you will find it's CONSOLE ; INPUT. Now does that seem out of place to you. 135B:0030 B280 MOV DL,80 135B:0032 B408 MOV AH,08 135B:0034 CD21 INT 21 ; Changed to INT 13h 135B:0036 7232 JB 006A Whoa, that was tricky. If you execute up to 135B:30 here is what it should look like.. 135B:0030 B280 MOV DL,80 135B:0032 B408 MOV AH,08 135B:0034 CD13 INT 13 135B:0036 7232 JB 006A AHA, now we are getting somewhere. If we lookup what Come on... Ain't Got All Day!! disk function 08 means, you won't be suprised. Function 08h is GET DRIVE TYPE. It will tell what type of disk drive we have. Remember, if you are loading off of a hard disk then it wants to use a different routine. Since we want it to think we are loading off of disk, then we want to take this jump. So for now, force the jmp by setting IP to 6A. At 135B:006A you find another jmp instruction 135B:006A EB6B JMP 00D7 This jumps to the routine that does the actual disk check. Here is the outer loop of that code (With my comments of course). ; This first part of this routine simply test to see how many ; disk drives you have. 135B:00D7 CD11 INT 11 135B:00D9 25C000 AND AX,00C0 135B:00DC B106 MOV CL,06 135B:00DE D3E8 SHR AX,CL Come on... Ain't Got All Day!! 135B:00E0 FEC0 INC AL 135B:00E2 FEC0 INC AL 135B:00E4 A20200 MOV [0002],AL ; Next, so setup for the actual disk check 135B:00E7 C606090000 MOV BYTE PTR [0009],00 135B:00EC B9F127 MOV CX,27F1 135B:00EF 8BE9 MOV BP,CX 135B:00F1 B107 MOV CL,07 135B:00F3 F8 CLC ; This calls the protection routine part 1 135B:00F4 E82F00 CALL 0126 135B:00F7 B9DE27 MOV CX,27DE 135B:00FA 8BE9 MOV BP,CX 135B:00FC B108 MOV CL,08 135B:00FE F9 STC ; This calls the protection routine part 2 Come on... Ain't Got All Day!! 135B:00FF E82400 CALL 0126 135B:0102 8D1E5802 LEA BX,[0258] 135B:0106 8D361C01 LEA SI,[011C] 135B:010A 8BCD MOV CX,BP 135B:010C AC LODSB 135B:010D 8AC8 MOV CL,AL ; This calls the protection routine part 3 135B:010F E8E300 CALL 01F5 ; Makes the final check 135B:0112 7271 JB 0185 135B:0114 AC LODSB 135B:0115 0AC0 OR AL,AL 135B:0117 75F4 JNZ 010D ; If not correct, try again 135B:0119 EB77 JMP 0192 ; Correct, continue program 135B:011B 90 NOP There are calls to 2 different subroutines. The routine at 126 and the routine at 1F5. If you examine the routine at Come on... Ain't Got All Day!! 126 you find that it makes several calls to the routine at 1F5. Then you you examine the routine at 1F5 you see the actual call to INT 13. Here is the code for both routine with comments ; First, it sets up the sector, head and drive information. ; DS:000A holds the sector to read 135B:0126 880E0A00 MOV [000A],CL 135B:012A 8A160900 MOV DL,[0009] 135B:012E B600 MOV DH,00 ; Sets the DTA 135B:0130 8D365802 LEA SI,[0258] 135B:0134 7213 JB 0149 ; Resets the disk 135B:0136 33C0 XOR AX,AX 135B:0138 CD13 INT 13 ; Calls the the check Come on... Ain't Got All Day!! 135B:013A B90114 MOV CX,1401 ; TRACK 14 sector 1 135B:013D 8BDE MOV BX,SI 135B:013F E8B300 CALL 01F5 ; The next track/sector to read in is stored in BP 135B:0142 8BCD MOV CX,BP 135B:0144 E8AE00 CALL 01F5 135B:0147 7234 JB 017D ; If an error occured, ; trap it. 135B:0149 88160900 MOV [0009],DL ; Reset drive 135B:014D 8A0E0A00 MOV CL,[000A] ; reset sector 135B:0151 E8A100 CALL 01F5 ; check protection 135B:0154 722F JB 0185 ; Check for an error 135B:0156 8D5C20 LEA BX,[SI+20] 135B:0159 8BCD MOV CX,BP ; Get next T/S 135B:015B B010 MOV AL,10 ; Ignore this 135B:015D E89500 CALL 01F5 ; Check protection Come on... Ain't Got All Day!! 135B:0160 7223 JB 0185 ; check for error ; The next sector of code checks to see if what was read in ; is the actual protected tracks ; First check 135B:0162 8DBCAC00 LEA DI,[SI+00AC] 135B:0166 B91000 MOV CX,0010 135B:0169 F3 REPZ 135B:016A A7 CMPSW ; NOTE: If it was a bad track, it will jmp to 185. A good ; read should just continue 135B:016B 7518 JNZ 0185 ; Second check 135B:016D 8D365802 LEA SI,[0258] 135B:0171 8D3E3702 LEA DI,[0237] 135B:0175 B90400 MOV CX,0004 135B:0178 F3 REPZ 135B:0179 A7 CMPSW Come on... Ain't Got All Day!! ; see NOTE above 135B:017A 7509 JNZ 0185 ; This exit back to the main routine. 135B:017C C3 RET ; Here is the start of the error trap routines. Basicly what ; they do is check an error count. If it's not 0 then it ; retries everything. If it is 0 then it exit back to dos. 135B:017D FEC2 INC DL 135B:017F 3A160200 CMP DL,[0002] 135B:0183 72B1 JB 0136 135B:0185 E85400 CALL 01DC 135B:0188 8B260B00 MOV SP,[000B] 135B:018C 2BC9 SUB CX,CX 135B:018E 58 POP AX 135B:018F 50 PUSH AX 135B:0190 EB1F JMP 01B1 Come on... Ain't Got All Day!! ** Here is the actual code the does the check ** ; ES:BX points to the buffer 135B:01F5 1E PUSH DS 135B:01F6 07 POP ES ; SI is set to the # of retries 135B:01F7 56 PUSH SI 135B:01F8 BE0600 MOV SI,0006 ; Remember how I said we would use what was in DS:0000 later. ; well, here is where you use it. It loads in the FUNCTION ; and # of sectors from what is stored in DS:0000. This is ; just a trick to make the int 13 call more vague. 135B:01FB A10000 MOV AX,[0000] 135B:01FE CD13 INT 13 ; If there is no errors, then exit this part of the loop 135B:0200 7309 JNB 020B 135B:0202 F6C480 TEST AH,80 Come on... Ain't Got All Day!! ; Check to see if it was a drive TIMEOUT. If so, then set ; an error flag and exit 135B:0205 7503 JNZ 020A ; It must have been a load error. Retry 6 times 135B:0207 4E DEC SI 135B:0208 75F1 JNZ 01FB ; Set the error flag 135B:020A F9 STC ; restore SI and return 135B:020B 5E POP SI 135B:020C C3 RET If you follow through all of that. You will see that the only real way out is the jmp to "135B:0192" at 135B:0119. So, how do we test it. Simple. Exit back to dos and let's Come on... Ain't Got All Day!! add a temporary patch. Reload ERE.COM under debug. Execute the program setting a breakpoint at 135B:0022 (if you remember, that is right at the begining of the self modifing code). When execution stops, change you IP register to 192. Now execute the code. Well shit, we are at the main menu. We just bypassed the entire protection routine. So, now where to add the patch. We will be adding the patch at 135B:0022. But what should the patch be. In this case, simply jumping to 135B:0192 will do. So, reload ERE.COM under debug. Execute the code until 135B:0022. Now unassemble it. Here is the code fragment we need. 135B:0022 B013 MOV AL,13 135B:0024 A23500 MOV [0035],AL 135B:0027 A2FF01 MOV [01FF],AL 135B:002A A22F02 MOV [022F],AL 135B:002D A23901 MOV [0139],AL Here is the code we want to use as the patch 135B:0022 E96D01 JMP 192 Come on... Ain't Got All Day!! So, to add the patch, we search the file ERE.COM using PC-TOOLS. For our search string we use B0 13 A2 35 00 A2 FF 01 A2 2F 02 A2 39 01 PC-TOOLS should find the search string at reletive sector #13. Edit the sector and change "B0 13 A2" to "E9 6D 01" (our patch) and save the sector. BOOM! your done and CSMP is cracked. Fun huh. You just kicked 5 seconds off of the load time. Preaty fucken good. Well, I hope this textfile helped. -Buckaroo Banzai -Cracking Guru CRACKING 101 - 1990 Edition Lesson 4 revision 1 ZDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD? Come on... Ain't Got All Day!! 3 REMOVING THE DOC CHECK FOR STAR CONTROL 3 @DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDY < Added for revision 1 - First, let me tell you about a major fuckup I made. When I first wrote this file, I left out a major part of the patch. For all of the user who got that version, I'm sorry but even I make mistakes at 3:00 in the morning. Anyway, just replace the original with this updated version - Buckaroo Banzai > Hey, Buckaroo Banzai .. Cracking Guru back once again to help you lesser crackist learn. This time, we will be going over Star Control. This is the last lesson in the original 4. From here on out, I will simply release lessons as I write them. I want to say a few things about some of the groups out Come on... Ain't Got All Day!! there right now. Speed isn't everything. I really wish that for example when you remove a doc check, most of us want it REMOVED. We don't want to have to enter your group name or even typing 1 letter is to much. We shouldn't even see the menu for the doc check. Now, I don't direct this to all of you, but there seems to have been a move from quality to quickness. Let's go back to the days of SPI (and INC when they were first getting started) and crack right. If there is a doc check, remove it, not just fake it. Nuff said, on with the tutorial. Star Control (SC for here out) is a preaty good game. The protection on it wasn't too hard, but if you didn't read enough in to it, you would just kill the title music also. So, how do we go about cracking SC. Well for this one I opted to break out when SC asks for the code from the code wheel. Originaly I did this just for the hell of it, but it turned out to be a luck guess and made life a lot easier. As usual we will be using periscope to crack SC. I used PSKEY (using int 3 as the trap interrupt not int 2) to pop in at the input routine. So lets get started. Load up PS and Come on... Ain't Got All Day!! PSKEY, then execute Star Control. When you get to the doc check, break out. Now you should be at the usual IRET insturction that's part of PSKEY. Now comes the tricky part. Since we are using a key trap to break out during the input sequence, we could be anywhere inside the entire input routine. So in cases like this I suggest finding a reference point. So how do you pick the reference point. Well, since this doc check must be entered via the keyboard you can bet somewhere it will call INT 16h (bios keyboard) (although there are times when this is not true, it rare). I think we should go off and find that call to that interrupt. So we trace (using the 'T' command) through some code and finally come apon the follow subroutine .... ( NOTE: all comments were added by me ) ; This is the actual routine that is used to get a key 2A00:09D4 55 PUSH BP Come on... Ain't Got All Day!! 2A00:09D5 8BEC MOV BP,SP 2A00:09D7 8A6606 MOV AH,[BP+06] 2A00:09DA 8AD4 MOV DL,AH 2A00:09DC 80E20F AND DL,0F 2A00:09DF CD16 INT 16 ; Call to bios. We will 2A00:09E1 7509 JNZ 09EC ; use this as our 2A00:09E3 80FA01 CMP DL,01 ; reference point 2A00:09E6 7504 JNZ 09EC 2A00:09E8 33C0 XOR AX,AX 2A00:09EA EB0A JMP 09F6 2A00:09EC 80FA02 CMP DL,02 2A00:09EF 7405 JZ 09F6 2A00:09F1 0BC0 OR AX,AX 2A00:09F3 7501 JNZ 09F6 2A00:09F5 48 DEC AX 2A00:09F6 5D POP BP 2A00:09F7 CB RETF So we write down the address of our REFERENCE point and get ready to procede. Now, It's really kinda boring to keep trying to trace through the entire input routine while trying to enter the code string, so what we want to do next, is to figure out the input routine. A quick look at this last section of code shows that it only reads in a character but Come on... Ain't Got All Day!! really does not handle it. So, we exit via the RETF at 9F7 enter the next level of the subroutine. Again, if you manual trace through this routine (as well as the next level up) you see that it simple exits out rather quickly. This is definitly not the top loop of the imput routine. So, we trace through the next level up, and again exit quickly to a higher level. But this time, as we trace through, we find that the it loops back on itself. AHA, the outer input loop. Here is the code to the entire input loop. I have marked the place where you should enter from the lower level. ( String input loop -- Outer level ) 7C00:0835 FF365220 PUSH [2052] 7C00:0839 FF365020 PUSH [2050] 7C00:083D 9A2802FD41 CALL 41FD:0228 ; Entery here 7C00:0842 888670FE MOV [BP+FE70],AL 7C00:0946 0AC0 OR AL,AL 7C00:0848 7503 JNZ 084D 7C00:084A E99200 JMP 08DF Come on... Ain't Got All Day!! 7C00:084D 2AE4 SUB AH,AH 7C00:084F 2D0800 SUB AX,0008 7C00:0852 745A JZ 08AE 7C00:0854 48 DEC AX 7C00:0855 48 DEC AX 7C00:0856 7503 JNZ 085B 7C00:0858 E90901 JMP 0964 7C00:085B 2D0300 SUB AX,0003 7C00:085E 7503 JNZ 0863 7C00:0860 E90101 JMP 0964 7C00:0863 8A9E70FE MOV BL,[BP+FE70] 7C00:0867 2AFF SUB BH,BH 7C00:0869 F687790B57 TEST BYTE PTR [BX+0B79],57 7C00:086E 746F JZ 08DF 7C00:0870 F687790B03 TEST BYTE PTR [BX+0B79],03 7C00:0875 740C JZ 0883 7C00:0877 F687790B02 TEST BYTE PTR [BX+0B79],02 7C00:087C 7405 JZ 0883 7C00:087E 80AE70FE20 SUB BYTE PTR [BP+FE70],20 7C00:0883 8A8670FE MOV AL,[BP+FE70] 7C00:0887 C49E7EFE LES BX,[BP+FE7E] 7C00:088B 8BB682FE MOV SI,[BP+FE82] 7C00:088F 26 ES: 7C00:0890 8800 MOV [BX+SI],AL Come on... Ain't Got All Day!! 7C00:0892 FF8682FE INC WORD PTR [BP+FE82] 7C00:0896 FFB688FE PUSH [BP+FE88] 7C00:089A 8D8678FE LEA AX,[BP+FE78] 7C00:089E 50 PUSH AX 7C00:089F 9A56049324 CALL 2493:0456 7C00:08A4 83C404 ADD SP,+04 7C00:08A7 0BC0 OR AX,AX 7C00:08A9 7534 JNZ 08DF 7C00:08AB EB27 JMP 08D4 7C00:08AD 90 NOP 7C00:08AE 83BE82FE00 CMP WORD PTR [BP+FE82],+00 7C00:08B3 7404 JZ 08B9 7C00:08B5 FF8E82FE DEC WORD PTR [BP+FE82] 7C00:08B9 B008 MOV AL,08 7C00:08BB 50 PUSH AX 7C00:08BC 9A1003443D CALL 3D44:0310 7C00:08C1 8D8684FE LEA AX,[BP+FE84] 7C00:08C5 16 PUSH SS 7C00:08C6 50 PUSH AX 7C00:08C7 9A6A00843D CALL 3D84:006A 7C00:08CC B047 MOV AL,47 7C00:08CE 50 PUSH AX 7C00:08CF 9A1003443D CALL 3D44:0310 7C00:08D4 8D8678FE LEA AX,[BP+FE78] Come on... Ain't Got All Day!! 7C00:08D8 16 PUSH SS 7C00:08D9 50 PUSH AX 7C00:08DA 9A8202C93C CALL 3CC9:0282 7C00:08DF 83BE8CFE00 CMP WORD PTR [BP+FE8C],+00 7C00:08E4 7503 JNZ 08E9 7C00:08E6 E94CFF JMP 0835 ; , etc.). Now execute the program. SHIT! It worked, we are fucking amazing. Ok, now adding the patch permenatly. Using PCTOOLS (or whatever) search the file STARCON.EXE for the bytes mention above (ie: C746F60B00C746F87900C746FA2801) But wait, now matches...Hmmm strange. It was there just a minute ago...but Come on... Ain't Got All Day!! wait there... another file STARCON.OVL (as we all know .OVL mean OVERLAY). Let's try searching this one. There we go, that's better (it should should up on the 13 sector read in). Now to add the patch. Simply find the search bytes and the go backwards until the first occurance of the hex byte 9A. Add the patch here. Save it. Next, add the patch to 45E2:023F. Search for the bytes 83C4040BC07465. The should appear on sector 3 (give or take a few sectors). Now simply change the 2 bytes 74 65 to 90 90 and save the sector. Now, you are good to go. Well shit, this has been some hell of a textfile. 1113 lines in all. But what detail. Ok I hope you learned something from all of this. And this end the first part of CRACKING 101 - the 1990 edition. From here out all lessons ( lesson 5 and up) will be released on their own. I would like the thank Phantom Phlegm for pushing me to finish this shit. Till lesson 5 this is Buckaroo Banzai, signing off. Come on... Ain't Got All Day!! OH... I can be reached for personal help via E-MAIL on LORD WOLFEN's CASTLE or TOS... [2] Tfiles: (1-3,?,Q) :