home *** CD-ROM | disk | FTP | other *** search
-
- CRACKING 101 - 1990 edition
-
- Lesson 3
-
- ┌─────────────────────────────────────┐
- │ CHAMBER OF THE SCI-MUTANT PREISTEST │
- └─────────────────────────────────────┘
-
-
- 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.
-
- 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
- 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
- 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
- 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
- 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
- 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
- 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
-
- 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
- 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
-
- 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
- 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
-
- ; 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
-
-
- ** 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
-
- ; 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
- 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
-
- 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
-