|
|
|
|
|
|
|
|
|
|
||
|
||
|
|
There is a crack, a crack in everything. That's how the light gets in. |
|
|
Name:
Registration Code:
On startup, TimeSlice searches your Registry
file for your name/handle and Registration Code for TimeSlice which it
expects to find here:-
HKEY CURRENT USER\Software\Maui Software\TimeSlice\TimeSlice\CustomerName
HKEY CURRENT USER\Software\Maui Software\TimeSlice\TimeSlice\Registration
|
Now lets start thinking like *crackers*.. If we wish to 'back-track through the code looking for where the our fake serial number gets compared with the real one created by the program then we must first choose a likely system function used by the program which we know has a very good chance of being used within or by the program's protection system.
My favorite method of entry into a target
program is via the MessageBox system
function (found in the Kernel.DLL file ) if it is a 16-bit program, or
via the MessageBoxA system function
(found in the Kernel32.DLL file) if it's a 32-bit program. This is
often (but not always) used to display the 'Beggar off cracker' messages
and the 'Thank you for purchasing bla bla messages.
So once I had created a 'Dead Listing'
of TimeSlice-32 I immediately searched for this system function (MessageboxA)
and found it mentioned just once in this program at:
:0044BC0E FF153CDE4700
Call User32!MessageBoxA
:0044BC14 891E
mov dword ptr [esi], ebx
:0044BC16 837DFC00
cmp dword ptr [ebp-04], 00000000
:0044BC1A 89450C
mov dword ptr [ebp+0C], eax
:0044BC1D 740B
je 0044BC2A
:0044BC1F 6A01
push 00000001
:0044BC21 FF75FC
push [ebp-04]
:0044BC24 FF1520DE4700
Call dword ptr [0047DE20]
:0044BC2A 6A01
push 00000001
:0044BC2C 8BCF
mov ecx, edi
:0044BC2E E822FFFFFF
call 0044BB55
:0044BC33 8B450C
mov eax, dword ptr [ebp+0C]
:0044BC36 5F
pop edi
:0044BC37 5E
pop esi
:0044BC38 5B
pop ebx
:0044BC39 C9
leave
:0044BC3A C20C00
ret 000C
Just in case you don't already know this,
routines or blocks of code usually begin with any assembly instruction
and more importantly, end with a jmp
or a ret instruction, so if we want
to find the BEGINNING of the above message printing routine we would scan
up the dead listing until we came across either a jmp
or ret instruction..
Lets do this right now...
If you did this correctly then you will see the beginning of the message printing routine here:-
:0044BB7F 5E
pop esi
:0044BB80 C20400
ret 0004 ;End of some other routine
:0044BB83 55
push ebp ;Start of Message Print routine
:0044BB84 8BEC
mov ebp, esp
OK, now we know where the beginning of the message print routine is, it starts at memory offset 0044BB83. If you now check all the conditional jump statements from here to our call User32!MessageBoxA statement you'll quickly see that these jnz's, jz's statements relate only to how the actual message will look when it's been displayed, it does NOT however, have anything to do with the protection system or serial number used within the program.. You can see this for yourself by first going into the target program's registration screen, then, once you've filled in the required details create a Softice breakpoint on bpx Messageboxa then pressing the 'OK' button to let the target program run as normal until Softice cut's in. From here you would press the 'F11' key once to get back into the target program's code then scroll up Softice's disassembly window and place further breakpoints on all of the conditional jump statements in our target program's code up until memory offset address 0044BB83. Once you've done this simply press 'x' to let the program run as normal.. Now re-run the registration screen again, re-type in your User details and observe where Softice breaks and try and change the program's normal flow as it is halted on each of your breakpoints..
Our next job is to find where in the program this message print routine was called from, this is sometimes dead easy to find and on other times it can be very difficult to find without using the assistance of Softice.. Let's see how we can do this..
We need to find a jmp or call instruction that goes to the beginning of our Message Print Routine which we know starts at memory offset: 0044BB83.. W32Dasm does NOT tell us this information, this is because the program will be using some kind of internal address table that it 'looks up' each time it needs to direct the program to our Message Print Routine. If your using an Editor of some sort then simply search for 0044BB83 and you should find no instruction statement that refers to this memory offset address..
What we are looking for then is an Assembly instruction that looks like one of these examples:-
jmp [eax]
jmp [eax +00000123]
jmp [eax - 00000123]
call dword ptr [eax]
call dword prt [eax+00000123]
call dword ptr [eax-00000123]
Basically what these instructions are doing is to tell the computer to call or jump to the memory offset contained within the computer's register (in this example we are using the eax register).
Call
= Tell the computer to prepare for a new place
to visit.
Dword
= Tell the computer to expect a memory address.
prt
= Tell the computer to 'read' the address
it needs from the given
register and then add or subtract from this any
numeric value
assigned to this register
[eax+00000123] = If
eax equals 80000000h then add 0123h so the pointer
address now reads 800000123h
So now the computer has been 'told' where in the computer's memory it should find the actual memory address to call, so it then 'read's the first four bytes starting from 800000128h and it's THIS memory offset address that the computer WILL go to.. This is only a basic example but should give you an idea on how this system of indirect addressing works.
With this in mind and while still in W32Dasm go to the beginning of the Message Print Routine and begin scrolling up the listing and note down all jumps and calls using this kind of indirect addressing.. Do about five or six.. Next find the end of our Message print Routine and again, make notes of about five or six statements that use this kind of indirect memory addressing. We DON'T want to cover the Whole listing, just a small section of code above and below where our Message Print Routine is located.. Most of the time you'll see that the code routines that deal with the protection system sit side by side to each other.. It makes it easier for programmers to debug these routines if they are all close by to each other..:)
If you've been able to follow this essay
so far then you should have made the following notes on these suspicious
memory locations code instructions:--
:0044BB1B FF1540DE4700
Call dword ptr [0047DE40]
:0044BB43 FF1540DE4700
Call dword ptr [0047DE40]
:0044BB65 FF90B8000000
call dword ptr [eax+000000B8]
:0044BB7C FF506C
call [eax+6C]
Our Message print Routine lies here..
:0044BBB9 FF90B8000000
call dword ptr [eax+000000B8]
:0044BC55 FF9294000000
call dword ptr [edx+00000094]
:0044BC9F FF9294000000
call dword ptr [edx+00000094]
:0044BD0A FF5004
call [eax+04]
:0044BD1E FF5024
call [eax+24]
What we can do here is fire up our target
program again, go into the registration screen and fill in the User details
again. Then, press Ctrl-D and set a bpx messageboxa softice breakpoint
(if you haven't already done this) and press the OK button to let the program
begin checking our User details.. Once again the target program will display
the 'beggar off cracker message' and Softice will break once you've clicked
the 'OK' button to this message. Now, scroll up AND down the disassembly
listing and locate the instructions that I've shown above and when found,
DOUBLE-CLICK on them which will tell Softice you want break on this
line if it should ever get executed.
At this point all you need to do is re-run
the program and when Softice breaks on one of these 'special' call statements
do the following:-
Example:
Suppose you land on this instruction:
:0044BB65 FF90B8000000
call dword ptr [eax+000000B8]
Then you will need to type:
d eax+000000B8
This will display [in hex format] a series of number in your code window.
Now, in order to find out where this call instruction will take the program to we must now take the FIRST FOUR NUMBERS shown in our code window and REVERSE the sequence of numbers..
Like this.. The first four numbers in this
case is: 6A284400 so all you need to
do is type:
u 0044286A and this will show you
where the program will go next.. Does this equal the start of our Message
Print Routine at: 0044BB83?.
Now do this on ALL the Softice breakpoints
that we've set..
Very quickly you'll come to this statement:
:0044BC9A 8B10
mov edx, dword ptr [eax]
:0044BC9C FF75F0
push [ebp-10]
:0044BC9F
FF9294000000
call dword ptr [edx+00000094]
:0044BCA5 834DFCFF
or dword ptr [ebp-04], FFFFFFFF
:0044BCA9 8D4DF0
lea ecx, dword ptr [ebp-10]
:0044BCAC 8BF0
mov esi, eax
This is our 'babe', this is the one that we're interested in.
For those of you who are a little more *experienced* in cracking then yes, there is a much easier way to have found this instruction.. Once the 'Beggar off cracker' message was displayed we could have simply pressed the 'F11' key once to return to the target program's code then by pressing the 'F10' a few times we would come to a RET instruction which would have returned us here but I wanted to show how to find this return address for those occasions that this RET address method does not work.
Back to the essay...
If you scroll up the disassembly listing in W32Dasm you'll see there is only ONE conditional jump statement within this routine and dozens of further locations where this routine is called from, The single conditional jump statement inside this routine will still execute the 'beggar off cracker' routine so this we 'feel' is not where our serial number can be 'fetched', it still lies somewhere else..
Can you see that RET instruction at memory location:
:0044BCC1 C20C00 ret 000C
You need to get back into the target program's code (use bpx messageboxa) again then type: bc * then place a new Softice breakpoint on THIS ret instruction.
Run the target program again through the
registration screen and once again Softice will stop on this line, simply
press the 'F10' key once and we will land here:-
* Referenced by a (U)nconditional
or (C)onditional Jump at Addresses:
|:00418691(C), :004186A2(C)
:004189B9 6AFF
push FFFFFFFF
:004189BB 6A00
push 00000000
:004189BD 6A29
push 00000029
:004189BF E89A320300
call 0044BC5E
:004189C4 8D4C2410
lea ecx, dword ptr [esp+10] ;We land here
:004189C8 C644243001
mov [esp+30], 01
:004189CD E8DBA90200
call 004433AD
We're nearly there.. Notice here that there are no cmp or test instructions in this small routine, so we know that this routine isn't the one we're after. If you look in your 'Dead Listing' of our target program you'll see two references to conditional jump statements that execute this routine. So simply pressing the F10 key to the end of this routine won't take you to any of these conditional jumps so we must locate them ourselves.. The two references shown are quite close to each other so lets examine this code a little more closer..
But first....
type bc * to clear away any
previous Softice breakpoints then x to leave Softice..
Run our target program through the registration
screen.
Next, type bc messageboxa to create
a new softice breakpoint.
Press 'OK' to let the program check
our User details.. Softice now breaks...
Press the 'F11' key to allow the
program to display the 'beggar off cracker' message.
Press 'OK' to close this message
box. Softice breaks again.
Type: bc * then bpx 00418681
then x to leave softice.
For the very LAST time re-run the target
program again, fill in the User details again and let the program check
our User details again.
Here's where the Softice breaks, it's
before the two conditional jump statements that we've tracked down.
:00418681 8B4560
mov eax, dword ptr [ebp+60]
:00418684 8D7560
lea esi, dword ptr [ebp+60];esi=our User
;Name
:00418687 C644243002
mov [esp+30], 02
:0041868C 8B48F8
mov ecx, dword ptr [eax-08]
:0041868F 85C9
test ecx, ecx
:00418691 0F8422030000
je 004189B9 ;If Username blank etc then
;jump
:00418697 8B4D5C
mov ecx, dword ptr [ebp+5C];ecx=our fake
;Serial No
:0041869A 8D7D5C
lea edi, dword ptr [ebp+5C]
:0041869D 8B41F8
mov eax, dword ptr [ecx-08]
:004186A0 85C0
test eax, eax
:004186A2 0F8411030000
je 004189B9 ;if Serial No blank etc then
;jump
:004186A8 8D542414
lea edx, dword ptr [esp+14]
:004186AC 6A01
push 00000001
:004186AE 52
push edx
:004186AF 51
push ecx
:004186B0 8BCC
mov ecx, esp
:004186B2 89642430
mov dword ptr [esp+30], esp
;Save
memory location of the real serial number at esp+30
:004186B6 56
push esi
:004186B7 E8B6AB0200
call 00443272
:004186BC E8EF030000
call 00418AB0
:004186C1 8B442420
mov eax, dword ptr [esp+20] ;Real Serial
; At this point if you type: d eax you will see your 'REAL serial #
:004186C5 8B0F
mov ecx, dword ptr [edi] 'fake serial
:004186C7 83C40C
add esp, 0000000C
:004186CA 50
push eax
:004186CB 51
push ecx
:004186CC E85F5F0100
call 0042E630
:004186D1 83C408
add esp, 00000008
:004186D4 F7D8
neg eax
:004186D6 1BC0
sbb eax, eax
:004186D8 40
inc eax
:004186D9 84C0
test al, al
:004186DB 0F84D7000000
je 004187B8 ;Invalid serial #? then jump
;Notice, instead of jumping to 004187B9 it jumps instead to 004187B8, one instruction LESS to our previous routine that we just examined.. The dead listing of our target program using W32Dasm didn't show this jump!
So here we have it, by typing d
eax when we have stopped at 00416C5 we can sniff out the
real serial number for the user name we have typed into the program. Of
course there are perhaps easier methods to get to this location but sooner
or later your going to have to start to employ this cracking method shown
if your going to *crack* some programs that try and fool the newbie cracker
into giving up on cracking it's inner secrets.
Job Done.
|
|
My thanks and gratitude goes to:-
Fravia+ for providing possibly the greatest
source of Reverse Engineering
knowledge on the Web.
+ORC for showing me the light at the end
of the tunnel.
|
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.
Next | Return to Essay Index | Previous |