|
|
|
|
|
|
|
|
|
|
||
|
||
|
|
There is a crack, a crack in everything. That's how the light gets in. |
|
|
|
OK, now run up Xara3D2 and go into it's 'Unlock' Screen via the Help menu.
For the Unlock code type in any numbers
you wish, I used 7777777
Our task is to patch rather than sniff
out the 'Unlock' code, we have 30 days to complete this task before the
program expires *grin*
Once done, press Ctrl-D and type
into Softice:
BPX messageboxa
Now type X to leave Softice and
press the 'OK' button so that Xara3D2 can get on with verifying
our Unlock code.
As expected, Softice breaks at the start of the MessageBoxA routine, from here press F11 once then answer 'OK' to the 'Invalid Unlock code', message that now pops up and again we're back in to Softice.
We should see the following snippet of
code in Softice.
:004753D5 | push [ebp+0C] |
:004753D8 | push [edi+78] |
:004753DB | push [ebp+08] |
:004753DE | push eax |
:004753DF | Call dword ptr [User32!MessageBoxA] |
:004753E5 | mov dword ptr [esi], ebx ;We land here |
:004753E7 | cmp dword ptr [ebp-04], 00000000 |
:004753EB | mov dword ptr [ebp+0C], eax |
:004753EE | je 004753FB |
:004753F0 | push 00000001 |
:004753F2 | push [ebp-04] |
:004753F5 | Call dword ptr [004F6CF0] |
:004753FB | push 00000001 |
:004753FD | mov ecx, edi |
:004753FF | call 00475326 |
:00475404 | mov eax, dword ptr [ebp+0C] |
:00475407 | pop edi |
:00475408 | pop esi |
:00475409 | pop ebx |
:0047540A | leave |
:0047540B | ret 000C ;When
we 'ret'urn from here it will take us to memory
;location: 014F::00475476 |
You will be able to trace the program's flow as it heads towards the call [User32messageboxa] instruction, which we've just returned from.
Incidentally, before the program can display a message box on our screen it must first place a number of values on the stack so that when the messagebox routine is called it can access these values in order to create the final messagebox in the way the programmer had wanted.
int MessageBox(
HWND
hWnd, // handle of owner window
LPCTSTR
lpText, // address of text in message box
LPCTSTR
lpCaption, // address of title of message box
UINT
uType // style of message box
);
- If we don't have a window, that
call's our MessageBox we set "hWnd" to zero.
- "lpText" will be the offset of
our text (where in memory it is stored)
- "lpCaption" ---> offset of the
messagebox Caption
- "uType" if set to "0" then it
corresponds to a "normal" MessageBox with a nice OK-button (Type
mb_ok)
Anyway, once we've explored the section of code between 014F::00475354 to 014F:0047540B and found that there isn't anywhere we can patch the program we leave via the ret instruction to another section of code at: 014F:475476
* Referenced by a CALL
at Addresses:
|:00402405
, :004037A5 , :00404015 , :0040B865
, :0040BBC6
|:0040C59E
, :0040D286 , :0040D2B6 , :0040D538
, :0041134C
|:00411E85
, :00417B92 , :00418F1C , :00418F7C
, :00419F2E
|:0041C32B
, :0046A84D , :0046EB47 , :00471B74
, :00471CCF
|:00471D01
, :00474E92 , :0047A7A0 , :00481A56
|
:0047542F B8C04A4800
mov eax, 00484AC0
:00475434 E83FE5FDFF
call 00453978
:00475439 51
push ecx
:0047543A 56
push esi
:0047543B 8D4DF0
lea ecx, dword ptr [ebp-10]
:0047543E E8CA83FFFF
call 0046D80D
:00475443 FF7508
push [ebp+08]
:00475446 8365FC00
and dword ptr [ebp-04], 00000000
:0047544A 8D4DF0
lea ecx, dword ptr [ebp-10]
:0047544D E83195FFFF
call 0046E983
:00475452 8B7510
mov esi, dword ptr [ebp+10]
:00475455 83FEFF
cmp esi, FFFFFFFF
:00475458 7503
jne 0047545D
:0047545A 8B7508
mov esi, dword ptr [ebp+08]
:0047545D E831A60000
call 0047FA93
:00475462 8B4004
mov eax, dword ptr [eax+04]
:00475465 56
push esi
:00475466 FF750C
push [ebp+0C]
:00475469 8BC8
mov ecx, eax
:0047546B 8B10
mov edx, dword ptr [eax]
:0047546D FF75F0
push [ebp-10]
:00475470 FF9294000000
call dword ptr [edx+00000094] ;Calls the routine
that deals with
;setting up the 'Invalid UnLock code'
;message when we get it wrong.
:00475476 834DFCFF
or dword ptr [ebp-04], FFFFFFFF ;We land here
after the above call.
:0047547A 8D4DF0
lea ecx, dword ptr [ebp-10] ;Register EAX
points to our beggar off
;message at loc: 0157:00A92F80
:0047547D 8BF0
mov esi, eax
:0047547F E8D484FFFF
call 0046D958
:00475484 8B4DF4
mov ecx, dword ptr [ebp-0C]
:00475487 8BC6
mov eax, esi
:00475489 64890D00000000
mov dword ptr fs:[00000000], ecx
:00475490 5E
pop esi
:00475491 C9
leave
:00475492 C20C00
ret 000C
At this point I cleared all of Softice's
breakpoints with bc * and placed a new breakpoint at location: 014F:0047542F
by simply scrolling up Softice's Code Window and then double-clicking on
this line.
:0047542F B8C04A4800
mov eax, 00484AC0
Why this line?. Well as you can
see from the above snippet of code it is called from many places within
the program's code, and since this line is the start of this code block
we want to try and work out what this block does.
OK, now re-run Xara3D2 from the Unlock screen, enter a dummy Unlock code and press the 'OK' button.
We now land at our new breakpoint and again, we trace through the code by using the F10 key and still we find no jnz or jpz instruction that allows us to bypass the calling of the 'You have entered an invalid Unlock code' message. We at least know we're still on the right track because we find the location of this beggar off message at memory location: 0157:0040c5A3
OK, keep pressing the F10 key until
we hit the 'ret'urn instruction at: :00475492
so that we emerge at the following section of code:
*
Referenced by (C)onditional Jumps at Addresses:
|:0040C3A9(C), :0040C3BD(C),
:0040C3D9(C), :0040C3F5(C), :0040C411(C)
|:0040C42D(C), :0040C449(C),
:0040C465(C), :0040C4DC(C)
:0040C595 6AFF
push FFFFFFFF
:0040C597 6A10
push 00000010
:0040C599 68BD0B0000
push 00000BBD ;Reference to our beggar off msg.
:0040C59E E88C8E0600
call 0047542F ;Call's the routine we just left
:0040C5A3 0F842A010000
mov al,[esp+13]
Here's where the program push's onto the stack our beggar off message, we're getting closer now to finding where to patch this program, but wait a minute, if we scroll up Softice's Code Window we see that there are many conditional jumps in close proximity to this beggar off function, nine in fact. Does this mean we have to patch all nine locations to get the program to accept our dummy unlock code?.. Let's first look at the code that comes before this beggar off routine and see if we can get a 'feel' for the code's logic.. Remember, we're looking for a good place to patch the code, not to sniff out the unlock code, which as we know is different each time it is installed on the User's machine.
:0040C395 83F801
cmp eax, 00000001
:0040C398 0F8505020000
jnz 0040C5A3
:0040C39E 8B842440010000
mov eax, dword ptr [esp+00000140]
:0040C3A5 8378F807
cmp dword ptr [eax-08], 00000007
:0040C3A9 0F85E6010000
jz 0040C595 ;1st jump to the 'Beggar
off routine'
:0040C3AF 0FBE10
movsx edx, byte ptr [eax]
:0040C3B2 52
push edx
:0040C3B3 E808530400
call 004516C0
:0040C3B8 83C404
add esp, 00000004
:0040C3BB 85C0
test eax, eax
:0040C3BD 0F84D2010000
jz 0040C595 ;2nd jump to the 'Beggar
off routine'
:0040C3C3 8B842440010000
mov eax, dword ptr [esp+00000140]
:0040C3CA 0FBE4801
movsx ecx, byte ptr [eax+01]
:0040C3CE 51
push ecx
:0040C3CF E8EC520400
call 004516C0
:0040C3D4 83C404
add esp, 00000004
:0040C3D7 85C0
test eax, eax
:0040C3D9 0F84B6010000
jz 0040C595 ;3rd jump to the 'Beggar
off routine'
:0040C3DF 8B942440010000
mov edx, dword ptr [esp+00000140]
:0040C3E6 0FBE4202
movsx eax, byte ptr [edx+02]
:0040C3EA 50
push eax
:0040C3EB E8D0520400
call 004516C0
:0040C3F0 83C404
add esp, 00000004
:0040C3F3 85C0
test eax, eax
:0040C3F5 0F849A010000
jz 0040C595 ;4th jump to the 'Beggar
off routine'
:0040C3FB 8B8C2440010000
mov ecx, dword ptr [esp+00000140]
:0040C402 0FBE5103
movsx edx, byte ptr [ecx+03]
:0040C406 52
push edx
:0040C407 E8B4520400
call 004516C0
:0040C40C 83C404
add esp, 00000004
:0040C40F 85C0
test eax, eax
:0040C411 0F847E010000
jz 0040C595 ;5th jump to the 'Beggar off routine'
:0040C417 8B842440010000
mov eax, dword ptr [esp+00000140]
:0040C41E 0FBE4804
movsx ecx, byte ptr [eax+04]
:0040C422 51
push ecx
:0040C423 E898520400
call 004516C0
:0040C428 83C404
add esp, 00000004
:0040C42B 85C0
test eax, eax
:0040C42D 0F8462010000
jz 0040C595 ;6th jump to the 'Beggar off
routine'
:0040C433 8B942440010000
mov edx, dword ptr [esp+00000140]
:0040C43A 0FBE4205
movsx eax, byte ptr [edx+05]
:0040C43E 50
push eax
:0040C43F E87C520400
call 004516C0
:0040C444 83C404
add esp, 00000004
:0040C447 85C0
test eax, eax
:0040C449 0F8446010000
jz 0040C595 ;7th jump to the 'Beggar off
routine'
:0040C44F 8B8C2440010000
mov ecx, dword ptr [esp+00000140]
:0040C456 0FBE5106
movsx edx, byte ptr [ecx+06]
:0040C45A 52
push edx
:0040C45B E860520400
call 004516C0
:0040C460 83C404
add esp, 00000004
:0040C463 85C0
test eax, eax
:0040C465 0F8446010000
jz 0040C595 ;8th jump to the 'Beggar off
routine'
:0040C46B 8B842440010000
mov eax, dword ptr [esp+00000140]
:0040C472 0FBE4804
movsx ecx, byte ptr [eax+04]
:0040C476 0FBE5006
movsx edx, byte ptr [eax+06]
:0040C47A 8D0C49
lea ecx, dword ptr [ecx+2*ecx]
:0040C47D 8D0CCA
lea ecx, dword ptr [edx+8*ecx]
:0040C480 0FBE5002
movsx edx, byte ptr [eax+02]
:0040C484 8D0C49
lea ecx, dword ptr [ecx+2*ecx]
:0040C487 8D0CCA
lea ecx, dword ptr [edx+8*ecx]
:0040C48A 0FBE5005
movsx edx, byte ptr [eax+05]
:0040C48E 8D0C49
lea ecx, dword ptr [ecx+2*ecx]
:0040C491 8D0CCA
lea ecx, dword ptr [edx+8*ecx]
:0040C494 0FBE10
movsx edx, byte ptr [eax]
:0040C497 8D0C49
lea ecx, dword ptr [ecx+2*ecx]
:0040C49A 8D0CCA
lea ecx, dword ptr [edx+8*ecx]
:0040C49D 0FBE5001
movsx edx, byte ptr [eax+01]
:0040C4A1 8D0C49
lea ecx, dword ptr [ecx+2*ecx]
:0040C4A4 8D0CCA
lea ecx, dword ptr [edx+8*ecx]
:0040C4A7 0FBE5003
movsx edx, byte ptr [eax+03]
:0040C4AB 8D0C49
lea ecx, dword ptr [ecx+2*ecx]
:0040C4AE 8BC5
mov eax, ebp
:0040C4B0 D1E8
shr eax, 1
:0040C4B2 8D94CA67216BFB
lea edx, dword ptr [edx+8*ecx-0494DE99]
:0040C4B9 8BCD
mov ecx, ebp
:0040C4BB 2555555555
and eax, 55555555
:0040C4C0 81E155555555
and ecx, 55555555
:0040C4C6 8D0C48
lea ecx, dword ptr [eax+2*ecx]
:0040C4C9 8D0489
lea eax, dword ptr [ecx+4*ecx]
:0040C4CC C1E008
shl eax, 08
:0040C4CF 2BC1
sub eax, ecx
:0040C4D1 8D04C0
lea eax, dword ptr [eax+8*eax]
:0040C4D4 8D0441
lea eax, dword ptr [ecx+2*eax]
:0040C4D7 8D0C40
lea ecx, dword ptr [eax+2*eax]
:0040C4DA 3BD1
cmp edx, ecx
:0040C4DC 0F85B3000000
jne 0040C595 ;9th jump to the 'Beggar off
routine'
:0040C4E2 8B0D10EC4B00
mov ecx, dword ptr [004BEC10]
:0040C4E8 55
push ebp
:0040C4E9 6828744A00
push 004A7428 ;Reference to
string 'Key"
:0040C4EE 6820744A00
push 004A7420 ;Reference to string
"Install"
:0040C4F3 E8AFA20600
call 004767A7
:0040C4F8 C605D0E44B0000
mov byte ptr [004BE4D0], 00
:0040C4FF 8D8C2444010000
lea ecx, dword ptr [esp+00000144]
:0040C506 C68424B40400000B
mov byte ptr [esp+000004B4], 0B
:0040C50E E845140600
call 0046D958
:0040C513 8D8C2440010000
lea ecx, dword ptr [esp+00000140]
:0040C51A C68424B40400000A
mov byte ptr [esp+000004B4], 0A
:0040C522 E831140600
call 0046D958
:0040C527 8D8C2404010000
lea ecx, dword ptr [esp+00000104]
:0040C52E C68424B404000009
mov byte ptr [esp+000004B4], 09
:0040C536 E8ABF30600
call 0047B8E6
:0040C53B 8D8C24A8000000
lea ecx, dword ptr [esp+000000A8]
:0040C542 C68424B404000003
mov byte ptr [esp+000004B4], 03
:0040C54A E8C7010600
call 0046C716
:0040C54F 8D4C2458
lea ecx, dword ptr [esp+58]
:0040C553 C68424B404000002
mov byte ptr [esp+000004B4], 02
:0040C55B E8E0620500
call 00462840
:0040C560 8D4C2458
lea ecx, dword ptr [esp+58]
:0040C564 E887630500
call 004628F0
:0040C569 8D4C241C
lea ecx, dword ptr [esp+1C]
:0040C56D C68424B404000000
mov byte ptr [esp+000004B4], 00
:0040C575 E8DE130600
call 0046D958
:0040C57A 8D4C2414
lea ecx, dword ptr [esp+14]
:0040C57E C78424B4040000FFFFFFFF
mov dword ptr [esp+000004B4], FFFFFFFF
:0040C589 E8CA130600
call 0046D958
:0040C58E B001
mov al, 01
:0040C590 E9AA000000
jmp 0040C63F
* Referenced by a (U)nconditional
or (C)onditional Jump at Addresses:
|:0040C3A9(C), :0040C3BD(C),
:0040C3D9(C), :0040C3F5(C), :0040C411(C)
|:0040C42D(C), :0040C449(C),
:0040C465(C), :0040C4DC(C)
|
:0040C595 6AFF
push FFFFFFFF
:0040C597 6A10
push 00000010
:0040C599 68BD0B0000
push 00000BBD
:0040C59E E88C8E0600
call 0047542F
:0040C5A3 0F842A010000
mov al,[esp+13]
Our first job is to locate ALL nine condition
jumps to our 'begger off' routine, we don't want to miss any, else we could
end up back to square one. For those impetuous crackers among us we might
see that if we changed the line:
:0040C398 0F8505020000
jnz 0040C5A3
TO
:0040C398 EB8505020000
jp 0040C5A3
Then we could jump over all nine of these
beggar off jumps and let the program carry on from there so lets try this:-
First, clear all Softice's previous breakpoints by typing bc *
Next, locate the line we're about to change at memory location [0040C398] and then double-click on it. This tells Softice to treat this line as a breakpoint.
Type x to leave Softice then re-run Xara3D2 so we're back into the 'Unlock Screen' with a dummy unlock code already typed in. Now press the 'OK' button.
Ok, so far so good, we're now at the memory location we suspect that can bypass the protection system and so we now type:
r eip=0040C5A3
*
What we're telling Softice is to 'forget' what part of the program
it is about to execute and instead, execute the program's code at the new
memory location we've just given it. This is exactly the same procedure
that would happen IF we had changed the jnz instruction to a jp instruction.
*
We can now type x to leave softice
and let the program run as normal to see what happens next.
"You have entered an invalid Unlock code, this program has not been unlocked."
Hmmm, that's a shame, it did look promising and would have saved me further investigation and to be honest, I'm already getting sick of looking at this program's code looking for that elusive patch.. Time to re-think my strategies.. Head's back to the program's manual, looking for a clue, hint to where to try and attack the program..
hey, what's this, the program prevents access to the change background function as long as it's unregistered!. Why?.. Ah, I see, it's default background has the company's logo spread all over it, so if you try and use any logo's created with this program then the Xara3D2 logo gets shown as well..Hmm, nice touch. But how does this help us?. Can you feel it yet?, I certainly did..
I'll explain, each time you try and change the background border a message box pops up and tells you that you can't use this facility until the program has been registered.. Here's a nice messagebox we can trap.. Also, if we can't access the change background facility then the program must store a 'flag' of some sort in memory when it can't find it's unlock code in the system registry file.. This flag will usually consist of a byte value of '1' meaning not registered or a value of '0' meaning registered.
Press Ctrl-D and within Softice type bc * to clear all it's breakpoints then x to exit.
Run up Xara3D2 and
progress into the main screen, with the default background showing.
Now re-enter Softice (Ctrl-D) and type: bpx messageboxa then x
to leave Softice.
Now select the 'View'
option then chose 'Change Background Texture' and straight away
we're in Softice, we should see:-
:004753C6 E875A30000
call 0047F740 ;checks to see if memory
;location 004F2B08 is '0'
;0= program Registered
;1= program Unregistered
:004753CB 8B45F8
mov eax, dword ptr [ebp-08]
:004753CE 85C0
test eax, eax
:004753D0 7403
je 004753D5
:004753D2 8B401C
mov eax, dword ptr [eax+1C]
:004753D5 FF750C
push [ebp+0C]
:004753D8 FF7778
push [edi+78]
:004753DB FF7508
push [ebp+08]
:004753DE 50
push eax
* Reference To: USER32.MessageBoxA,
Ord:0195h
|
:004753DF FF15046B4F00
Call [User32!MessageBoxA]
:004753E5 891E
mov dword ptr [esi], ebx ;We land here
:004753E7 837DFC00
cmp dword ptr [ebp-04], 00000000
:004753EB 89450C
mov dword ptr [ebp+0C], eax
:004753EE 740B
je 004753FB
After checking out where the call
0047F740 went I quickly found that at memory
location 004F2B08 contained a single byte that when checked through a 'Dead
Listing' played a very important part within the whole program. When the
program is first run this memory location contains a value of '0', but
after it has checked to see if there is an Unlock code in the system registry
file it places a value of '1' in this location, signify that the program
is unregistered. Clearing all of Softice's breakpoints and creating
a memory access breakpoint: bpm 0157:004F2B08
gave me a number of locations within the program that handled this memory
location. One such area of interest concerns the initialization of
the program itself, where, having found that it is unregistered, goes on
to display how many days left you have before the 30 day time limit expires!.
This certainly is of interest to us because if we can somehow make the
program 'forget' to check memory location: 0157:004F2B08
at the start of the program then the rest of the program will follow suit!.
After a lot of trial and error I found
the block of code that works out how many days we have left to evaluate
this program, amongst other things and a little more work soon gave me
the actual call that would do this check.
:004105D0 68AC774A00
push 004A77AC
:004105D5 8BCE
mov ecx, esi
:004105D7 E859FD0600
call 00480335
:004105DC 6A05
push 00000005
:004105DE 8BCE
mov ecx, esi
:004105E0 E8AA060700
call 00480C8F
:004105E5 E846B3FFFF
call 0040B930 ;If the program is unreg'd
;then check no of days
;remaining and set the
;'unregistered' flag to 1
:004105EA 84C0
test al, al
:004105EC 7512
jne 00410600
Can you see where my patch will be placed?.
All we need to do is change:-
:004105E5 E846B3FFFF call 0040B930
*** TO ***
:004105E5 EB19
jmp 00410600
:004105E7 90
nop
:004105E8 90
nop
:004105E9 90
nop
Job Done.....
|
SEARCH FOR
:- E846B3FFFF84C07512
REPLACE WITH:-
EB1990909084C07512
|
**
Self modifying code is where while running, the program will change some
of it's own code to something totally different and therefore, changes
the way it runs based on any number of conditions **
The first time I cracked this program
I managed to get it to correctly register itself in the Window's Registry
file, where it inserted the 'Unlock Code' at:-
My Computer\HKEY_CURRENT USER\Software\Xara\XD2\Install
Key 0xb180b679 (2978002553)
This key was based on the program's serial No: WHPWRNCXP
I haven't explained how I did this because
I can't re-create the steps I took to make this happen, but perhaps someone
might find out how to do this and let me know..:)
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.
|
Next | Return to Essay Index | Previous |