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


                      ͻ
                        Tutorial for fuzzyCaT crackme #1   
                      ͼ


note : this tutorial is for the crackme called 'CrkMe[Native].exe'


Ŀ
1.Intro 


My first VB keygen which doesn't use Smartcheck, I hope there will be others ;)

I must warn you that i'll use ideas that can be called 'totally crazy and only good for simple
minded people'... but they work. If you have better ways to do it, just make a tut or shut up ;)



Ŀ
2. A few words before starting 



	2.1. Unpacking
	

Since it's not possible to use WDASM / Smartcheck on a packed program, we'll have to unpack
it first. The crackme is packed with UPX 1.01, which is one of the last version of this 
excellent (and free) packer, so grab UPX and type:

'UPX -d CrkMe[Native].exe'

that's all for the unpacking part.


	2.2. WDASM and SICE
	

Fuzzycat says : "Dont try to use Smartcheck"... and he's right because Smartcheck crashes when
you try to run the crackme. OK, we're gonna do it the 'classic' way, with WDASM and SICE.


		2.2.1. The WDASM patch
		

If you use WDASM on a VB proggy, you won't have any Stringreferences, because Visual Basic uses
the Wide Char format ( 'T' 0x00 'S' 0x00 'C'  instead of  'T' 'S' 'C').

Luckily, our friend Duelist made a patch for WDASM that makes it possible to view these strings :
get in now from protools.cjb.net


		2.2.2. SICE configuration
		

Just add these 2 lines in your 'winice.dat' to be able to set breakpoints on VB functions :

EXP=c:\windows\system\Msvbvm50.dll
EXP=c:\windows\system\Msvbvm60.dll



Ŀ
3. Time for a dead listing 



	3.1. the dead listing
	

Here is the part of the dead listing that interests us :

<-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->
* Reference To: MSVBVM60.__vbaVarForInit, Ord:0000h
                                  |
:00407940 E86599FFFF              Call 004012AA => oh my god, there is a function to 
                                                   initialise a 'for' loop !!!

begin_for_loop
--------------

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004079F7(U)
|
:00407945 3BC6                    cmp eax, esi
:00407947 0F84AF000000            je 004079FC -> exit_loop
:0040794D 8B450C                  mov eax, dword ptr [ebp+0C]
:00407950 898524FFFFFF            mov dword ptr [ebp+FFFFFF24], eax
:00407956 C7851CFFFFFF08400000    mov dword ptr [ebp+FFFFFF1C], 00004008
:00407960 8D45D4                  lea eax, dword ptr [ebp-2C]
:00407963 50                      push eax

* Reference To: MSVBVM60.__vbaI4Var, Ord:0000h
                                  |
:00407964 E82399FFFF              Call 0040128C
:00407969 50                      push eax
:0040796A 8D851CFFFFFF            lea eax, dword ptr [ebp+FFFFFF1C]
:00407970 50                      push eax
:00407971 8D855CFFFFFF            lea eax, dword ptr [ebp+FFFFFF5C]
:00407977 50                      push eax

* Reference To: MSVBVM60.__vbaStrMove, Ord:026Bh
                                  |
:00407978 E81599FFFF              Call 00401292
:0040797D 8D855CFFFFFF            lea eax, dword ptr [ebp+FFFFFF5C]
:00407983 50                      push eax
:00407984 8D8570FFFFFF            lea eax, dword ptr [ebp+FFFFFF70]
:0040798A 50                      push eax -> points to letters of the name

* Reference To: MSVBVM60.__vbaStrVarVal, Ord:0000h
                                  |
:0040798B E80899FFFF              Call 00401298 => converts letter to ASCII value
:00407990 50                      push eax

* Reference To: MSVBVM60.__vbaFreeObjList, Ord:0204h
                                  |
:00407991 E80899FFFF              Call 0040129E
:00407996 66898514FFFFFF          mov word ptr [ebp+FFFFFF14], ax
:0040799D 89BD0CFFFFFF            mov dword ptr [ebp+FFFFFF0C], edi
:004079A3 8D8574FFFFFF            lea eax, dword ptr [ebp+FFFFFF74]
:004079A9 50                      push eax
:004079AA 8D850CFFFFFF            lea eax, dword ptr [ebp+FFFFFF0C]
:004079B0 50                      push eax
:004079B1 8D854CFFFFFF            lea eax, dword ptr [ebp+FFFFFF4C]
:004079B7 50                      push eax

* Reference To: MSVBVM60.__vbaVarAdd, Ord:0000h
                                  |
:004079B8 E8E798FFFF              Call 004012A4 => adds the ASCII values of the name
:004079BD 8BD0                    mov edx, eax
:004079BF 8D8D74FFFFFF            lea ecx, dword ptr [ebp+FFFFFF74]

[SNIP]

* Reference To: MSVBVM60.__vbaVarForNext, Ord:0000h
                                  |
:004079F2 E88998FFFF              Call 00401280
:004079F7 E949FFFFFF              jmp 00407945

end_for_loop
-------------


* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407947(C)
|
:004079FC 6A01                    push 00000001

* Reference To: MSVBVM60.__vbaOnError, Ord:0000h
                                  |
:004079FE E87798FFFF              Call 0040127A
:00407A03 C78524FFFFFF84B80000    mov dword ptr [ebp+FFFFFF24], 0000B884
:00407A0D C7851CFFFFFF03000000    mov dword ptr [ebp+FFFFFF1C], 00000003
:00407A17 DD0598114000            fld qword ptr [00401198]
:00407A1D DD9D14FFFFFF            fstp qword ptr [ebp+FFFFFF14]
:00407A23 C7850CFFFFFF05000000    mov dword ptr [ebp+FFFFFF0C], 00000005
:00407A2D C78504FFFFFF06000000    mov dword ptr [ebp+FFFFFF04], 00000006
:00407A37 89BDFCFEFFFF            mov dword ptr [ebp+FFFFFEFC], edi
:00407A3D 8D8574FFFFFF            lea eax, dword ptr [ebp+FFFFFF74]
:00407A43 50                      push eax
:00407A44 8D851CFFFFFF            lea eax, dword ptr [ebp+FFFFFF1C]
:00407A4A 50                      push eax
:00407A4B 8D855CFFFFFF            lea eax, dword ptr [ebp+FFFFFF5C]
:00407A51 50                      push eax

* Reference To: MSVBVM60.__vbaVarMul, Ord:0000h
                                  |
:00407A52 E81798FFFF              Call 0040126E
:00407A57 50                      push eax
:00407A58 8D45AC                  lea eax, dword ptr [ebp-54]
:00407A5B 50                      push eax
:00407A5C 8D850CFFFFFF            lea eax, dword ptr [ebp+FFFFFF0C]
:00407A62 50                      push eax
:00407A63 8D854CFFFFFF            lea eax, dword ptr [ebp+FFFFFF4C]
:00407A69 50                      push eax

* Reference To: MSVBVM60.__vbaVarMul, Ord:0000h
                                  |
:00407A6A E8FF97FFFF              Call 0040126E
:00407A6F 50                      push eax
:00407A70 8D85FCFEFFFF            lea eax, dword ptr [ebp+FFFFFEFC]
:00407A76 50                      push eax
:00407A77 8D853CFFFFFF            lea eax, dword ptr [ebp+FFFFFF3C]
:00407A7D 50                      push eax

* Reference To: MSVBVM60.__vbaVarDiv, Ord:0000h
                                  |
:00407A7E E8E597FFFF              Call 00401268
:00407A83 50                      push eax
:00407A84 8D852CFFFFFF            lea eax, dword ptr [ebp+FFFFFF2C]
:00407A8A 50                      push eax

* Reference To: MSVBVM60.__vbaVarIdiv, Ord:0000h
                                  |
:00407A8B E8E497FFFF              Call 00401274
:00407A90 50                      push eax

* Reference To: MSVBVM60.__vbaStrVarMove, Ord:0000h
                                  |
:00407A91 E86E98FFFF              Call 00401304
:00407A96 8BD0                    mov edx, eax
:00407A98 8D4DBC                  lea ecx, dword ptr [ebp-44]

* Reference To: MSVBVM60.__vbaStrMove, Ord:0000h
                                  |
:00407A9B E86A98FFFF              Call 0040130A
:00407AA0 FF7584                  push [ebp-7C] -> @ of entered_serial
:00407AA3 FF75BC                  push [ebp-44] -> @ of correct_serial

* Reference To: MSVBVM60.__vbaStrCmp, Ord:0000h
                                  |
:00407AA6 E8B797FFFF              Call 00401262
:00407AAB 85C0                    test eax, eax
:00407AAD 757E                    jne 00407B2D -> fuck off
:00407AAF B904000280              mov ecx, 80020004
:00407AB4 898D34FFFFFF            mov dword ptr [ebp+FFFFFF34], ecx
:00407ABA 6A0A                    push 0000000A
:00407ABC 58                      pop eax
:00407ABD 89852CFFFFFF            mov dword ptr [ebp+FFFFFF2C], eax
:00407AC3 898D44FFFFFF            mov dword ptr [ebp+FFFFFF44], ecx
:00407AC9 89853CFFFFFF            mov dword ptr [ebp+FFFFFF3C], eax

* Possible StringData Ref from Code Obj ->"Kool!!"
                                  |
:00407ACF C78514FFFFFFB82A4000    mov dword ptr [ebp+FFFFFF14], 00402AB8
:00407AD9 899D0CFFFFFF            mov dword ptr [ebp+FFFFFF0C], ebx
<-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->


	3.2. The serial
	

If you're happy with a serial, no problem :

:00407AA0 FF7584                  push [ebp-7C] -> @ of entered_serial
:00407AA3 FF75BC                  push [ebp-44] -> @ of correct_serial
:00407AA6 E8B797FFFF              Call 00401262 __vbaStrCmp

Type 'D EBP-74' and you'll see a DWORD in your data window (it's the @ of the correct_serial)

=> 18 06 41 00

Type 'D 410618' (you'll have another value) and you'll see your serial in Wide Char Format

name   : TSCube
serial : 8659933

If you're a keygener, keep reading ! ;)



Ŀ
4. The keygen 



	4.1. the VARIANT data type
	

		4.1.1. Intro
	       
<<
The Variant data type is a special data type that can contain numeric, string, or date data as 
well as user-defined types and the special values Empty and Null. The Variant data type has a 
numeric storage size of 16 bytes and can contain data up to the range of a Decimal, or a 
character storage size of 22 bytes (plus string length), and can store any character text. 
>>

That's why I don't like VB very much : a lot of people only use the VARIANT data type and
VB spends it's time converting from Variant to Integers, from Variant to String etc...
what a waste ot time !!!

This crackme makes eavy use of the VARIANT data type, look at this :

:004079B8 E8E798FFFF              Call 004012A4 -> MSVBVM60.__vbaVarAdd (adds 2 VARIANT)
:00407A52 E81798FFFF              Call 0040126E -> MSVBVM60.__vbaVarMul (multiplies)
:00407A7E E8E597FFFF              Call 00401268 -> MSVBVM60.__vbaVarDiv (divides)
:00407A8B E8E497FFFF              Call 00401274 -> MSVBVM60.__vbaVarIdiv (divides)

There is a BIG trouble with the VARIANT type : when you type with SICE 'd @_of_variant', you
see only a bunch of bytes (16 to be exact ;) and you can't tell the value of this variant.
I know there is a direct way to know the numeric value of a VARIANT (after all, Smartcheck knows 
it), but I didn't manage to find it yet.


		4.1.2. Finding the value of a VARIANT
		

But to make this keygen, we NEED to know the numeric values of the VARIANTs used by the crackme,
so how are we going to do it ? Well, I found a way to do it ... it is a BAD way... but it works. 
Here it is :

The VB function __vbaI4Var can convert a VARIANT to an INTEGER (only if the VARIANT represents
an integer, of course ;) . It works like this :

PUSH @_of_VARIANT
CALL MSVBVM60.__vbaI4Var -> when returning, EAX will contain the value of the VARIANT

So, If when you trace with SICE, you need to know the value of the variant, do it like this :

a (to start assembling code)
MOV EAX, @_of_VARIANT (usually, it is MOV EAX, DWORD PTR[EBP-XX])
PUSH EAX
CALL MSVBVM60!__vbaI4Var
(hit enter 2 times to end)

Now hit F10 3 times, note the value of EAX, hit F5... and let the crackme crashes (!!!).


	4.2. The 'for' loop
	

Using your brain can be quite effective, for example, you can see that this loop uses the
__vbaVarAdd function... and that it loops strlen(name) times.

So, if you're not too drunk ( sorry to tell this, but I DON'T drink beer and i don't listen to
hard rock : I drink nothing and right now, I'm listening to some good old rock'n roll), it's
a good idea to suppose that the crackme adds the ASCII values of your name.

In case you don't agree, I suggest you use my (C) "VARIANT to INTEGER method" just after the
__vbaVarAdd function (@4079B8) and you'll see that EAX really contains the sum of the ASCII
values.


	4.3. First multiplication
	

:00407A3D 8D8574FFFFFF            lea eax, dword ptr [ebp+FFFFFF74] -> sum of ASCII values
:00407A43 50                      push eax
:00407A44 8D851CFFFFFF            lea eax, dword ptr [ebp+FFFFFF1C] -> 0xB884

(look at @407A03 to see where this value comes from) 

:00407A4A 50                      push eax
:00407A4B 8D855CFFFFFF            lea eax, dword ptr [ebp+FFFFFF5C] -> result will be stored here
:00407A51 50                      push eax

* Reference To: MSVBVM60.__vbaVarMul, Ord:0000h
                                  |
:00407A52 E81798FFFF              Call 0040126E


=> result1 = sum_of_ASCII_values * 0xB884


	4.4. Second multiplication
	

:00407A58 8D45AC                  lea eax, dword ptr [ebp-54]		-> strlen(name)
:00407A5B 50                      push eax
:00407A5C 8D850CFFFFFF            lea eax, dword ptr [ebp+FFFFFF0C]	-> 3.14
:00407A62 50                      push eax

look at @407A1D to see where this value comes from, and don't forget to type 'WF' in SICE to see
the FPU window)

:00407A63 8D854CFFFFFF            lea eax, dword ptr [ebp+FFFFFF4C]
:00407A69 50                      push eax

* Reference To: MSVBVM60.__vbaVarMul, Ord:0000h
                                  |
:00407A6A E8FF97FFFF              Call 0040126E


=> result2 = strlen(name) * 3.14


	4.5. First division
	

:00407A6F 50                      push eax -> this is the result from the second multiplication
:00407A70 8D85FCFEFFFF            lea eax, dword ptr [ebp+FFFFFEFC] -> this a constant value
                                                                       equals to 6
:00407A76 50                      push eax
:00407A77 8D853CFFFFFF            lea eax, dword ptr [ebp+FFFFFF3C]
:00407A7D 50                      push eax

* Reference To: MSVBVM60.__vbaVarDiv, Ord:0000h
                                  |
:00407A7E E8E597FFFF              Call 00401268

=> result3 = result2 / 6


	4.6. Second division
	

:00407A83 50                      push eax -> -> this is the result from the first division
:00407A84 8D852CFFFFFF            lea eax, dword ptr [ebp+FFFFFF2C] -> this is the result from
                                                                       the first multiplcation
:00407A8A 50                      push eax

* Reference To: MSVBVM60.__vbaVarIdiv, Ord:0000h
                                  |
:00407A8B E8E497FFFF              Call 00401274

=> serial = result1 / result3 (don't ask my why the operands are reversed ;)

The rest of the code converts this value to a string.


	4.7. The keygen
	

Now you can easily make a keygen. I've not mentioned the need to round the results of the
multiplications/additions to integers, because it depends on the language used for the
keygen.

For example, my (C) Javascript keygen uses floor() and ceil().



Ŀ
5. Outro 


I just wanted to say that I'm happy to see that CiA is back... any trial crackme for me ? ;)

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

www.tscube.cjb.net