	  Ŀ
	                                                              Ŀ
	    
	          
	          
	                                               
	                                               
	                                   
	                                   
	                                   
	                                                
	                                                
	                       
	                       
	                 
	                                                                  
	                                                                  
	                         
	                 p r o u d l y     p r e s e n t s                
	                         
	                                                                  
	Ŀ                                            www.tscube.cjb.net
	  



                      ͻ
                        Tutorial for Crack'em crackme   
                      ͼ

Best viewed with NFO viewer



Ŀ
1. Intro 


The GUI of this VB crackme is pretty nice, and I'm sure you really want to deactivate this
security protocol ;)

The serial check routine uses the FPU, but don't start bumping your head against the wall,
because I'll explain everything ;)



Ŀ
2. The Protection scheme 


Smartcheck won't help us here : we can only see LOTS of string manipulations and some nice
"What ya looking at BoZo!?!?" and "BERSERK!!!!" strings. 
Yeah, we will surely go berserk if we keep trying to find something with SC, so let's fire 
WDASM ('VB patched version') :

Here is the interesting part :

<-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->

=> [EBP-20] is a magic_number generated from the name

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041326F(C)
|
:004132E2 DD45E0                  fld qword ptr [ebp-20]
:004132E5 DC3558104000            fdiv qword ptr [00401058] -> / 10
:004132EB FF75E8                  push [ebp-18]
:004132EE DD5DE0                  fstp qword ptr [ebp-20]

magic_number = magic_number / 10

* Reference To: MSVBVM50.__vbaLenBstr, Ord:0000h
                                  |
:004132F1 E8EEDEFEFF              Call 004011E4
:004132F6 69C09A020000            imul eax, 0000029A
:004132FC 898564FFFFFF            mov dword ptr [ebp+FFFFFF64], eax
:00413302 FF75E8                  push [ebp-18]
:00413305 DB8564FFFFFF            fild dword ptr [ebp+FFFFFF64]
:0041330B DC3560104000            fdiv qword ptr [00401060] -> / 8
:00413311 DC3568104000            fdiv qword ptr [00401068] -> / 60
:00413317 DC2570104000            fsub qword ptr [00401070] -> - (-2)
:0041331D DC2578104000            fsub qword ptr [00401078] -> - 0.325
:00413323 DD1D3C404100            fstp qword ptr [0041403C]

=> unused_number_1 = ((((strlen(serial)*666) / 8) / 60) + 2) - 0.325

:00413329 DD45E0                  fld qword ptr [ebp-20]
:0041332C DC3580104000            fdiv qword ptr [00401080] -> / 6780496716
:00413332 DC0D88104000            fmul qword ptr [00401088] -> * 3
:00413338 DD1D44404100            fstp qword ptr [00414044]

=> magic_number = (magic_number / 6780496716) * 3

* Reference To: MSVBVM50.__vbaLenBstr, Ord:0000h
                                  |
:0041333E E8A1DEFEFF              Call 004011E4
:00413343 69C04D010000            imul eax, 0000014D
:00413349 898560FFFFFF            mov dword ptr [ebp+FFFFFF60], eax
:0041334F DB8560FFFFFF            fild dword ptr [ebp+FFFFFF60]
:00413355 DC3560104000            fdiv qword ptr [00401060] -> / 8
:0041335B DC3568104000            fdiv qword ptr [00401068] -> / 60
:00413361 DC2570104000            fsub qword ptr [00401070] -> - (-2)
:00413367 DC2578104000            fsub qword ptr [00401078] -> - 0.325
:0041336D DC2590104000            fsub qword ptr [00401090] -> - 0.8375
:00413373 DD1D4C404100            fstp qword ptr [0041404C]

=> unused_number_2 = (((((strlen(serial)*333) / 8) / 60) + 2) - 0.325) - 0.8375

:00413379 DD0544404100            fld qword ptr [00414044]
:0041337F DC1D98104000            fcomp qword ptr [00401098] -> 72

=> we are registered if magic_number = 72

:00413385 DFE0                    fstsw ax
:00413387 9E                      sahf
:00413388 7528                    jne 004133B2 -> FUCK OFF
:0041338A 833DAC44410000          cmp dword ptr [004144AC], 00000000
:00413391 750F                    jne 004133A2 -> registered
:00413393 68AC444100              push 004144AC
:00413398 681C144100              push 0041141C

* Reference To: MSVBVM50.__vbaNew2, Ord:0000h
                                  |
:0041339D E85ADEFEFF              Call 004011FC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413391(C)
|
:004133A2 8B35AC444100            mov esi, dword ptr [004144AC]
:004133A8 8D4DD8                  lea ecx, dword ptr [ebp-28]
:004133AB 51                      push ecx

* Possible Reference to String Resource ID=00001: "Thank you for registering"
                                  |
:004133AC 6A01                    push 00000001
<-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->

As you can see, the crackme generates 2 numbers which are NOT used at all... just to make us
waste our time ;)

=> VERY IMPORTANT : to deactivate the crackme, the serial must be 6 letters long !!!!


	2.1. The FPU
	

If it's the first time you deal with the FPU, I suggest you have a look at the file named
'fpu.tutorial.txt' which explains everything you need to know.

Luckily for us, SICE can be used to view the FPU stack elements (ST0,ST1...ST7)

=> type 'WF' in SICE to view them

Now, let's take for example the first lines of the serial_check routine :

fld qword ptr [ebp-20]		=> Loads a float (ST0 = float loaded)
fdiv qword ptr [00401058]	=> Divides ST0 by [401058] ( ie ST0 = ST0 / 10)
push [ebp-18]
fstp qword ptr [ebp-20]		=> Stores the result back in [EBP-20]

You may be wondering how I know that [00401058] = 10. To find this, I used a (bad) idea : I
typed the following code in SICE :

'a' (to start assembling code)
FLD [401058]

Then I executed the 'FLD [401058]' instruction and I simply looked the value of ST0 (don't forget
to exit and run again the crackme after this modification ;)


	2.2. The magic_number
	

This number is generated a few lines above :

<-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->
note : this code is executed strlen(serial) times

:004132AA 50                      push eax

* Reference To: MSVBVM50.rtcAnsiValueBstr, Ord:0204h
                                  |
:004132AB E82EDFFEFF              Call 004011DE
:004132B0 0FBFC0                  movsx eax, ax -> ASCII value of serial[i]
:004132B3 898568FFFFFF            mov dword ptr [ebp+FFFFFF68], eax
:004132B9 8D4DD8                  lea ecx, dword ptr [ebp-28]
:004132BC DB8568FFFFFF            fild dword ptr [ebp+FFFFFF68]
:004132C2 DC4DE0                  fmul qword ptr [ebp-20]
:004132C5 DD5DE0                  fstp qword ptr [ebp-20]
<-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->

in 'C', it looks like :

int magic_number = 2; // DON'T forget this initial value !!!
for (int i=0;i<strlen(serial);i++) magic_number = magic_number * serial[i];


	2.3. The equation to solve
	

(((magic_number/10) / 6780496716) * 3) = 72

=> magic_number = 1627319211840



Ŀ
3. How to find a correct serial 


Very good question, but first let me show how the serial_check routine looks like in 'C' 
(the 'LOOKS LIKE' words are very important ;)

<-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->
char serial[50];
gets(serial);

int magic_number = 2; // DON'T forget this initial value !!!
for (int i=0;i<strlen(serial);i++) magic_number = magic_number * serial[i];

if (magic_number != 1627319211840) puts("Unregistered");
else puts("Registered");
<-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->

Two solutions :
1) Write a brute forcer to generate all possible serials
2) Use our head to find a correct serial

I chose the second solution (if you want to try the first solution, you'll maybe need a Bignum
library).


	3.1. The 'factor.exe' program
	

This program (modified by ghiribizzo) is part of the MIRACL bignum library : it can factorize
big numbers in a few seconds (very useful to crack RSA, don't you thing promethee ? ;)

I used it to help me find the ASCII values of the serial :

C:\crackme\crackem>factor 1627319211840
first trying brute force division by small primes
PRIME FACTOR     2
PRIME FACTOR     2
PRIME FACTOR     2
PRIME FACTOR     2
PRIME FACTOR     2
PRIME FACTOR     2
PRIME FACTOR     3
PRIME FACTOR     3
PRIME FACTOR     3
PRIME FACTOR     3
PRIME FACTOR     3
PRIME FACTOR     5
PRIME FACTOR     7
PRIME FACTOR     7
PRIME FACTOR     7
PRIME FACTOR     17
PRIME FACTOR     37
PRIME FACTOR     97

This means that : 1627319211840 = 2*2*2*2*2*2*3*3*3*3*3*5*7*7*7*17*37*97

Since the magic_number initialisation value is 2, we can divide it's final value by 2 :

813659605920 = 2*2*2*2*2*3*3*3*3*3*5*7*7*7*17*37*97

We got 17 numbers... which must be reduced to 6 (the serial has 6 letters)


	3.2. From 17 to 6
	-

2 2 2 2 2 3 3 3 3 3 5 7 7 7 17 37 97
                  
2 2 2 2 2 3 3 3 3 5 7 7 7 17 111 97 (37*3=111)
                        
2 2 2 2 2 3 3 3 3 5 7 7 119 111 97 (17*7=119)
                    
2 2 2 2 2 3 3 3 3 5 49 119 111 97 (7*7=49)
      
2 2 2 3 3 3 60 49 119 111 97 (5*3*2*2=60)

2 2 3 3 3 60 98 119 111 97 (49*2=98)

108 60 98 119 111 97 (2*2*3*3*3=108)

Great ! Now let's find the letters which corresponds to these ASCII values :

=> 'l' '<' 'b' 'w' 'o' 'a'

=> serial = "l<bwoa" (or "bowla<" or ...)



Ŀ
4. Outro 


I wonder WHO made this crackme...


    ________     _______     _______
   /__   __/\   /  ____/\   /  ____/\
   \_/  /\_\/  /  /\___\/  /  /\___\/
    /  / /    /  /_/_     /  / / 
   /  / /    /____  /\   /  / /
  /  / /     \___/ / /  /  / /
 /  / /     ____/ / /  /  /_/_
/  / /     /_____/ /  /______/\
\__\/      \_____\/   \______\/ 30/07/2000

www.tscube.cjb.net
