| 
 | 
I want to explain you how to disable this quite good protection
and, in the second part,
how to perform the real crack of this target!
| 
 | 
| 
 | 
| 
 | 
| 
 | 
Well done mr. McClanahan ! I’ll have to work hard ! And only two days ago I decided to stop smocking !
Quickly searching for an iced beer and for a box of my favourite cigarettes
and I’m ready to restart my study from beginning.
Now I tried  the ‘dead listing approach’ using WDASM and searching, trought
the IMPORTED FUNCTION, for one named EXITWINDOW or EXITWINDOWSEX and, as
you can see, the disassembler
shows me this interesting snippet of code :
* Possible StringData Ref from Data Obj ->"You shouldn't try to crack
shareware, "
                                       
->"what should I do with you?" 
:0040429A 681C594600               
push 0046591C
:0040429F 6A00                           
push 00000000
* Reference To: ADVAPI32.InitiateSystemShutdownA, Ord:00ACh
:004042A1 FF15C8F84600           
Call dword ptr [0046F8C8]
:004042A7 81C4A8000000           
add esp, 000000A8
:004042AD C3                              
ret
:004042AE 6A00                          
push 00000000
:004042B0 6A0D                          
push 0000000D
* Reference To: USER32.ExitWindowsEx, Ord:00CBh                                
|
:004042B2 FF1504FF4600           
Call dword ptr [0046FF04]
:004042B8 81C4A8000000           
add esp, 000000A8
:004042BE C3                              
ret
 
We can, of course, nopping the entire call but the next instruction
that adjusts the stack causes an error of page fault, and so I prefer to
change the CMP/JNE istruction you can find at :00404236
(see the reference).
:00404231 837C242402             
cmp dword ptr [esp + 24], 00000002
:00404236 7576                        
jne 004042AE
like that :
:00404231 C644242402             
mov dword ptr [esp + 24], 02
:00404235 90                            
nop
:00404236 90                            
nop
About the INITIATESYSTEMSHUTDOWNA we can do the same thing but I breakpointed
it, and, I don’t know why, the program never arrives to execute this call
! Strange but true !
We done a good step ahead so get on with it !
Launch the program and have a look at what happens...
Windownload starts and the check routine immediatly close it !
But, finally, it doesn’t reset the computer !
Launch the program again but this time through SoftICE, after breakpointing
the call to the API functions named POSTQUITMESSAGE and POSTMESSAGEA.
Everytime you jump into the ICE check with F4 if the program’s window
is on the screen or not and it will be easy to find out the guilty call
!
Here it is :
* Reference To: USER32.PostMessageA, Ord:01B1h   
:00403DCC FF1508FF4600           
Call dword ptr [0046FF08]
:00403DD2 56                     
push esi
:00403DD3 E8BEBB0200             
call 0042F996
:00403DD8 83C404                 
add esp, 00000004
:00403DDB EB8B                   
jmp 00403D68
Nopping the call is enough to obtain a normal and full functional program,
that now is, more or less, like any other password protected shareware,
and you can work inside it without the loss of time the reboot routine
gives you.
 I reckon this is the most interesting part of my essay 
and I believe that even 
a newbie could now crack this target successfully! 
Anyway, for a little bit of glory
and for those who have a lazy brain I’m going to explain the 
complete reverse
engineering of this program! Naturally you can jump over this second part
and try to do it yourself!
I don’t want to bore you explaining all attempts I’ve made before finding the right way, but you can probably immagine how many they were ! So I’ll explain to you only my last, winning, effort !
If you run a register monitor utility like REGMONEX before launching the program, you can obtain a lot of information about it, but the most interesting one is the underlined below :
Windownl   OpenKey             
HKCU\Software\WinDownload hKey:        
0xC2B94B98          SUCCESS
Windownl   CloseKey             
HKCU\Software\WinDownload                                       
        
SUCCESS
Windownl   QueryValueEx      
0xC2B94B98\Password                                        
              
NOTFOUND
Windownl   CloseKey             
0xC2B94B98                                          
                                
SUCCESS
 
It’s easy to understand what that means? Isn’t it ?
The program looks for a string stored in your register which is, obviously, the password. Knowing that, we can easly hang the execution of the program just before the check routine, by setting a breakpoint each REGQUERYVALUEEX call and watching when the call is refered to the string mentioned above!
To understand this you have to know how the call at this API function
works :
Look at this snippet of code taken from the file WINDOWNLOAD.EXE :
:004498B9 50                     
push eax                              
;  the parameters
:004498BA 57                     
push edi                              
;  passed to the call
:004498BB 51                     
push ecx                             
;  by the stack
:004498BC 57                     
push edi
:004498BD FF7510                 
push [ebp+10]                 
;  look at this value
:004498C0 56                     
push esi
* Reference To: ADVAPI32.RegQueryValueExA, Ord:0136h
:004498C1 FF15C0F84600           
Call dword ptr [0046F8C0]
:004498C7 8BD8                   
mov ebx, eax
:004498C9 85DB                   
test ebx, ebx
:004498CB 752B                   
jne 004498F8
 
The last value but one pushed into the stack is an indirect address
where you can find the string that the query are looking for, and, in particulary,
we must pay attention to it !
Well, all right ? Let’s open an iced beer and...go on in the right order !
The first thing to do is to open the REGEDIT.EXE and to create a subkey called ‘PASSWORD’ into the key HKEY_CURRENT_USER/Software/Windownload exactly where the program espects to find it, if not, the application will jump over the heart of the code where the checking routine is executed, and we will not be able to examine it ! And, logically, you must stuff it with a string you prefer, as well !
Next step is to run your SoftICE and breakpoint the REGQUERYVALUEEXA ( to do this remember to include in your WINICE.DAT the following string : EXP=C:\Windows\System\Advapi.dll ) and every time ICE stops, simply press F-12 to return from the call.
Just after ...25 or 30 times (patience is a great quality for a cracker), when your ashtray is full of cigarettes, you finally find out what you’re looking for exactly in the same snippet of code I used as my example before :
:004498BD FF7510                 
push [ebp+10]                 
;  look at this value
:004498C0 56                         
push esi
* Reference To: ADVAPI32.RegQueryValueExA, Ord:0136h
:004498C1 FF15C0F84600           
Call dword ptr [0046F8C0]
Really, you’ll land here two or three times, but you have to check where
the address stored in [ebp+10] point to, (use the Dump command), because
only when you find the occurance of string ‘PASSWORD’ you are at the end
of your effort !
Soon after you can see another call like the previous one because the
program, before, tests if the subkey is present and only if it is the next
one gets the value stored in.
C’mon guys ! We are on the right way !
After a few STEP (F-10) we arrive more or less here :
:00403923 E878FAFFFF             
call 004033A0
:00403928 8B00                   
mov eax, dword ptr [eax]
:0040392A 8B4DDC                 
mov ecx, dword ptr [ebp-24]
:0040392D C645FC04               
mov [ebp-04], 04
:00403931 8B40F8                 
mov eax, dword ptr [eax-08]
:00403934 8B11                   
mov edx, dword ptr [ecx]
:00403936 C645FC01               
mov [ebp-04], 01
:0040393A 2B42F8                 
sub eax, dword ptr [edx-08]                        
; Check if your key’s lenght
:0040393D 83F801                 
cmp eax, 00000001                                     
; are as the right one
:00403940 1BC0                   
sbb eax, eax                                         !
;        
; 0 = OK let’s go on !
:00403942 40                     
inc eax           
ß 1 = Bye ! Bye !
:00403943 8945D8                 
mov dword ptr [ebp-28], eax
:00403946 E80A030000             
call 00403C55
:0040394B 837DD800               
cmp dword ptr [ebp-28], 00000000
:0040394F 744F                   
je 004039A0
We are, now, in front of the first check the program made between your wrong key and it’s right one using the length of the string, so if you entered a password with a non correct number of chars you have to modify the flag Z ( r fl z in the command line of SoftICE) before the JE instruction at address 0040394F and you’d take note of the instructions just above the jump (this time it’s not necessary because I’ve done it for you !) .
After a little thinking about how to change the code in a permanent way I decided to proceed as follows to prevent a possible joke by the program more ahead.
:0040393D 83F801                
cmp eax, 00000001
:00403940 1BC0                    
sbb eax, eax
:00403942 40                         
inc eax
Change to :
:0040393D B800000000        
mov eax, 00000000
:00403942  90                        
nop
Let’s go on ! (I have my third beer).
If you correctly do the jump and advance a little you’ll find yourself here :
:00403A1D E87EF9FFFF             
call 004033A0
:00403A22 C645FC08               
mov [ebp-04], 08
:00403A26 8B4DDC                 
mov ecx, dword ptr [ebp-24]
:00403A29 8B55F0                 
mov edx, dword ptr [ebp-10]
:00403A2C 8B19                   
mov ebx, dword ptr [ecx]
:00403A2E C645FC01               
mov [ebp-04], 01
:00403A32 8A0C13                 
mov cl, byte ptr [ebx + edx]                    
; Get one byte of your key
:00403A35 884DEC                 
mov byte ptr [ebp-14], cl       ; Store it
in a temporary address
:00403A38 8B00                   
mov eax, dword ptr [eax]
:00403A3A 8B55F0                 
mov edx, dword ptr [ebp-10]
:00403A3D 320C10                 
xor cl, byte ptr [eax + edx]                      
; Check it with the right key
:00403A40 884DEC                 
mov byte ptr [ebp-14], cl                         
; Store it in a temporary address
:00403A43 E867000000             
call 00403AAF
:00403A48 0FBE4DEC               
movsx ecx, byte ptr [ebp-14]
:00403A4C 85C9                   
test ecx, ecx                                        &nbs!
p;      
; Test if the result is 0
:00403A4E 7508                   
jne 00403A58         ß if
not jump out
:00403A50 FF45F0                 
inc [ebp-10]                                         !
;     
; If yes  increase the pointer and repeat
:00403A53 E94FFFFFFF             
jmp 004039A7
This is the heart of the test routine and you can notice the strange way to compare the single item.
Only if the two chars are the same the XOR instruction give back the 0 result it’s waiting for, and so, we have to change it with XOR [ebx + edx] in so as now the program compare your password with itself indipendently of whatever it is, and give us the green trafic light !
I wanna underline that you can find the right password of your copy of WINDOWNLOAD, simply searching where the register EAX + EBX are pointing to when you arrive just before the first XOR instruction, but I dont’ work for a warez site, and I like to reverse the code to the end and make it completely functional with every password.
Follow me ! There’s only a few streets to walk !
Now we’ll encounter only another two hurdle before winning our match !
Here they are :
The 1st
:00403AEA E8C1810100             
call 0041BCB0                              
; Compare the two string
:00403AEF C645FC01               
mov [ebp-04], 01
:00403AF3 83C408                 
add esp, 00000008
:00403AF6 83F801                 
cmp eax, 00000001
:00403AF9 1BC0                   
sbb eax, eax
:00403AFB 40                     
inc eax
:00403AFC 8945D8                 
mov dword ptr [ebp-28], eax              
; Store the result temporarly
:00403AFF E831010000             
call 00403C35
:00403B04 837DD800               
cmp dword ptr [ebp-28], 00000000       
; Zero ? OK !
:00403B08 744F                   
je 00403B59
The 2nd
:0403B8C E81F810100             
call 0041BCB0                              
; Compare the two string
:00403B91 83C408                 
add esp, 00000008
:00403B94 8B4DE4                 
mov ecx, dword ptr [ebp-1C]
:00403B97 C645FC01               
mov [ebp-04], 01
:00403B9B 83F801                 
cmp eax, 00000001
:00403B9E 194DE4                 
sbb dword ptr [ebp-1C], ecx
:00403BA1 F75DE4                 
neg [ebp-1C]
:00403BA4 E87C000000             
call 00403C25
:00403BA9 837DE400               
cmp dword ptr [ebp-1C], 00000000      ; Zero ?
BAD !
:00403BAD 741F                   
je 00403BCE
:00403BAF C645FC00               
mov [ebp-04], 00
In both cases the program uses a little subroutine to compare two strings
but if you disassemble the file with WDASM you can observe that, that call
is used in many other sides of the program and so we can’t modify it or
the results it gives back !
The only thing to do is to change the answer of the program in front
of a bad result by modifing it after the call, as shown below :
About the first you have to nopping the INC EAX instruction to obtain
a zero result !
:00403AFB 40                     
inc eax              
Change to :        00403AFB  90       
nop
About the second it’s unnecessary to work around the result, it’s enough
to change the jump instruction with a (typical nopping) INC EAX, DEC EAX
:00403BAD 741F                   
je 00403BCE    Change to :      
00403BAD   40    inc eax
                                          
                                          
            
00403BAE   48    dec eax
 
| 
 | 
I hope you’ll find my essay interesting and helpful!
Thanks to all who helped me to bring about my little work
with their great tutorials and essays, death to all the useless wannabye 
crackers groups 
that don't teach anything and only leech material from the good sites
 
Search : Change :
C645FC012B42F883F8011BC040                     
B80000000090
884DEC8B008B55F0320C10884D                    
320C13
C645FC0183C40883F8011BC040                     
B80000000090
837DE400741FC645FC00E8AD00                    
4048
85C00F8487000000837C2424027576                
C6442424029090
FF1508FF460056E8BEBB0200                         
404840484048
| 
 |