Lesson #4 Some Cracking Practice

By

Indian_Trail





Since the fall is usually filled with rainy grey days I decided to study some basic cracking techniques. One of best cracking sitez on the net (next to fravias) is Lord Caligo's site He has alot of crack_me's and Try_me's. These are usually .com files and contain some protection written by crackers. Since the protectionist of comercial software are too Lazy to write real protection schemes, some crackers write their own for others to try. Let us download some of these files and fire Softice and start cracking them.

Here are the files you should download for this lesson.
The best thing with these files is that they contain variations of diffrent techniques. So if you wanna learn how to crack paper protection (password protection schemes) the fastest way to get a grasp of the variation of those protection schemes is to crack these try_me files.

Lets begin with pw.com. The first thing we should do is to run pw. So now you know that it displays:
Enter Password:
Switch to Softice and examine the memory by using the "MAP" command. Look for seg:offset where Pw dwells. In my computer it dwells at 10f2:0 and ends at 10f2:8F0E.
Write that adress down and switch back to pw. Type in your name and switch to softice and search for your inputs in the segment where pw dwells.
S 10F2:0 l ffff 'your input'
Softice will give you an adress where your input is stored.

10F2:010B (In my computer).

Remeber segment adresses are always diffrent but the offset adress is always the same.

Lets display that memory location and see that our inputs are really there.

D 10F2:010B

You should see your input at that adress. Now, we know that our input is not the correct password (unless we are lucky as hell) and that pw compares our input with the correct password. To do that it has to read our characters from the memory location where our input is stored and compare them with the correct password chars. So lets put a breakpoint on our chars in memory.

BPR 10F2:010B 10F2:010b +6(# of chars you typed) RW

Now switch back to pw and press enter. Softice will pop up as soon as pw reads from the memory locations where our input is stored. You'll pop up in this routine:

	MOV	BX,DX		;DX is the sixth char user pw
	MOV	AX,DI
	MOV	[BX],AL
	RET
------
	XOR	CH,CH
	MOV	CL,[0103]	;What is at adress 0103? 
	MOV	CX,BX
	MOV	AL,[BX+103]	;
	CMP	AL,[BX+010A]	;[BX+10A]= The sixth char of user pw
	JNZ	01BF		;Bad jump

Now you should know what you have found (if you have read the preceeding lessons). If you dump adress 0103 you'll see the correct password. So the JNZ is "Bad Password" jump. How should we crack it? Well there are at least two ways. One way is to change the JNZ into a JZ. That way we will get the "correct password" everytime we type in a FALSe Password. The second way is to make the program compare the correct password with the correct password instead of comparing correct password with user password. That way it will always print "correct password" no matter what we typed in. To change it that way we simply change the CMP line to.

CMP AL,AL

As you noticed if you reassembled that line in softice that more instructions came out after our CMP AL,AL. That's because the original instructions were 4 bytes and we changed it with our new instruction into 2 bytes. Like this:

CMP AL,AL
OR AL,[BX+DI]

So place 2 NOP (no operation) instruction and it will work fine. This is how should be:
	CMP	AL,AL
	NOP
	NOP	
	JNZ	01BF
If you view pw.com with a hexeditor you'll be able to see the correct password. If you take a comercial game protected with a manual scheme and hex view it you might see the correct passwords. If you dont, it generally means two things.
  1. The passwords are ENCRYPTED
  2. The program generates the password it self
The last one is quite common with windows software that has a registering option, where you enter a serial number to register the program. We will study windows cracking in Lesson_5. It's still raining in Sweden today so lets move on to the next try_me file.

Test1.com

Test1.com is 673 bytes and a quick hex view reveals that it has been packed with pklite. You can see the PKLITE string inside the file, wich means that the file is compressed. Therefor you wont be able to see any strings of possible passwords, you will se letters that has been arranged by a specific algorithm that PKLITE use. So before we go on lets unpack it with an exe fileunpacker like UNP. I'm using UNP 4.11, you'll easily find it on the web.

UNP test1.com

The new file size (of the decompressed test1.com) is 1039. Alright, lets hex view the file now and see if there's any strings that could be possible passwords.
We can see strings like
  1. Please enter password:
  2. Right password...congratulations...ask Lordbyte for next job
  3. Wrong password....Try again..>:)
Then follow some strange looking chars in 3 to 5 rows (I didn't count them), but no possible password, unless the password is "enter" or "password" or any combination of the words that we saw in the file. So I say it's probably encrypted. I gather that from the strange rows of chars that was in the file. Those strange chars are probably used to decrypt the password in the decryption routine. They could also be used to generate a password, it almost the same thing. So lets run it and see what it does. As expected it prompts for a password. Type in a false password and switch to Softice and dump the memmory using the "MAP" command (very handy).

183D:0 -6574 TEST1

Now search for your input in that segment as we did with PW.com. Softice doesn't find our input. That means that the user password is copied into Test1's data segment as we press return. For us that means that we cant breakpoint on our input string with BPR, becuse we dont know where that string is stored. How do we find out the location where our input is stored? Well two approaches are possible.
  1. Run the program and wait for the Wrong password....Try again..>:) to appear. Then search the main memory regions of the program for the string that you put in as password.If Softice finds it you should run a new attempt to see if the same location is used for storing the user input. If it is, you'll can use the same technique as we used with pw:
    (BPR xxxx:yyyy xxxx:yyyy+length of input R).
  2. Since the program writes our input from the buffer (in this case the dos buffer) and stores it somewhere in test1's offset memory we could BPR on the whole data segment of Test1 with write. To find out the offset. This approach is very secure, since our input has to be written to Test1's data segment. This approach is quite common with window programs (as you'll see in Lesson_5). One side affect with this method is that data is written all the time to the segment range of our main program (Test1). We are only interested in the part that copies our input from the keyboard buffer to the data segment of Test1. Therefor we will set this breakpoint just before we press enter. In dos programs often use interruptsto do basic tasks such as copy text from one place to another. So with this breakpoint set we can expect to land in a part of an interrupt routine that copies the text from the buffer to Test1. Lets try

    BPR 183D:0 183D:6574 W

    Here where we land:
    
    FF03:5468	MOV	[DI-01],DH
    	INC	DH
    	PUSH 	DS
    	PUSH	ES
    	POP	DS
    	POP	ES
    	MOV	SI,01FB	; 01FB is the dos buffer where our ; string is 		MOV	CL,DL	
    	REPZ	MOVSB   ; Move our input to ES:DI (data of 			RET		; Test1)
    	-----
    	IRET		;return from Interrupt
    	
    The Iret means reurning from the interrupt service back to the main programs Here what follows:
    	MOV	SI,01E6		 ; Si = encryptet password
    	MOV	AL,C3		
    	XOR	SI,AL		 ; Decrypt a char
    	CMP 	BYTE PTR [SI],00 ; Last char?
    	JZ	END OF STRING
    	SUB	AL,25
    	INC	SI		  ; Get next char
    	JMP	NEXT CHAR TO DECRYPT	
    		
    If you dump Si you'll see the correct password appear through out the loop. So this is the decryption mechanism. This encryption is quite easy to understand. So when the password is decrypted we will jump to END OF STRING, Here that is:
    	MOV 	SI,01E6
    	XOR 	AX,AX
    	MOV	SI,01E6		; Correct password
    	MOV	DI,01DD		; User password
    	MOV	CL,[SI] 	; Put first char of correct pw in CL
    	MOV	BL,[DI] 	; Put first char of user pw in BL
    	CMP	CL,BL		; Compare them
    	JZ	FALSE PASSWORD
    So Changing the instruction CMP CL,BL into CMP CL,CL will do the trick for this program. It's always good to make the crack at the churn of the protection scheme. If you crack the JZ, it might be a mirror check somewhere and you'll have to find that one and change it. By cracking the CMP any kind of flag etc that could be set if the the check fails/succeds will be set as if we entered the right password.

    The BPR 183D:0 183D:6574 W took us to the correct place. We first landed in an interrupt routine and stepped from there to the programs execution place. Now you'll probably know that you can breakpoint on interrupts in Softice with the command

    BPINT interrupt number |al|ah|ax=value. If we would have used that breakpoint we would have avoided the bios routine and gone straight to the location the IRET took us. But we dont know the interrupt service number that Test1 is using. Well that is easily changed. Run Test1 but this time use the LDR (DLDR if you are using winice) command to load Test1 and BPINT 21 before you press CTRL-D. Here is the list of Int 21 called from test1.com:

    1. Display String
    2. Buffered Keyboard Input.
    Put a breakpoint on the line after the int 21 and switch to the program to enter a password. As you'll see Softice puts you in the decryption routine. Less than 5 sec to get to the churn of the protection scheme. How did I know that I was gonna breakpoint on INT 21?
    well since the protection takes place in DOS it's very likely it uses Dos interrupts wich is service 21. This method is fast and quite reliable, it does however not work for protection that "hooks" an interrupt. Hooking an interrupt means that the program directs an interrupt to a special place in the code where ie the protection scheme is hidden. Checking for cheat codes in games are usally done by this way. INT 16 is Keyboard and I/O service and is called from programs everytime you press a key. A game might change the adress of INT 16 to its own code where its checks to see if the key 'W' was pressed and if so increase players energi. Then when the checks are done the game jumps to the original adress of INT 16.

    There are utilities that log interrupts during an execution of a program. (The best utilities are the ones you write your self though, plus that you'll gain knowledge of assembly language aswell). This can be useful if you get stuck on a protection scheme and need a push in the right direction. I described both method in this lesson because the first one (BPR seg:0 seg:end W ) is the basic aproach and will give you a complete overview of what's going on. Some programmers dont use interrupts and using BPINT on such a application wont get you anywhere. But a BPR with write on diffrent memory location will get you somewhere. But remeber always try the easiest approaches because protection scheme is usually not well written in comercial software. Plus that it is difficult to write a smart protection scheme. So with programs that asks for a password in dos, you could try any of the above techniques starting with the fastest one. Lest try the next Try_me file wich is Test2.com.

    Test2.com

    Lets apply the same approach as we have done with the other try_me files. If you breakpoint with BPR W you'll get in the interrupt routine and if you just use BPINT 21 you'll land on Buffered Keyboard Input. Your input is at DX+02. BPMB the first char of the string you entered and press CTRL-D. This is what you should see:
     __
         |	XOR	AX,[SI]
         |	CMP 	BYTE PTR [SI+01],00  ;Here is where you land
         |	JZ 	014E
         |	CMP 	BYTE PTR [SI+01],0D  ;check if char is carraige return(0D)
         |	JZ	014E
         |	INC	SI
         |	JMP	013D		     ; run until end of string is reached
         |__				
    
    014E	CMP	WORD PTR CS:[0245],00 ;???? what's this???
    	JNZ	014E		      ; a loop! for what????
    	MOV	SI,0241
    	MOV	DX,[SI]
    	PUSH	AX
    	MOV	AX,[SI+02]
    	MOV	DS,AX
    	MOV	AX,251C
    	INT 	21		;SET VECTOR
    If you let the program run it will show "Wrong password.." and exit to DOS. So it only reads our input string one time. The XOR AX,[SI] looks suspecious at first look, it looks like a encryption instruction. Its the only thing in the first pieace of code that manipulates our string. The next thing that my eyes see is the CMP WORD PTR CS:[0245],00 The CMP is checking the status at CS:[0245] unti it's zero. What's going on at adress CS:0245? and what changes the 01 into 0?
    Here is where Softice takes us
    
    	DEC	WORD PTR CS:[0245]	; Here's the toggle from 01/00
    	IRET
    	---
    	INT 	1C			;So Int 1C is one that is hooked
     	CALL	8CFA
    INT 1C is the user timer click vector. It runs constantly, just try a BPINT 1C and you'll see. Now we understand the strange CMP WORD PTR CS:[0245],00. We now make a guess that the XOR AX,[SI] instruction encrypts our input letters for a later compare. Since the encryptet string is stored in AX as a number and not as a string we have to look for instructions that moves AX value to a place in memory. The PUSH AX stores our encrypted string on the stack. Step over it and do a D SS:SP and you'll see that the number that was in AX is now on another adress. BPM that adress.

    BPM SS:FFFA (adress could be diifrent in your computer)

    Softice will pop here:
    
    	XOR	[BP+08],BX
    	JNZ	01B2		; Evil Jump
    ---
    If you scan up alittle in the code you'll se this:
    	MOV	BX,[BP+04]
    	XOR	BX,B816
    	XOR	[BP+08],BX	; BP+08 is our encrypted code
    	JNZ	01B2
    Now we can easily crack this by changing the JNZ into a JZ If you wanna know the correct password you'll have to DECRYPT it. I'll leave that up to you. Here are some hint if you wanna have a try.
    1. If you look at the last compare before the evil jump, you'll see what our Encrypted string should be after the encryption loop.
    2. The hardest part is to figure out how you'll get that result from the encryption loop.
    3. Number of chars is very important. You could make a table and put you results in.
    4. The fastest way is to use some sort of mathematical function or equation to calculate the correct password. You could write a small program to caculate the correct password


    Conclusion:

    When I first tried these Try_me files I cracked them flat on three seconds. Trying the diffrent techniques we have studied here. These methods are basic cracking Techniques and by using them you should be able to crack most of the programs that use the password protection. To crack Test2.com the above steps are not necessary. You could just have single stepped a few instructions from the Encryption routine and you would have landed at the final compare. What we did was to dig out some pieces that we didn't understand at first, that's called "studing". The difference between cracking a scheme and studing it is that when studing you put together all the pieces the protection holds to get a full view. When that is done you have learned something new (if the protection was new to you). You usually first try to crack it and if you fail you study it. The purpose of this lesson was to show you how to approach diffrent schemes of the same BASE protection, in this case the password protections. There are three more files left wich I'll leave up to you to study on your own. I know that some people want these solutions published. The reason why I dont publish my solutions to these three files in this lesson is beacuse I dont have the time and becuase I would like you to work on your own. I'll happily answer all questions that you may have (or get).If you go on and study the last three files, please write down your solution and E-mail it to me and I'll publish it here.This site is dedicated to Newbies and the best thing that could happen is that newbies teach each other on this site. Fravias Page of Reverse Engineering is the best cracking site I've ever seen. This page is meant to be like a preparation for a beginner before he moves on to other sitez. I'll also welcome all opions about my work E-mail me at. Email me. Best regards and luck!

    Indian_Trail