~ Perusing Opera's guts ~
Version April 2000

This is NOT for beginner reversers, beginners should simply [learn the basics first] and come here later.
Anyway, for those of you that already know the basic of reversing, here it goes...
Once you "deadlist" Opera (here I have used wdasm32 for this task), you'll find following interesting strings:
 String Resource ID=21425: "Your timed evaluation has %i days left"
 String Resource ID=21428: "(unregistered)"
 String Resource ID=22001: "This copy of Opera is already registered. Do you want to cha"
 String Resource ID=22004: "Opera Registration"
 String Resource ID=22005: "Invalid registration number. You have probably entered a pre"
The String Resource 22001, "This copy of Opera is already registered. Do you want to change the registration information", is the more promising one for reversing purposes, as you will see examining the relevant parts of the code that I have commented, below. In fact, as you will see now, the flag inside memory location 994728 (which corresponds to pointer [eax+4E8]) obviously decides if you are already -or not- a registered user: if this location is one (true) then you are already registered, else if it is zero (false) you are a unregistered user in his allowed 30 days trial time. As you will see, the same flag is used to decide if the program should check -or not- how many times you have been using it. Another typical case where -if you understand assembly language- changing one single byte of your target (from zero to one) would defeat a fairly complicated protection which is quite long and windy per se but, alas for the programmers, has been written in a higher level language...
:4911F4 33F6	      xor esi,esi		     ;make sure esi is zero
...
:491213 A11C175100    mov eax, dword ptr [0051171C]  ;get this flag
:491218 3BC6          cmp eax, esi		     ;is it zero?
:49121A 740F          je 0049122B		     ;if zero then go to Make_eax_=_1
:49121C 33C9          xor ecx, ecx	             ;make sure ecx is zero
:49121E 39B0E8040000  cmp dword ptr [eax+4E8], esi   ;check registered_flag
:491224 0F94C1        sete cl		             ;set cx=1 if flag=FALSE (0)
:491227 8BC1          mov eax, ecx		     ;now ax=0 ONLY if flag=TRUE (1)
:491229 EB03          jmp 0049122E	     	     ;now continue to second_check

* Make_eax_=_1: Conditional Jump from Address 49121A
|
:49122B 6A01          push 1		             ;...setting eax...
:49122D 58            pop eax		             ;...=1 (bad)

* Second_check: Unconditional Jump from Address 491229
|
:49122E 3BC6          cmp eax, esi		     ;check once more: esi =0: now,
:491230 7525          jne 00491257                   ;if ax=1 then user NOT registered
:491232 8B0D3C175100  mov ecx, dword ptr [51173C]    ;else prepare for displaying APIs
:491238 56  	      push esi		             ;push various parameters
:491239 56            push esi  		     ;push zero
:49123A 6A24          push 24			     ;push value 0x24 (36)
:49123C 56            push esi			     ;push zero
:49123D 68F1550000    push 55F1           ;ID=22001: Opera is already registered"
:491242 FF7508        push [ebp+08]		     ;push value 0xB60 (2912)
:491245 E889EEFDFF    call 004700D3       ;go GetFocus, LoadString and MessageBoxA
Among the 6 parameters pushed before the call (note that the preceding command at 491232: mov ecx, dword ptr [51173C], pre-points ecx to the string "Internal program error, please note situation and contact support", just in case something will go wrong during the following calls) the most interesting one (actually the very one that attracted in the first time our attention to the snippet of code above) is obviously the push 55F1, which is the string location "This copy of Opera is already registered. Do you want to change the registration information?" that will appear in a small messagebox ONLY if you are already registered. Hence it is trivial to set the correct memory location to 01 and to FAKE that you are already registered to Opera.

Note, moreover, how the 30 days check is implemented inside Opera (a typical snippet for most 30 days limit protections) using the same memory location as check:
:4AE4BE 8BB1E8040000    mov esi, dword ptr [ecx+4E8]       ;get "registered" flag
:4AE4C4 85F6            test esi, esi		           ;is this user registered?
:4AE4C6 7539            jne 004AE501		           ;yep, don't call
:4AE4C8 6880000000      push 80                            ;else prepare call
:4AE4CD 8D853CFFFFFF    lea eax, dword ptr [ebp+FFFFFF3C]  ;get how many days?
:4AE4D3 50              push eax			   ;and pass them below
:4AE4D4 68B1530000      push 000053B1   ;"Your timed evaluation has %i days left"
:4AE4D9 E81D40FBFF      call 004624FB		           ;show message
This confirms the obvious. Once more, it is trivial for any reverser to set the correct memory location once for all to "already registered". Newbies and beginners reading this will just have to wait until they are a little more "erfahren", or they will have to experiment and find out on their own.
It is a pity that the programmers didn't find the time to learn [some obvious anti-cracking tips].
This said, [Opera] is a wondrous application and you should by all means buy it after the allowed trial time.

 

Back to [Tutti all'opera!]     Back to the page [you came from]


basic

(c) 2000: [fravia+], all rights reserved