|
|
|
|
|
|
|
|
|
|
||
|
||
|
|
There is a crack, a crack in everything. That's how the light gets in. |
|
With ADC you are able
to:
· Organise volumes,
folders and files into categories;
· Add comment
to each file, folder and disk;
· Analyse ZIP,
ARJ, ARC and CAB archives, including self-extracting ones;
· Search for
files/folders using file name names;
· Search for
files in archives (registered version only);
· Generate customizable
reports;
· Search for
duplicated files;
· Extract description
and version number from executable modules (EXE/DLL);
· Delete indifidual
files and folders from the catalogs;
· Hide individual
files in the catalog"
|
This program expects the User to enter a valid 32 alpha-numeric serial
number, although it the actual code within the program has been coded to
handle a 40 alpha-numeric serial number (for future releases?)
On successful registration the program creates the following entry in your System registry File:-
HKEY_LOCAL_MACHINE\Software\Elcom\Advance Disk Catalog\
Creating many sub entries but the sub entry we're interested in is found at:
HKEY_LOCAL_MACHINE\Software\Elcom\Advance Disk Catalog\Registration
Code = "Your serial number goes in here"
Where the program will eventually store
your serial number in.
|
1.
In programs such as this, it is more than likely to use the SAME serial
number checking routine to check to see if the User has entered in a valid
serial number and THEN every time you first run this program, where
it will then read your serial number from the System registry file or .ini
file ( which ever it uses to store your serial number) before deciding
if the program is still Shareware or has been registered.
2.
In cases described above, a simple patch to a conditional jump is all that
is required.
When I created a
'Dead Listing' of this program it was missing many of the shareware text
messages that I knew this program used, so it must then get this information
from somewhere else, another file perhaps, like a .DLL maybe!.
Sure enough, a quick
look in the directory where Advanced Disk catalog resides, shows another
file, a .DLL no less called Validate.DLL
*PLEASE NOTE
**
While W32Dasm shows us a memory offset address for the assembly code in our 'Dead Listing'
Example:
:00401784
6A50
push 00000050
|<----->|
<-----------------------------------Memory offset value
These 'offsets' address will be DIFFERENT when you come to using Softice because .DLL files are placed higher in the computer's memory than what W32dasm is able to figure out.
This therefore makes following a dead listing much harder when using Softice to trace through the code, since the memory offsets shown in Softice will be totally different to that shown in your dead listing. The only thing that remains the same is the sequence of Assembly code instructions.
So
for this essay I will continue to use the memory offsets provided by W32Dasm
but when you come to using Softice these WILL be different.
Right, fire up W32Dasm and create a 'Dead Listing' of the Validate.DLL file.
Search for the text string:
"Thank you for registering!"
* Referenced by a CALL
at Address: :004018F7
:00401784 6A50
push 00000050
:00401786 689C344100
push 0041349C
:0040178B 6A64
push 00000064 ;="Quite enough to try..Sorry.."
:0040178D A194344100
mov eax, dword ptr [00413494]
:00401792 50
push eax
:00401793 E8B7DC0000
Call USER32.LoadStringA
:00401798 6A50
push 00000050
:0040179A 68EC344100
push 004134EC
:0040179F 6A65
push 00000065 ;"Thank you for registering!"
:004017A1 8B1594344100
mov edx, dword ptr [00413494]
:004017A7 52
push edx
Notice that there are NO conditional jumps
before in this code snippet, so obviously the program has already decided
that our serial was correct before it arrived to this routine. So we now
have to back-track a little through the code until we come to a section
of code that has some sort of conditional jump that will either execute
the 'Beggar Off Cracker' routine' or to the one above, our 'Good Cracker'
routine.
Our most important clue to where we must look is given by W32Dasm, where it shows:-
* Referenced by a CALL at Address: :004018F7
This tells us that our 'Good Cracker' routine
gets executed at memory offset :004018F7, so lets take a look at this section
of code:-
* Referenced by a (C)onditional
Jump at Address :004018C5(C)
:004018CE 8B4D08
mov ecx, dword ptr [ebp+08]
:004018D1 890D94344100
mov dword ptr [00413494], ecx
:004018D7 6800400000
push 00004000
:004018DC 6A04
push 00000004
:004018DE E864DA0000
Call KERNEL32.GetProcessHeap
:004018E3 50
push eax
:004018E4 E8DAD90000
Call KERNEL32.HeapAlloc
:004018E9 8BF0
mov esi, eax
:004018EB 893578024100
mov dword ptr [00410278], esi
:004018F1 85F6
test esi, esi
:004018F3 7502
jne 004018F7 ;Our good Cracker Routine
:004018F5 33DB
xor ebx, ebx
:004018F7 E888FEFFFF
call 00401784 ;Our good Cracker Routine
:004018FC EB1D
jmp 0040191B
Now that we've arrived here this still
isn't what we're looking for, because while it does have a conditional
jump statement the program will STILL end up at our 'Good Cracker' routine
wether or not the conditional jump statement is 'set' or 'not' because
the 'Call' instruction below it will make sure of that. So we must
back-track further into the program and again W32Dasm shows us where to
go next:-
*
Referenced by a (C)onditional Jump at Address :004018C5(C)
One
thing worth mentioning here, it's been pretty easy so far to back-track
our way through the program because these routines are called from just
one memory location, however, some programs may have two or more places
which calls these types of routines and we would then have to check them
all out, so that we don't miss anything important.
As it happens the
above routine gets called by this section of code, which happens to sit
right above it:-
:004018BD E852090000
call 00402214 ;Check our serial number.
;Returns with either:=
;eax=0 (Serial No invalid)
;eax=1 (Serial No valid)
:004018C2 59
pop ecx ;Restore
contents of ecx register
:004018C3 85C0
test eax, eax ;eax=0?
:004018C5 7507
jne 004018CE ;Jump if eax not equal to '0'
:004018C7 6A00
push 00000000 ;
:004018C9 E813DA0000
Call KERNEL32.ExitProcess
What's important here is that the Call
00402214 returns with a value in the eax register, either a '0' or a '1'.
Now, if you've read some of my other essay's then you'll know that *most*
shareware programs uses a memory location (it doesn't matter exactly where
) as a sort of flag, which if this memory location has a value of say '0'
then the program knows it's running in Shareware Mode, but if, during the
serial number validation the program finds your serial number to be correct,
then it will place a value of '1', signifying that it has been registered.
Using the values '0' or '1' dates back to the old days of programming in
binary, where numbers were represented in series of 1's and 0's.
OK, lets follow where the Call 00402214
takes us shall we..
*** Serial Checking Routine ***
* Referenced by a CALL
at Address: :004018BD
:00402214 55
push ebp
:00402215 8BEC
mov ebp, esp
:00402217 51
push ecx
:00402218 E87ED10000
Call KERNEL32.GetVersion
:0040221D 85C0
test eax, eax
:0040221F 7D3E
jge 0040225F ;Serial Ok, so lets register prog.
:00402221 33C0
xor eax, eax ;Set eax to '0' (Shareware Mode)
:00402223 A340364100
mov dword ptr [00413640], eax ;Still Shareware
:00402228 A1700C4100
mov eax, dword ptr [00410C70]
:0040222D 85C0
test eax, eax
:0040222F 7438
je 00402269 ;Beggar Off Cracker
:00402231 8D55FE
lea edx, dword ptr [ebp-02]
:00402234 52
push edx
:00402235 50
push eax
:00402236 8B4D08
mov ecx, dword ptr [ebp+08]
:00402239 51
push ecx
:0040223A E889FEFFFF
call 004020C8
:0040223F 83C40C
add esp, 0000000C
:00402242 85C0
test eax, eax
:00402244 7423
je 00402269 ;Beggar Off Cracker
:00402246 668B45FE
mov ax, word ptr [ebp-02]
:0040224A 663B05740C4100
cmp ax, word ptr [00410C74]
:00402251 0F94C2
sete dl
:00402254 83E201
and edx, 00000001
:00402257 891540364100
mov dword ptr [00413640], edx ;Set *Reg Flag*
:0040225D EB0A
jmp 00402269 ;Beggar Off Cracker
:0040225F C705403641000100
mov dword ptr [00413640], 00000001 ;*REGISTRED!*
:00402269 A140364100
mov eax, dword ptr [00413640] ;GET EAX VALUE
:0040226E 59
pop ecx ;Restore registers
:0040226F 5D
pop ebp ;
:00402270 C3
ret ;Return to previous routine
There are two places in the above routine that the program can become fully *Registered*.. The first place the program decides that the serial is valid is near the beginning of this routine, where at:-
:0040221F
jge 0040255F will take the program directly to:-
.....
.....
....
:0040225F
mov dword ptr [00413640] , 00000001
where it saves the value '1' in a memory location designated by the program
as the Shareware/Registered flag.
If, during this checking of our serial number the program finds our serial number is invalid, then it skips over the assembly instruction mov dword ptr [00413640] , 00000001 thereby leaving this memory location with the default value of '0', which is the default Shareware mode.
So our 'patch' is a simple one, we patch the jge 0040255F instruction into a jmp 0040255F so that the program ALWAYS accepts whatever serial number we give it.
WRONG!
We've been had!. In reality this does not seem to happen. Had we carried out this 'patch' then we would have found that it wouldn't work. It seems all the code we've just examined is there to mis-lead us away from the 'real' routines, which look almost identical in places to the *real* ones used by the program!. So dis-regard EVERYTHING shown above and only follow what is now being described.
Lets get softice to show us the way..
1.
Start up Advanced Disk catalog and select the 'Register' button.
2.
Type in anything you want for the serial number.
3. Press
Ctrl-D to fire up Softice.
4.
Type bpx messageboxa then type x to leave Softice.
5. Now
click on the 'OK' button.
Softice now breaks at the beginning of the system function messageboxa routine.
6. Press 'F11' key once and click the 'OK' button to the message 'The Code is invalid'.
Softice now displays the following code snippet...
Remember, the memory offset values shown by W32dasm will NOT match what Softice shows us, but the actual sequence of assembly instructions will still be the same. This is why I used :F8XXXXXX in place of any memory offsets shown by W32Dasm because that's where Validate.DLL gets loaded to on my puter.
*
Referenced by a (C)onditional Jump at Address: 0040142D(C)
:F8XXXXXX
6A30
push 00000030
:F8XXXXXX
683C354100 push :F8XXXXXX
:F8XXXXXX
68DC354100 push :F8XXXXXX
:F8XXXXXX
E8B4DF0000 Call USER32.GetFocus
:F8XXXXXX
50
push eax
:F8XXXXXX
E89CDF0000 Call USER32.MessageBoxA
:F8XXXXXX
FF0588344100 inc dword ptr [F8XXXXXX] ;Increase
No of attempts
;to register this prog.
:F8XXXXXX
A188344100 mov eax, dword ptr [F8XXXXXX]
:F8XXXXXX
83F805 cmp eax, 00000005
;user tried 5 times?
:F8XXXXXX
7E1E
jle F8XXXXXX
;No? then carry on
:F8XXXXXX
6A10
push 00000010
;else exit program
:F8XXXXXX
683C354100 push F8XXXXXX
:F8XXXXXX
689C344100 push F8XXXXXX
From this we see that we're in the 'Beggar off cracker' message routine, so lets see where in our 'Dead Listing' this same section of code is and follow that from there. We don't want to lose any newbies reading this essay..:)
We don't need Softice
anymore, so type x to leave then quit Advance Disk Catalog and lets
get back to our dead listing again. We used Softice to help us confirmed
the *real* starting point in the code, and since Softice Breaks on the
messageboxa function called by the above code we know for sure that this
section of code is *real* and not placed by the programmers to fool us..
From our dead listing
we quickly find that our starting point is here:-
*
Referenced by a (C)onditional Jump at Address :0040142D(C)
:00401496
6A30
push 00000030
:00401498
683C354100 push 0041353C
:0040149D
68DC354100 push 004135DC
:004014A2
E8B4DF0000 Call USER32.GetFocus
:004014A7
50
push eax
:004014A8
E89CDF0000 Call USER32.MessageBoxA
:004014AD
FF0588344100 inc dword ptr [00413488];Count
No of attempts
;we make at guessing the
;serial number.
:004014B3
A188344100 mov eax, dword ptr [00413488]
;Save this number
:004014B8
83F805 cmp
eax, 00000005 ;Have we tried 5 times?
:004014BB
7E1E
jle 004014DB ;no?
then jump
:004014BD
6A10
push 00000010 ;else
exit the program.
:004014BF
683C354100 push 0041353C
:004014C4
689C344100 push 0041349C
Notice how similar the above code is to the one described near the start of this essay?. Rest assured that this is the *real* routine.
Our dead listing tells us that the above routine was called from memory location 0040142D, so lets take a closer look at this section of code..
:00401425 E8FE040000
call 00401928 ;Go check our Serial Number.
;Returns with either:=
;eax=0 (Serial No invalid)
;eax=1 (Serial No valid)
:0040142A 59
pop ecx
:0040142B 85C0
test eax, eax ;eax=0?
:0040142D 7467
je 00401496 ;yes? then Beggar off
cracker
Before the program takes us to the 'beggar off cracker' routine it first checks our serial number, which it does with the Call 00401928 instruction. Lets follow this call and see where it takes us..
* Referenced by a CALL
at Addresses: 004012BE, :00401425, :0040166C
:00401928 55
push ebp
:00401929 8BEC
mov ebp, esp
:0040192B 8B4508
mov eax, dword ptr [ebp+08]
:0040192E 50
push eax
:0040192F E8A0040000
call 00401DD4
:00401934 59
pop ecx
:00401935 5D
pop ebp
:00401936 C3
ret
Since there are no conditional jumps here we can be certain that this
routine is not what we're after, however, the call 00401DD4 looks interesting
and since this is the only place the program can go we too shall follow
it..
* Referenced by a CALL
at Address: :0040192F
:00401DD4 55
push ebp
:00401DD5 8BEC
mov ebp, esp
:00401DD7 83C4C0
add esp, FFFFFFC0
:00401DDA 53
push ebx
:00401DDB 56
push esi
:00401DDC 8B5D08
mov ebx, dword ptr [ebp+08]
:00401DDF 85DB
test ebx, ebx
:00401DE1 7507
jne 00401DEA ;Follow this jump
:00401DE3 33C0
xor eax, eax
:00401DE5 E988000000
jmp 00401E72
* Referenced by a (C)onditional
Jump at Address :00401DE1(C)
:00401DEA 8A13
mov dl, byte ptr [ebx]
:00401DEC 84D2
test dl, dl
:00401DEE 7504
jne 00401DF4 ;Follow this jump
:00401DF0 33C0
xor eax, eax
:00401DF2 EB7E
jmp 00401E72
* Referenced by a (C)onditional
Jump at Address: :00401DEE(C)
:00401DF4 6A40
push 00000040
:00401DF6 6A00
push 00000000
:00401DF8 8D55C0
lea edx, dword ptr [ebp-40]
:00401DFB 52
push edx
:00401DFC E8CB2A0000
call 004048CC
:00401E01 83C40C
add esp, 0000000C
:00401E04 53
push ebx
:00401E05 E8EE2B0000
call 004049F8
:00401E0A 59
pop ecx
:00401E0B 83F840
cmp eax, 00000040
:00401E0E 7E05
jle 00401E15 ;Follow this jump
:00401E10 B840000000
mov eax, 00000040
***
SERIAL CHECKING ROUTINE ***
;By
checking with Softice I found that this routine is called every time
;this program is first run and also to validate
the serial number when the ;User tries
to register Advanced Catalog Disk.
* Referenced by a (C)onditional
Jump at Address :00401E0E(C)
:00401E15 50
push eax
:00401E16 53
push ebx
:00401E17 8D55C0
lea edx, dword ptr [ebp-40]
:00401E1A 52
push edx
:00401E1B E83C2A0000
call 0040485C
:00401E20 83C40C
add esp, 0000000C
:00401E23 8D4DD0
lea ecx, dword ptr [ebp-30]
:00401E26 51
push ecx
:00401E27 E8B0FEFFFF
call 00401CDC
:00401E2C 59
pop ecx
:00401E2D 8BD8
mov ebx, eax
:00401E2F 8D45D8
lea eax, dword ptr [ebp-28]
:00401E32 50
push eax
:00401E33 E8DCFEFFFF
call 00401D14
:00401E38 59
pop ecx
:00401E39 8BF0
mov esi, eax
:00401E3B 56
push esi
:00401E3C 53
push ebx
:00401E3D E836000000
call 00401E78
:00401E42 83C408
add esp, 00000008
:00401E45 85DB
test ebx, ebx
:00401E47 7420
je 00401E69 ;Invalid serial, keep as Shareware
;This also makes
a great place to
;patch this program!.
:00401E49 85F6
test esi, esi
:00401E4B 741C
je 00401E69 ;Invalid serial, keep as Shareware
:00401E4D 8D45E0
lea eax, dword ptr [ebp-20]
:00401E50 50
push eax
:00401E51 E8F6FEFFFF
call 00401D4C
:00401E56 59
pop ecx
:00401E57 85C0
test eax, eax
:00401E59 740E
je 00401E69 ;Invalid serial, keep as Shareware
:00401E5B 8D55C0
lea edx, dword ptr [ebp-40]
:00401E5E 52
push edx
:00401E5F E82CFFFFFF
call 00401D90
:00401E64 59
pop ecx
:00401E65 85C0
test eax, eax
:00401E67 7504
jne 00401E6D ;Go register this program!
:00401E69 33C0
xor eax, eax
:00401E6B EB05
jmp 00401E72 ;Invalid serial, keep as Shareware
* Referenced by a (C)onditional Jump at Address: :00401E67(C)
:00401E6D B801000000
mov eax, 00000001 ;This sets our eax register
;to '1'.
;This is where the program
;actually registers itself!.
* Referenced by a (C)onditional
Jump at Addresses:
:00401DE5(U), :00401DF2(U),
:00401E6B(U)
|
:00401E72 5E
pop esi
:00401E73 5B
pop ebx
:00401E74 8BE5
mov esp, ebp
:00401E76 5D
pop ebp
:00401E77 C3
ret
Looking at the 'Serial Checking' routine we can see several conditional jumps that direct the program AWAY from executing the mov eax, 00000001 instruction, which is what assigns the eax register with that all important value of '1' which it later saves into a memory location that is treated as a flag to let it know wether it should run in Shareware mode or Registered mode after it has checked our serial number.
Finally, in order to 'patch' this program we should change the FIRST
conditional jump instruction that would normaly ignore the rest of the
serial checking instructions so that it will ALWAYS jump directly to our
mov eax,
00000001 instruction, thereby making sure that the program always
runs in REGISTERED MODE.
Job Done.
|
|
While be able to read and understand dead listings is one thing, we have to also make sure we understand the possible short falls of using this source of information on it's own. We have to understand our tools weaknesses as well as their strengths.
W32Dasm does not handle .DLL files very well, so if you create
a dead listing of a .DLL then always remember that the memory offsets shown
in your dead listing will not be the same when you come to using Softice
to trace through the same .DLL file. Should you also come across a .DLL
file such as the one described in this essay that has two sets of almost
identical routines, then make sure you don't get these confused when you
have to re-adjust your offsets from Softice back into the ones used by
W32Dasm.
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 |