|
|
|
|
|
|
|
|
|
|
||
|
||
|
|
There is a crack, a crack in everything. That's how the light gets in. |
|
There are three versions of RAR for Windows:
- console version for Windows 95 and Windows
NT
- version with Windows 3.1 standard user
interface for Windows 3.1 with Win32s installed,
Windows 95 and Windows NT
- version with Windows 95 user interface
for Windows 95 (WinRAR 95)
|
Your name or registration (AV) text has
the first 5 characters encrypted, these 5 encrypted characters are compared
with 5 encrypted serial numbers. I will show you as much as I know on this,
hopefully someone who knows something can help me with the final manipulation
of the serial.
|
Install WinRar and fire it up. We are at the main program interface with the title WinRAR (Evaluation Copy). Under options go to Registration.
Enter your name in the registration (AV)
text: The Headlesschickens
Enter your registration code: 9999999999
Press OK, it comes up registration failed, yep as usual the program has a bug *grin*, lets fix that so it says thanks good cracker.
Where to start, well as i'm just beginning I have trouble getting the overall picture with WinIce so I use WinIce in conjunction with a dead listing from W32Dasm V8.9, it just helps me follow things through when tracing through the code in WinIce. So if you wan't go ahead and make a dead listing but if not you can still follow this tut as I have done the hard work for you.
Go back to the registration screen and enter a name and serial. Now we want to break into the code and see whats going on, I use either getwindowtexta, getdlgitemtexta, hmemcpy, messageboxa. Usually i will break in at the start with something like getdlgitemtexta then mark on my deadlisting where it goes from here, then break in at the messagebox error, mark on my deadlisting where this is and work backwards. I usually end somewhere in the middle and it gives me a good complete picture of the protection scheme.
After you have entered your name and serial Press Ctrl-D at the same time to pop up WinIce. We want to break when the program gets our name and serial then follow it through. For this we can set a breakpoint on getdlgitemtexta, how do i know, well i just try either the previous one or getwindowtexta, if that doesn't work the i use hmemcpy.
Type in BPX getdlgitemtexta DO "d esp->C;"
then press enter to activate our breakpoint
(This will set a breakpoint on the windows
API function getdlgitemtexta)
PS: I know nothing about windows programing except what little I have picked up from some cracking tuts, if i have said something wrong about breakpoints or API's please feel free to correct me or edit this tut.
Press F5 to go back to our program. Press OK to register. We land back in WinIce at our breakpoint. Press F12, which is return to caller and pause. Down the bottom of the WinIce code screen you will see WINRAR95 CODE!0001234 or something like this, the important part is to look for the winrar95, this tells us we are in the winrar code. Also see in the data window of WinIce our name appears, this is from the breakpoint command DO "d esp->c;" this part of the command saves us from having to search where our name is first stored, if we wan't we could now set a breakpoint on range of the name and follow what happens without having to step through all the code, i usually get lost without my deadlisting when i do this but i guess its just experience.
Press F5 again and WinInce will break again, Press F12 to get back to the caller. This is done twice because the program has to get our name then our serial number. You now will see your serial number in the data window if everything is working alright. The more experienced cracker would now put a BPR (break point range) on the serial as well then follow from there. Seem we are learning we will just step through and follow what happens.
We land here after our net breakpoint return:
* Reference To: USER32.GetDlgItemTextA, Ord:0000h
:00413C31 E8000D0100
Call 00424936
:00413C36 80BD54FFFFFF00
cmp byte ptr [ebp+FFFFFF54], 00 ;We land here, check
;check we have entered
:00413C3D 751A
jne 00413C59 ;a serial number then
;jumps if we have.
Jump to here from above:
* Referenced by a (U)nconditional
or (C)onditional Jump at Address:
|:00413C3D(C)
|
:00413C59 8D559C
lea edx, dword ptr [ebp-64]
:00413C5C 52
push edx
:00413C5D 6830AD4200
push 0042AD30
:00413C62 E839920000
call 0041CEA0
:00413C67 83C408
add esp, 00000008
:00413C6A 8D8D54FFFFFF
lea ecx, dword ptr [ebp+FFFFFF54]
:00413C70 51
push ecx
:00413C71 8D459C
lea eax, dword ptr [ebp-64]
:00413C74 50
push eax
:00413C75 E84768FFFF
call 0040A4C1
:00413C7A 83C408
add esp, 00000008
:00413C7D 85C0
test eax, eax
:00413C7F 7532
jne 00413CB3
Now we some pushes and a call, is this
call important, to check lets see what is getting pushed onto the stack.
F10 until you are on the line:
:00413C5C 52
push edx
type in Softice: d edx
look in the data window of SI and we see our name, so our name is going to have something done to it in this call
Lets trace into this call and see whats
happening. F10 until you are at :00413C62
E839920000
call 0041CEA0
Press F8 to trace into this call, we see below:
|:0041A579
, :0041A66D , :0041A7BC , :0041BA8A
, :0041BAA8
|:0041BAC6
, :0041BB35 , :0041BB73 , :0041BB9C
, :0041BBC2
|:0041BD40
, :0041BD65 , :0041BD83 , :0041BDB6
, :0041BDD4
|:0041BDF2
, :0041C1D2 , :0041C4CA , :0041CA1F
, :0041CA3A
|:0041CA55
, :0041CA70 , :0041CA8B
|
:0041CEA0 55
push ebp
:0041CEA1 8BEC
mov ebp, esp
:0041CEA3 56
push esi
:0041CEA4 57
push edi
:0041CEA5 8B7D0C
mov edi, dword ptr [ebp+0C] ;move the address of my name
;into edi
:0041CEA8 8BF7
mov esi, edi ; move
the address of my name into esi
:0041CEAA B9FFFFFFFF
mov ecx, FFFFFFFF ecx ;is our counter register and will
;end up with the len of our name
:0041CEAF 32C0
xor al, al
;length of our name in hex
:0041CEB1 FC
cld
:0041CEB2 F2
repnz
:0041CEB3 AE
scasb ; repeat while not zero scan our name
:0041CEB4 F7D1
not ecx ; ecx is negative so to get the length we have
; to neg it (-(-ecx) = ecx)
:0041CEB6 8B7D08
mov edi, dword ptr [ebp+08] ; move address where name
;will be copied to edi
:0041CEB9 8BC7
mov eax, edi
:0041CEBB 8BD1
mov edx, ecx
:0041CEBD D1E9
shr ecx, 1
:0041CEBF D1E9
shr ecx, 1
:0041CEC1 FC
cld ;clear direction flag so it increments
forward
:0041CEC2 F3
repz
:0041CEC3 A5
movsd ;move data to new memory area pointed
to by es:edi
:0041CEC4 8BCA
mov ecx, edx
:0041CEC6 83E103
and ecx, 00000003
:0041CEC9 F3
repz
:0041CECA A4
movsb
:0041CECB 5F
pop edi ;restore registers then return
:0041CECC 5E
pop esi
:0041CECD 5D
pop ebp
:0041CECE C3
ret
This routine scans the length of our name then copies it to another location, so we now have 2 locations in memory for our name. Whenever you see ECX being loaded with FFFFFFFF then repnz then scasb, this is getting the length of something, in this case our name. I have commented each line for you as best as I can.
To really understand what is going on just trace through each line with SI then watch the ecx register and see what happens. Whenever you see repz then movsd, this is a sign that something is being copied to another memory location. Movsd is assembly for move string data, and it copies from what is pointed to by the register ds:esi (source index) to the new address at es:dsi (destiny index). I usually F10 to the movsd the in SI type d es:edi, this will show in the data window the memory area where something is being copied. Press F10 to step over the movsd and watch the data window, whatever was being copied will appear in the data window. The more experienced cracker would now set a BPR on this memory location as well.
Ok trace through the rest of the call to the return, F10 to get back to the main part of the program. We end up here after our call:
:00413C67 83C408
add esp, 00000008 ;clear the stack
:00413C6A 8D8D54FFFFFF
lea ecx, dword ptr [ebp+FFFFFF54] ;load my
;serial
;address
;into ecx
:00413C70 51
push ecx ;push the address onto the stack
:00413C71 8D459C
lea eax, dword ptr [ebp-64] ;load my name
;address into eax
:00413C74 50
push eax ;push
my name address
:00413C75 E84768FFFF
call 0040A4C1 ;must be an important call
:00413C7A 83C408
add esp, 00000008 ;clear stack
:00413C7D 85C0
test eax, eax ;is eax zero or something else
:00413C7F 7532
jne 00413CB3 ;eax =0 don't jump bad cracker
:00413C81 6A30
push 00000030
:00413C83 6A1A
push 0000001A <--"Warning"
:00413C85 E801650000
call 0041A18B
:00413C8A 59
pop ecx
:00413C8B 50
push eax
:00413C8C 6A6A
push 0000006A
:00413C8E E8F8640000
call 0041A18B
:00413C93 59
pop ecx
:00413C94 50
push eax
:00413C95 FF7508
push [ebp+08]
We can see something important is happening, leading up to the next call, our name and serial address are being pushed, you can see this by typing in SI, d ecx when you are at :00413C70 51 push ecx , you will see your serial in the data window of SI, then d eax when you are at :00413C74 50 push eax , you will see your name in the data window of SI.
You can see there is a test eax,eax after the call then a jnz to somewhere, so lets see where this jump goes. Trace down by pressing F10 until you get to :00413C7F 7532 jne 00413CB3. We have traced right over the important call where our name and serial was pushed and landed at this jne 00413cb3 after the test eax,eax. If we look down from here in our deadlisting we see the words Normal, Warning, Registration Failed. Because our test on eax came back zero we will not be taking this jump and heading straight down into all these bad words. So lets not go there.
In SI type RFL Z, this toggles the register flag, so now it isn't zero we will jump instead and see where we go. Press F5 to let the program run. Whoa, Thank you for your support. We have registered it, surely it can't be that easy,well no. Close your program and run it again, damn it is back to being an evaluation copy so we know from this it saves our original name and serial then rechecks everything again when the program runs. Doesn't matter because we also know that after the important call eax must come back with a 1 in it so we will take the jump. We can now concentrate on the important call which as we soon will see encrypts the first 5 letters of our name, manipulates the serial, compares the first 5 encryypted letters of our name with the 5 encrypted serial numbers, flags a memory location to tell the program whether it is registered or not, then pops out eventually with eax set to good guy or bad guy.
Seem we are only patching it the most important part of the routine is to find the compare and where in memory the good guy, bad guy flag gets set. As much as I can I will go through the name manipulation which wasn't to hard, and as much of the serial as I can show you before I got lost.
Go back and register your name and serial, set your bpx getdlgitemtexta, Press F5, Press OK to enter your info at the registration box. Press F12 to return to caller and arrive in the WinRAR code. Now type in SI u 00413c75, this will unassemble in the code window the area where want to stop, double click on this line so that it is highlighted, this means there is a breakpoint set on this line of code. You can check this by typing in SI bl, this will show you what breakpoints you have set. Disable the getdlgitemtexta breakpoint by typing bd0, we don't need it anymore. Press F5 and you should land right on top of our important call just before the test eax,eax and the jne 00413CB3.
Press F8 to trace into this call, I printed
out this call from W32Dasm and ended up with 5 pages of code, somewhere
in here we are going to find what we are looking for, lets trace.
The start important call:
* Referenced by a CALL at Addresses:
|:00408044 , :00413C75
|
:0040A4C1 55
push ebp
:0040A4C2 8BEC
mov ebp, esp
:0040A4C4 81C42CFFFFFF
add esp, FFFFFF2C
:0040A4CA 53
push ebx
:0040A4CB 56
push esi
:0040A4CC 57
push edi
We can see in our deadlisting it is called
from 2 places, 1 from where we have just come at :00413C75. It would be
interesting to see where the other call is from. In W32Dasm click on the
goto button and type the other address :00408044.
We see this:
:0040802C E81FC70100
Call KERNEL32.GetPrivateProfileStringA
:00408031 803D30AD420000
cmp byte ptr [0042AD30], 00
:00408038 7412
je 0040804C
:0040803A 6880AD4200
push 0042AD80 'push our serial
:0040803F 6830AD4200
push 0042AD30 'push my name
:00408044 E878240000
call 0040A4C1 ;Our important call
:00408049 83C408
add esp, 00000008
From sandmans essays we know getprivateprofilestringa gets info from an ini file, in this case our name and serial. This usually is done at the start of a program to recheck if our information is correct. The important thing here is that to check our information at the start of the program it uses the same routine as the registration checking routine. So if we patch that routine in the right place we will have the program registered correctly when we restart the program. This is why after we registered correctly before, then closed the program then restarted it, it still was only an evaluation copy. Lets get back to our important call and crack this babe.
Referenced by a CALL at Addresses:
|:00408044 , :00413C75
|
:0040A4C1 55
push ebp
:0040A4C2 8BEC
mov ebp, esp
:0040A4C4 81C42CFFFFFF
add esp, FFFFFF2C
:0040A4CA 53
push ebx
:0040A4CB 56
push esi
:0040A4CC 57
push edi
* Reference to String Resource ID=00070:
"Authenticity verification FAILED"
:0040A4CD 6A46
push 00000046
:0040A4CF 6A00
push 00000000
:0040A4D1 8D8574FFFFFF
lea eax, dword ptr [ebp+FFFFFF74]
:0040A4D7 50
push eax ;This call is like the movsb
;routine I showed you above,
:0040A4D8 E803290100
call 0041CDE0 ;except it uses stosd, trace into
;it the stop at the stosd.
:0040A4DD 83C40C
add esp, 0000000C
In SI, type d es:edi, F10 and you will see what gets copied.
In this case you will see a whole lot of zeros appear. So this call just clears a memory area. Just like cleaning an area on a whiteboard so you can write something there. It will most probably copy our name or serial here some time soon.
* Possible Reference to Dialog: ARCINFODLG,
CONTROL_ID:0009, "Help"
:0040A4E0 6A09
push 00000009
:0040A4E2 6A00
push 00000000
:0040A4E4 68EFB84200
push 0042B8EF
:0040A4E9 E8F2280100
call 0041CDE0 ;Same call as above,clear memory
;area.
:0040A4EE 83C40C
add esp, 0000000C
:0040A4F1 FF7508
push [ebp+08] ;Push address of my name onto stack
:0040A4F4 8D9574FFFFFF lea edx,
dword ptr [ebp+FFFFFF74]
:0040A4FA 52
push edx ;Address of memory area that
we
;filled with zeros.
:0040A4FB E8A0290100
call 0041CEA0 ;See above on explanation on Call
;0041CEA0, it moves
:0040A500 83C408
add esp, 00000008 ;our name to another memory
;location
:0040A503 FF7508
push [ebp+08]
:0040A506 E8C5290100
call 0041CED0 ;This call gets the length of our
;name similar to Call 0041CEA0
:0040A50B 59
pop ecx
:0040A50C 8945FC
mov dword ptr [ebp-04], eax ;Move length of our
;name into this memory
;area
:0040A50F 85C0
test eax, eax
;Is there a name
;present
:0040A511 7406
je 0040A519
:0040A513 837DFC3C
cmp dword ptr [ebp-04], 0000003C Is it more than
;3C hex long or
:0040A517 7E07
jle 0040A520
;60 characters.
We land here after the check on the length of our name, the next call has all sorts of stuff that I don't understand happening in it but if you look in your deadlisting you can see below the call there are the words warning and Not enough memory for registration. We can make a good guess then that this is just checking memory and is not where we should be checking for our protection.
:0040A520 6800001000
push 00100000
:0040A525 E8468C0100
call 00423170
:0040A52A 59
pop ecx
:0040A52B A33C574200
mov dword ptr [0042573C], eax
:0040A530 85C0
test eax, eax
:0040A532 7529
jne 0040A55D 'Jump here if there is enough memory
:0040A534 6A00
push 00000000
* Possible Reference to String Resource ID=00026: "Warning"
:0040A536 6A1A
push 0000001A
:0040A538 E84EFC0000
call 0041A18B
:0040A53D 59
pop ecx
:0040A53E 50
push eax
*Reference to String "Not enough
memory for registration"
:0040A53F 68BF000000
push 000000BF
:0040A544 E842FC0000
call 0041A18B
:0040A549 59
pop ecx
:0040A54A 50
push eax
:0040A54B FF35A0644200
push dword ptr [004264A0]
We land at the section of code below, this is where things start getting interesting and our code manipulation begins, so here goes, sorry if i haven't explained this very well but i'm struggling to understand key generation myself at this stage.
:0040A55D 8B15F4BE4200
mov edx, dword ptr [0042BEF4]
:0040A563 8955F4
mov dword ptr [ebp-0C], edx
:0040A566 C705F4BE420001000000
mov dword ptr [0042BEF4], 00000001
:0040A570 FF750C
push [ebp+0C] ;Push my serial onto the stack
:0040A573 8D8D2CFFFFFF
lea ecx, dword ptr [ebp+FFFFFF2C]
:0040A579 51
push ecx
:0040A57A E821290100
call 0041CEA0 ;Get the length of our serial.
:0040A57F 83C408
add esp, 00000008
:0040A582 C605EEB8420000
mov byte ptr [0042B8EE], 00
:0040A589 C6050ABF420000
mov byte ptr [0042BF0A], 00 ;Not to sure about
:0040A590 C60509BF420001
mov byte ptr [0042BF09], 01 ;the importance of
:0040A597 C60508BF420002
mov byte ptr [0042BF08], 02 ;moves?
:0040A59E 33C0
xor eax, eax Zero eax
:0040A5A0 89C3
mov ebx, eax Zero ebx
:0040A5A2 8945F8
mov dword ptr [ebp-08], eax ;[ebp-08] will have a
;zero put in it
:0040A5A5 8D841D74FFFFFF
lea eax, dword ptr [ebp+ebx-0000008C] ;eax holds
;name address
:0040A5AC 3B5DFC
cmp ebx, dword ptr [ebp-04] ;= the length of our
;name
:0040A5AF 7D0E
jge 0040A5BF ;Don't jump do little calculation.
:0040A5B1 33D2
xor edx, edx zero edx
:0040A5B3 8A10
mov dl, byte ptr [eax] move first letter of name into dl
:0040A5B5 3155F8
xor dword ptr [ebp-08], edx Xor it with value at [ebp-08], start=0
:0040A5B8 43
inc ebx
:0040A5B9 40
inc eax
:0040A5BA 3B5DFC
cmp ebx, dword ptr [ebp-04] ;have we been through
;the whole name
:0040A5BD 7CF2
jl 0040A5B1 ;if not jump and do calculation for
;next letter
What I found this little routine above
does is take the first letter of your name and Xor it with 0 at [ebp-08],
then get your next letter of your name in hex and Xor it with the new value
at [ebp-08], this goes right through the whole name and includes any spaces.
At the end of this calc you will have a value at [ebp-08]. This value is
used later on and is Xor with our serial number we typed in.
I will give you an example, you might
want to use a hex base calc for this:
Name: The Headlesschickens
Hex Code for each letter is: 54,68,65,20,48,65,61,64,6C,65,73,73,63,68,69,63,6B,65,6E,73
[ebp-08]=0
Xor first letter with 0, 0 Xor 54 = 54
Xor second letter with value in [ebp-08],
54 Xor 68 = 3C
then 3C Xor 65 = 59 and so on until
you have done all the letters of your name. The final result will be stored
in [ebp-08].
Mine worked out to be 4A hex using the name, The Headlesschickens
To see this being done just type in SI d ebp-08, Press F10 through the whole routine and watch the data window as you step through the routine. You will now see in the data window the result of each calculation.
After this routine has been through you
will follow onto the next piece of code that actually encrypts the first
5 bytes of our name. These 5 bytes are what the encrypted serial will be
checked against, so at least we know some of the code manipulation.
What it does is take the first letter
of your name and add it to the first letter of your name, then it takes
the 5th letter of your name and add it to the first value. Then get the
10th value of your name and adds it to the first value. The amount of times
this is done is the (total length of your name divided by 5). So the first
letter of your name will be encrpted, you can see this happening by typing
in SI d esi, press F10 and follow what happens you will see the first letter
of your name change several times depending on the length of your name.
It then gets the 6th letter of your name and adds it to the second letter
of your name ( this is all in Hex of course), and so on with the 3rd letter
and fourth letter and 5th letter until you see your first 5 letters of
your name encrpted. While watching the data window at esi just hold down
the F10 key and watch the code form before your eyes. Write down the values
you see or do a print screen in softice so you know when you come to your
main compare what you should be looking for.
:0040A5BF 33DB
xor ebx, ebx zero ebx
:0040A5C1 8D8574FFFFFF
lea eax, dword ptr [ebp+FFFFFF74] ;move user name to eax
:0040A5C7 8945F0
mov dword ptr [ebp-10], eax ;move address of name
:0040A5CA 8BC3
mov eax, ebx
:0040A5CC 8B55F0
mov edx, dword ptr [ebp-10] ;address of name into edx
:0040A5CF 8BF2
mov esi, edx
;address of name into esi
:0040A5D1 8D940574FFFFFF
lea edx, dword ptr [ebp+eax-0000008C]
:0040A5D8 3B45FC
cmp eax, dword ptr [ebp-04] ;compare length of name
:0040A5DB 7D0F
jge 0040A5EC
:0040A5DD 8A0A
mov cl, byte ptr [edx] ;move first letter into cl
:0040A5DF 000E
add byte ptr [esi], cl ;add first letter to first
;letter of name
:0040A5E1 83C005
add eax, 00000005 ;add 5 for comparing with name length
:0040A5E4 83C205
add edx, 00000005 ;move name pointer along 5 letters
:0040A5E7 3B45FC
cmp eax, dword ptr [ebp-04] ;At the end of the name yet
:0040A5EA 7CF1
jl 0040A5DD no do again
:0040A5EC 43
inc ebx increase ebx, ;when ebx = 5 means 5 letters
;have been encrypted
:0040A5ED FF45F0
inc [ebp-10]
;point to second letter of
;name, next one to be encrypted
:0040A5F0 83FB05
cmp ebx, 00000005 ;have we encrypted 5 letters yet?
:0040A5F3 7CD5
jl 0040A5CA ;no? well carry
on encrypting
:0040A5F5 8D852CFFFFFF
lea eax, dword ptr [ebp+FFFFFF2C]
:0040A5FB 50
push eax push the address of serial onto the stack
:0040A5FC E8CF280100
call 0041CED0 ;Heres our get length call again,
:0040A601 59
pop ecx
:0040A602 8BF8
mov edi, eax ;move length of serial into edi
:0040A604 33DB
xor ebx, ebx
:0040A606 8DB52CFFFFFF
lea esi, dword ptr [ebp+FFFFFF2C]
:0040A60C 3BFB
cmp edi, ebx
:0040A60E 7E1F
jle 0040A62F
This is setting up for some code manipulation, I get lost after this but I will tell you what I know. At the routine below it tests each value of your serial pointed to be esi with hex 39, which is 9 in the real world, so if it is a number add hex D0 to it, if it is above hex 39 it must be a letter so it goes and adds -20 to the hex value,( just minus 20 from the hex value) then adds hex C9 to it then puts it back where it got it from. In SI do your d esi to see what your numbers change into.
:0040A610 803E39
mp byte ptr [esi], 39 ;compare first serial
;number at esi with dec 9
:0040A613 7611
jbe 0040A626 ;if
below must be a number
;go and add (D0) to it
:0040A615 33C0
xor eax, eax
:0040A617 8A06
mov al, byte ptr [esi]
:0040A619 50
push eax
;push serial onto stack,
;must be a letter
:0040A61A E815810100
call 00422734 ;minus 20h
from the value
:0040A61F 59
pop ecx
:0040A620 04C9
add al, C9 add C9 to value
:0040A622 8806
mov byte ptr [esi], al ;put new value where you
;got it from
:0040A624 EB03
jmp 0040A629
:0040A626 8006D0
add byte ptr [esi], D0 ;must be a num, so add D0
:0040A629 43
inc ebx
:0040A62A 46
inc esi
;point next serial value
:0040A62B 3BFB
cmp edi, ebx
;are we at the end of the
;serial yet
:0040A62D 7FE1
jg 0040A610
This next part of the serial calculation uses our value that we created from our name and stored in [ebp-08]. I will just comment the code as best as I can, it then comes to a call where I think the final manipulation takes place, I didn't understand much after that so I hope someone can help me out at a later date with it.
:0040A62F 33DB
xor ebx, ebx
:0040A631 8D852CFFFFFF
lea eax, dword ptr [ebp+FFFFFF2C] points to our encrpted serial
:0040A637 3BFB
cmp edi, ebx
:0040A639 7E22
jle 0040A65D
:0040A63B 8A10
mov dl, byte ptr [eax] ;move serial into dl
:0040A63D C1E204
shl edx, 04
;shift it left 4 times, i
;think this is the same as
;serial number * 4, ?
:0040A640 025001
add dl, byte ptr [eax+01] ;add the next serial
;value to dl
:0040A643 3255F8
xor dl, byte ptr [ebp-08] ;Xor dl with our value
;from our name
:0040A646 8BCB
mov ecx, ebx
:0040A648 D1F9
sar ecx, 1
:0040A64A 7903
jns 0040A64F jump here
:0040A64C 83D100
adc ecx, 00000000
:0040A64F 88540DBC
mov byte ptr [ebp+ecx-44], dl ;move new value back
;into memory
:0040A653 83C302
add ebx, 00000002
;add 2 to ebx for
;compare with serial
;length
:0040A656 83C002
add eax, 00000002
;move serial pointer
;along 2 places
:0040A659 3BFB
cmp edi, ebx
:0040A65B 7FDE
jg 0040A63B
;are we finished with
;the new encrypted
;serial
After this just F10 down the listing there
are a whole lot of Xor on registers then moving the 0's to different memory
addresses. Not to sure of the importance of this. I got lost with the call
below
:0040A6DB E8499EFFFF
call 00404529
I'm sure it has something to do with the
final encryption of the serial, anybody who can show me the light on this
would be much appreciated
:0040A6CE 6A00
push 00000000
:0040A6D0 6800100000
push 00001000
:0040A6D5 FF353C574200
push dword ptr [0042573C] ;Probably the address
;for the encrypted
;serial
:0040A6DB E8499EFFFF
call 00404529
;Final manipulation of
;serial?
:0040A6E0 83C40C
add esp, 0000000C
This next piece of code below decrypts the code at [esi] which amazingly turns into the first 5 encrpted bytes of our name, I'm not to sure how this relates to anything but maybe it has something to do with the serial manipulation. Just trace through the code with F10 and keep your eye on the data window pointed to by esi to watch your code form when you trace.
:0040A6E3 33DB
xor ebx, ebx
:0040A6E5 BEEEB84200
mov esi, 0042B8EE ;point to encrpted
name data
:0040A6EA A104BF4200
mov eax, dword ptr [0042BF04] ;point to our decrption bytes
:0040A6EF 8A10
mov dl, byte ptr [eax] ;move decryption byte to dl
:0040A6F1 3016
xor byte ptr [esi], dl ;type: d esi to see your encrpted
;name
:0040A6F3 43
inc ebx
;bytes form, they will be the same as
;the ones that you wrote before.
:0040A6F4 46
inc esi
:0040A6F5 40
inc eax
:0040A6F6 83FB0A
cmp ebx, 0000000A ;keep decrypting
until ebx = 0A
:0040A6F9 7CF4
jl 0040A6EF
The next piece of code and call we come
to I also don't know what the point is. What happens is your whole name
with the encrypted first 5 letters are pushed onto the stack. Then it pushs
your 5 encrpted bytes of your name from the small routine before. In the
call all it seems to do is copy the 5 encrypted bytes from the name onto
each other. Not to sure why or the importance of it. I have commented it
below. Anyway we are almost at our main checking call. The bingo.
:0040A6FB 6A05
push 00000005 ;there are 5 bytes to check so push
5
:0040A6FD 8D8D74FFFFFF
lea ecx, dword ptr [ebp+FFFFFF74] ;ecx= address of name
:0040A703 51
push ecx ;first 5
bytes encrypted then push onto
;the stack
:0040A704 68E4B84200
push 0042B8E4 ;push 5 encrpted bytes of name onto
stack
:0040A709 E862260100
call 0041CD70 ;Copies them onto each other, why???
:0040A70E 83C40C
add esp, 0000000C
:0040A711 8B45F4
mov eax, dword ptr [ebp-0C]
:0040A714 A3F4BE4200
mov dword ptr [0042BEF4], eax
Finally we come to the most important part of this tutorial. Lets see what is getting pushed, first of all a 5, we know we are only checking the first 5 encrypted bytes of our name. F10 to you land at 0040A721 52 push edx , in SI type d edx, we see in our data window our name with the first 5 bytes encrypted, in SI type d 0042BF04 (our last push before the call 0041CF6C), in the data window we see some funny looking hex bytes, write or print screen the first 5 hex numbers. This is what our encrypted name gets compared to so somewhere along the line our serial has turned into these encrypted hex bytes. Before we trace into the call look what follows, there is a test eax,eax usually when you see something like this it means something important is being checked . So what we have after the call is this: If the compare doesn't match which we know it won't then eax will come out at anything but zero, thats bad because we then have :0040A732 0F94C1 sete cl which will mov a 01 into cl only if eax was Zero, which in our case there won't be a 01 put in cl, then : 0040A735 83E101 and ecx, 00000001, when we and 01 with 0 we get zero. Then the next command is the most important :0040A738 890D5C574200 mov dword ptr [0042575C], ecx , move whatever is in ecx into this memory location. This is the memory location that tells if the program is registered. We have seen that a bad compare of our name and serial will end up with a 0 in ecx, thus 0 will be put in this memory location [0042575C], program unregistered. We want a 1 in this memory location and to do that we have to pop out of the call 0041CF6C with eax set to 0.
:0040A719 6A05
push 00000005
;number of times to loop
:0040A71B 8D9574FFFFFF
lea edx, dword ptr [ebp+FFFFFF74];edx= address of our name
:0040A721 52
push edx
;push it onto the stack
:0040A722 FF3504BF4200
push dword ptr [0042BF04] ;push
address of our
;encrypted serial
:0040A728 E83F280100
call 0041CF6C
;Our main checking call
:0040A72D 83C40C
add esp, 0000000C
:0040A730 85C0
test eax, eax
;this must be 0 for good guy
:0040A732 0F94C1
sete cl
;set cl to 1 if Zero flag
;set
:0040A735 83E101
and ecx, 00000001
;ecx will then be 1 for good
;guy
:0040A738 890D5C574200
mov dword ptr [0042575C], ecx ;move 1, good guy memory
location
Alrighty then lets trace into this last
call and see whats happening and how we can get EAX to come back zero.
So F8 at :0040A728 E83F280100
call 0041CF6C Our main
checking call we land here, lets go through it. Basically what happens
is the first encrypted serial number is loaded into the bl register, then
it is compared with whats at the memory address pointed to by the edx register
which is our encrypted name.
It does this until there is not a match or until all 5 encrypted bytes have been compared then it takes the last encrypted serial number and the last encrypted name byte and subtracts them from each other. This will equal zero if we had put in the right serial number but in our case it will be a negative.
So now we know where we have to get our eax to equal zero. When you land at :0041CF79 85C9 test ecx, ecx , you can type in SI d eax to see what our serial has been encrpted into, d edx to see your name with the first 5 bytes encrpted. If our serial was correct it should have come out the same as the first 5 encrypted bytes from our name.
:0041CF6C 55
push ebp
:0041CF6D 8BEC
mov ebp, esp
:0041CF6F 53
push ebx
:0041CF70 8B4D10
mov ecx, dword ptr [ebp+10] ;move 5 into ecx, our loop counter
:0041CF73 8B4508
mov eax, dword ptr [ebp+08] ;address of encrpted serial into eax
:0041CF76 8B550C
mov edx, dword ptr [ebp+0C] ;address of our encrpted name
:0041CF79 85C9
test ecx, ecx
:0041CF7B 751A
jne 0041CF97 ;jump to checking part
:0041CF7D 33C0
xor eax, eax
:0041CF7F 5B
pop ebx
:0041CF80 5D
pop ebp
:0041CF81 C3
ret
* Referenced by a C)onditional
Jump at Address: 0041CF9E(C)
|
:0041CF82 8A18
mov bl, byte ptr [eax] ;move encrpted serial byte to bl
:0041CF84 3A1A
cmp bl, byte ptr [edx] ;compare it with our first encrpted name
;byte
:0041CF86 7504
jne 0041CF8C
;beggar off cracker
:0041CF88 40
inc eax
;point to next serial byte
:0041CF89 42
inc edx
;point to next encypted name byte
:0041CF8A EB0B
jmp 0041CF97
;continue loop
* Referenced by a (C)onditional
Jump at Address: 0041CF86(C)
:0041CF8C 0FB600
movzx eax, byte ptr [eax] ;land here if our check failed, then
;move last
:0041CF8F 0FB612
movzx edx, byte ptr [edx] ;bytes compared into eax and edx
:0041CF92 2BC2
sub eax, edx ;subtract them, eax will be minus, it might look
:0041CF94 5B
pop ebx ;something like this,
FFFFFFAB
:0041CF95 5D
pop ebp
:0041CF96 C3
ret
* Referenced by a (C)onditional
Jump at Addresses:0041CF7B(C), :0041CF8A(U)
|
:0041CF97 8BD9
mov ebx, ecx ;our counter for looping 5 times
:0041CF99 83C1FF
add ecx, FFFFFFFF
:0041CF9C 85DB
test ebx, ebx ;have we looped five times yet
:0041CF9E 75E2
jne 0041CF82 ;if not equal then compare next
byte
:0041CFA0 0FB640FF movzx
eax, byte ptr [eax-01] ;move last byte checked into eax and
;edx
:0041CFA4 0FB652FF movzx
edx, byte ptr [edx-01] ;then subtract them from each other
:0041CFA8 2BC2
sub eax, edx ;if we made it right through the loop they will
:0041CFAA 5B
pop ebx ;equal zero, eax
= 00000000, good guy.
:0041CFAB 5D
pop ebp
:0041CFAC C3
ret
|
So first at line:
:0041CF86 7504 jne 0041CF8C beggar off cracker
change the jne to a jump to next line. This will let the program go through the full check of your serial and name.
Now looks like this
0041CF86 EB00 jmp 0041CF88 beggar off cracker
Then at lines:
0041CFA0 0FB640FF
movzx eax, byte ptr [eax-01] ;move last byte checked into eax and edx
:0041CFA4 0FB652FF
movzx edx, byte ptr [edx-01] ;then subtract them from each other
:0041CFA8 2BC2
sub eax, edx
We don't want the movzx lines for subtract because it won't equal zero so just asemble over them with the following.
:0041CFA0
B800000000 mov eax, 00000000
;mov zero into eax for good guy
:0041CFA5 6640
inc ax ;we are five bytes short from original so
we
:0041CFA7 90
NOP ;need to pad out the extra 5 bytes
in a camoflauged
:0041CFA8 6648
dec ax ;way just incase the program looks for NOP's
The program will exit the routine with
eax = 0 thus it will allow the proper value of 1 to be put in the memory
flag area for good guy registered. Remember this is just my own patch here,
there are probably heaps of better ones, just experiment and see what happens.
Before we make this patch permanent there is just one more thing we have to check. F10 out of this routine too you get back to the routine where a 0 or 1 is put in the main memory area that tells the program whether it is registered or not.
:0040A728 E83F280100
call 0041CF6C
:0040A72D 83C40C
add esp, 0000000C ;return with eax = 0 good guy
:0040A730 85C0
test eax, eax
:0040A732 0F94C1
sete cl
:0040A735 83E101
and ecx, 00000001
:0040A738 890D5C574200
mov dword ptr [0042575C], ;ecx move 1 into
;memory location
;0042575C
We have to make sure we get out of this whole checking routine with eax = 1 for the program to take it to the Thankyou for your support caption. Usually this will happen very close to the end of the routine so go to your dead listing and have a look where the routine ends, ie: look for the ret opcode. Look up from this and look for the last place where eax is set. You will see below:
* Referenced by a (C)onditional Jump
at Addresses:
:0040A765(C), :0040A773(C), :0040A785(C),
:0040A797(C)
;move what is at memory location 0042575C
:0040A79C A15C574200 mov eax, dword ptr [0042575C] into eax,
;it
just so happens to be the memory location that we put a 1 into
;for
good guy.
* Referenced by a Conditional Jump at Addresses: :0040A51B(U),:0040A558(U)
:0040A7A1 5F
pop edi
:0040A7A2 5E
pop esi
:0040A7A3 5B
pop ebx
:0040A7A4 8BE5
mov esp, ebp
:0040A7A6 5D
pop ebp
:0040A7A7 C3
ret ;return with eax = 1 for good guy.
So eax is set by whatever is in our magic memory location that the program checks if it is registered or not with a 0 = unregistered and a 1 = registered.
Now we just need to make this patch permanent. I usually go back to W32Dasm and highlight the lines I need to change then write down the offset at the bottom of the screen. Fire Hiew then overwrite the old hex data with the new. Lets go and do that.
Our first patch is at offsett ::0041CF86
in W32Dasm goto this offsett, with the highlight bar on it at the bottom
of the screen you will see something like this @offsett 0001C586h in File:WinRAR
Write down the offsett 1C586, this is
where we will goto in Hiew.
Then in W32Dasm goto offsett: :0041CFA0 , write down the value after the @offsett at the bottom of the screen, 1C5A0, this is where we will goto in Hiew and write the next part of our patch.
Make a backup copy of Winrar and rename it with an extension that is not .exe. eg: WinRAR95.crk
Start Hiew then highlight our backed up copy of WinRAR.crk. Press enter to load it. Press F4 then Decode, Press F5 then type in our first offsett from W32Dasm ie: 1C586, press enter and we land right where we have to write our first part of the patch. Press F3 for edit then type in EB00 which is hex for jump to the next line. Press F9 to update.
Then do the same again for our next offsett, Press F5 ,type in our next offset ie: 1C5A0, enter, Press F3 to edit then type in our new hex data. B8000000006640906648, Press F9 to update then F10 to exit. Rename the file back to WinRAR95.exe and put it back in the main Winrar directory if it is not already there. Fire it up for your evaluation free version of WinRAR.
For some reason if WinRAR95.exe is not in your main Winrar directory it will still show evaluation copy. I think this has something to do with it needing the rar.ini file which holds your registration information.
Your registration info, that is your name and registration you typed in are kept in the rar.ini file under the heading Registration. Rar.ini is kept in the main WinRAR directory.
|
I'd like to thank +ORC for his tuts which I am slowly getting through, its good to lie awake at night trying to work out some of his cyptic tutorials.
And +Greythorne I think it is for putting all +ORKs targets on the web, I was almost ready to give up finding even one of his game targets.
And The Sandman for his tuts which are really helping me with Windows stuff.
And the writer of WinRAr, Eugene Roshal for his target. I have now deleted your target off my computer Eugene, I just needed it to unzip some windows help files on API's.
Gimmee (thats my nickname i don't want anything)
|
Ripping off software through serials
and cracks is for lamers..
If your looking for cracks or serial
numbers from these pages then your wasting your time, try searching elsewhere
on the Web under Warze, Cracks etc.
Back to Students Essay's |