Symantec Visual Cafe
Demonstration of some
principles of code reading
by Crushed_ICE
(17 September 1997)
Courtesy of Fravia's page of reverse engineering
Well, I'm once more impressed by the quality of the essay of a "new" (for
my page) zen-cracker. Let's hope
that Crushed_ICE will send more essays of this kind! It's exactly as he writes:
"How to gain an understanding of a rather simple time evaluation
protection without using SoftICE or any other code debugger.
Demonstration of some
principles of code reading"...here we also have an IDA-expert! ...as
+ORC wrote: good crackers should learn to use all available TOOLS (exspecially
very good ones like IDA :-)
A last consideration: This stupid protection
scheme has been written by Symantec! What do you think of programmers that protect
their own most valuable products in this sloppy way? Would you buy (and trust) languages
coded by such
inept programmers?
Contributor:
Crushed_ICE
Abstract:
How to gain an understanding of a rather simple time evaluation protection
without using SoftICE or any other code debugger. Demonstration of some
principles of code reading and a most excellent interactive disassembler.
Target:
Symantec Visual Cafe 30 day evaluation supplied CD ROM PC Magazine August 1997.
Tools:
IDA Pro 3.5 (a most excellent tool well worth purchasing)
Introduction.
Personally I have a dislike of working with debuggers, process monitors and
the like. Code analysis should be possible by direct vision of the code,
resources and general structure of the target perhaps akin to the felling
of Zen mentioned in the informative +ORC's tutorials.
This quick, simple analysis and reverse of a "childs" time limit implementation,
for there is no better description of the stupidity of this one, hopefully
shows the technique and benefits of a good disassembler. The IDA Pro excels in
this example because of its ability to identify C Runtime library calls.
The Target.
Wanting to learn about Java I came across the August issue of PC Magazine with
a free evaluation of Visual Cafe, 30 days or until the end of September which
ever came first. Time is short and there are many things to do in life, so
this limitation is a little bit troublesome especially as it was mid September
before it hit my CDROM drive.
Thinking Time.
Moving the computers clock forward produces the rather boring 'Time Expired'
dialog as soon as Visual Cafe is launched so the time test is early on in the
code making the most likely target the executable VCafe.exe rather than one of
its supporting DLLs. Setting the time back restores normal operation.
Taking the Target.
So starting an initial analysis of VCafe.Exe with IDA Pro what can we find?
In general C compilers tend to place all initialised data in one area of the
executable so if you find a string literal you will tend to find all the other
initialised structures in the same place. This is especially useful when UniCode
strings are used as these are not detected automatically.
So step 1. From the IDA Menu Select [Navigate|Jump To|Choose from list of Names].
Those valuable string literals will have been given prefix of 'a' and paging
down you will find *lots* of them. Spend a few moments getting the feel of them
and what jumps up but:
db 0 ;
dd offset j_SFC42_800
aHack db 'HACK',0 ; DATA XREF: _TEXT:0043DC31_o
; _TEXT:0043DD0C_o
unk_4B04FC db 1 ; ; DATA XREF: _TEXT:0043DC63_o
Double clicking on the second reference to this interesting literal produces the code
fragment:
loc_43DD04: ; CODE XREF: _TEXT:0043DCE9_j
cmp [ebx+200h], edi
jz short loc_43DD66
push offset aHack ; 'HACK'
lea ecx, [ebp-1Ch]
call j_SFC42_860
mov ecx, [ebp-1Ch]
push ecx
mov ecx, esi
call j_SFC42_6199
push dword ptr [ebx+20h]
call ds:GetParent
push eax
call j_SFC42_2864
But, stop wait look and listen. This might well be an interesting literal by nature
of its value but the usage of it does not look right. We can read:
if (edi != [ebx+200])
{
call SFC42_860(EA[EBP-1C],'Hack')
call SFC42_6199(...
..
All very interesting but doubtful. In these cases make a note of the area and push
it aside, while returning to the literals to see what else there might be.
Scanning through the rest does not immediately produce anything seemingly of interest
for now.
Step 2. Now the IDA Pro disassembler has a very clever trick in that it can find and
label calls to most of the C Runtime packages. As the program must discover the current
date and time we might expect (but should not find) a call to the standard function:
time_t time(time_t *timex);
As discussed in other papers this would be **stupid but looking in Navigate|Jump To|Function
there is a j_time runtime call.
; S u b ro u t in e
j_time proc near ; CODE XREF: sub_46C96F+E_p
; _TEXT:0046CBB8_p
jmp ds:time
j_time endp
and only called 2 times! Now you see the power of IDA in the instant identification of
calling routines.
Step 3. Look at the calling routines
sub_46C96F proc near ; CODE XREF: _TEXT:0046CB84_p
sub esp, 28h
push ebx
push esi
mov [esp+8], ecx
lea eax, [esp+0Ch]
push eax
call j_time
mov eax, [esp+0Ch]
mov ecx, [eax+110h]
imul esi, ecx, 15180h
add esi, [esp+10h]
mov dword ptr [esp+14h], 105h
mov ecx, [esp+10h]
mov [esp+2Ch], ecx
And
loc_46CBB0: ; CODE XREF: _TEXT:0046CB9E_j
; _TEXT:0046CBA6_j
lea eax, [esp+134h]
push eax
call j_time
lea ecx, [esp+14h]
call sub_0046CC57
mov eax, [esp+18h]
shl eax, 10h
or eax, [esp+1Ch]
mov [esp+13Ch], eax
The second routine using the time function looks interesting as it immediately calls
another function making the likely code:
..sub_0046CC57(time())..
What does this function do?
sub_0046CC57 proc near ; CODE XREF: sub_46C96F+81_p
; _TEXT:0046CBC1_p
push eax
mov [esp], ecx
mov ecx, [esp]
mov edx, [esp]
add edx, 14h
loc_46CC64: ; CODE XREF: sub_0046CC57+18_j
xor dword ptr [ecx], 0ABCDh ; Odd thing to do!
add ecx, 4
cmp edx, ecx
ja short loc_46CC64 ; Odd thing to do!
add esp, 4
retn
sub_0046CC57 endp
Well an XOR with a literal value! What a result given we known that the time() function
returns a time_t this make the above routine an encryptor (barely) of the result of
time(). We must be close as the only use of such a value is to detect the expiry date.
Step 4. Think. Somewhere the protection method must hide the time limits so the most
obvious place would be the registry (and the worst place). Looking around the call to
this encryptor we find:
mov eax, [esp+14h]
add eax, 10h
push eax
push 80000000h
call ds:RegOpenKeyExA
and a bit lower:
push offset aBackupinfo
lea ecx, [esp+30h]
push ecx
call sub_497140
add esp, 8
A reference to a string literal
aShelldefault db '\ShellDefault',0 ; DATA XREF: sub_46C834+1C_o
aBackupinfo db 'BackupInfo',0 ; DATA XREF: sub_46C923+2D_o
; _TEXT:0046CB05_o
So the key might be ..\ShellDefault\BackupInfo. Make a note in future to work the
literal a bit harder! Fire up regedit and search for this key and what do we find
but:
\\HKEY_CLASSES_ROOT\.java\ShellDefault\BackupInfo
C8 AA 00 00 FF 9F 00 00 A9 BE 00 00 D3 9F 00 00 29 EF 00 00 9D CD 00 00
Step 5. Stop. Put the code to one side and study the above plus the information gained.
- Result of time() is encrypted by repeated XOR'ing with 0xABCD
- Before getting the time the program reads a value from the registry key \\HKEY_CLASSES_ROOT\.java\ShellDefault.
So what is the current result of the time() function? Well a quick and simple C program
returns 0x341E44E4 which is the number of seconds since 01/01/70. Encrypt this
with 0xABCDABCD and you get 0x9FD3EF29 which compares to the contents of the key value:
... D3 9F 00 00 29 EF 00 00 ... = 0x9FD3EF29
So the last bit ..9D CD 00 00 is likely to be the least significant digits or perhaps
something to catch us out!
Looking at the other bit of the key value we have
0x9FFFAAC8 which XOR 0xABCDABCD = 0x34320105
and taking the install date from this results in the answer 14.9 to time left to the
end of September!
Step 6. The Proof. So what happens if we change the expiry section of the value
to, say:
C8 AA 00 00 FF FF
and move the date forward on the machine. Nothing! Protection scheme understood!
Conclusion:
Hidding expiry details in the registry gives little protection and with
a little application of code analysis it is not always necessary to
SoftICE, or otherwise debug a program. Working in this way you also gain
a better understanding on how the compiler generates code and soon learn
how to read high level structure directly from the disassembly.
(c) Crushed_ICE, 1997. All rights reversed.
You are deep inside fravia's page of reverse
engineering, choose your way out:
homepage
links
anonymity
+ORC students' essays tools
cocktails
academy database
antismut search_forms mail_fravia
is reverse engineering legal?