November 1998
"CD Wizzard V4.61"
( 'Sniffing out the serial generator routine'  )
Win '95 PROGRAM
Win Code Reversing
 
 
by The snake 
 
 
Code Reversing For Beginners 
 
 
 
  
 
CD Wizzard V4.61
('Sniffing out the serial generator routine'  )
Written by The snake
 
 
 
   
As an adition to Sandman's essay #43 about CD Wizzard, and as I decided to take the challenge of his final notes about "Perhaps someone will do this and send their essay on how to register the program via a serial", here is what i've found out about DC Wizzard serial generating routine.
 
About this serial routine
 
In the Essay part of the essay, we can see this pice of snippet code :
 
:00414606 E8AC0D0000             call 004153B7 ;Process the serial no's
:0041460B 83C40C                 add esp, 0000000C
:0041460E 85C0                   test eax, eax ;Serial ok?
:00414610 741C                   je 0041462E   ;no? then beggar off cracker
:00414612 6A40                   push 00000040 ;serial valid then continue
:00414614 C705C0E0430001000000   mov dword ptr [0043E0C0], 00000001
:0041461E FF15F8124300           Call USER32.MessageBeep
:00414624 6A40                   push 00000040
:00414626 57                     push edi

From this code snippet we can see at memory location 414606 the call to the routine that generates the real serial number.

The disassembly listing sohws us this code :-
 
* Referenced by a CALL at Addresses:
|:00414379 , :00414507 , :00414AE3 , :00415027 , :0041510D
|:00415298 , :004153C9 , :00415468
|
:00415381 8B542408             mov edx, dword ptr [esp+08] ; length of name
:00415385 53                   push ebx
:00415386 56                   push esi                    ;  our name
:00415387 8B74240C             mov esi, dword ptr [esp+0C] ;  name adress
:0041538B 57                   push edi
:0041538C 8D0432               lea eax, dword ptr [edx+esi]
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00415397(U)
|
:0041538F 8078FF20               cmp byte ptr [eax-01], 20 ; blanks at end?
:00415393 7504                   jne 00415399              ; no blanks
:00415395 4A                     dec edx
:00415396 48                     dec eax
:00415397 EBF6                   jmp 0041538F              ; blanks found
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00415393(C)
|
:00415399 33C0                   xor eax, eax              ; reset aex
:0041539B 33C9                   xor ecx, ecx
:0041539D 85D2                   test edx, edx             ; name empty?
:0041539F 7E12                   jle 004153B3 

Here is the loop that generates the code letter after letter:
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004153B1(C)
|
:004153A1 660FBE3C31             movsx di, byte ptr [ecx+esi]
:004153A6 8D5902                 lea ebx, dword ptr [ecx+02]
:004153A9 0FAFFB                 imul edi, ebx
:004153AC 03C7                   add eax, edi
:004153AE 41                     inc ecx
:004153AF 3BCA                   cmp ecx, edx
:004153B1 7CEE                   jl 004153A1
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041539F(C)
|
:004153B3 5F                     pop edi
:004153B4 5E                     pop esi
:004153B5 5B                     pop ebx
:004153B6 C3                     ret
 
* Referenced by a CALL at Addresses:        We land here from the call !!
|:00401C4C , :00414606
|
:004153B7 837C240808             cmp dword ptr [esp+08], 00000008&
:004153BC 7D03                   jge 004153C1             ; name is < 8
:004153BE 33C0                   xor eax, eax
:004153C0 C3                     ret
 
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004153BC(C)
|
:004153C1 FF742408               push [esp+08]
:004153C5 FF742408               push [esp+08]
:004153C9 E8B3FFFFFF             call 00415381
:004153CE 6BC00B                 imul eax, 0000000B      ; serial * 11 (hex)
:004153D1 59                     pop ecx
:004153D2 0FB7C0                 movzx eax, ax           ; al = 0000 !!!!
:004153D5 59                     pop ecx
:004153D6 6A07                   push 00000007
:004153D8 99                     cdq
:004153D9 59                     pop ecx
:004153DA F7F9                   idiv ecx                ; sn = sn / 7
:004153DC 33C9                   xor ecx, ecx
:004153DE 663944240C             cmp word ptr [esp+0C], ax ; sn ok ??
:004153E3 0F94C1                 sete cl                 ; if sn ok , cl=1
:004153E6 8BC1                   mov eax, ecx            ; 0 or 1
:004153E8 C3                     ret
   
now, lets go back to the call that send us to generates the code :
 
:00414606 E8AC0D0000             call 004153B7 ;Process the serial no's
:0041460B 83C40C                 add esp, 0000000C
:0041460E 85C0                   test eax, eax ;Serial ok?
:00414610 741C                   je 0041462E   ;no? then beggar off cracker
:00414612 6A40                   push 00000040 ;serial valid then continue
:00414614 C705C0E0430001000000   mov dword ptr [0043E0C0], 00000001
   
Ok, this is the code, let have some words about the main routine :

The loop moving one letter at a time to di. then it put a value from 2 to 10 in ebx. the hex value of the letter is mul by the value in ebx. aex is the sum register to all the letters calculation. when ecx count the last letter, the loop is finished.
 
Intresting instraction is at location :004153D2 0FB7C0 movzx eax, ax , the code is like cut, the low byte of eax get zero, and the code left in high byte is the one to register with.
 
Final Notes
 
There is not mutch to say about this routine, i've found it easy to follow.
 
 
My thanks and gratitude goes to:-
 
The Sandman for all that he is doing for us, newbies.
 
Rhayader for helping me with Reverse Code Engineering and
useful tips
 


 
 
 Back to Students Essay's 
 


Essay by:            The snake
Page Created: 26th November 1998