Opera 3.21 reverse
Commented by +Malattia and Fravia+ (10 july 1998)
Here's a very good essay from Ozymandias, a guy who calls himself a beginner,
but that IMO can be considered a REAL cracker yet: he shows that he studied
tutorials with attention and his essay seems easy to understand and
Just a few words about the program: if you haven't tried it
yet, DOWNLOAD IT IMMEDIATELY
LEARN how programs should be done! And,
of course, if you like it... PAY for it!
above are +Malattia's own, I agree completely. I read this small essay on +Malattia's good page and I liked it. I believe that
we should spread Opera much more, and I think this essay will help. I would also propose to the
Opera boys that WE write a good protection for them. The miserable way
they protect their good software means that they
won't be able to scare even a newbie. Therefore, if Operasoftware wishes it, we may
help building a
better protection scheme for their fantastic browser (not a perfect protection scheme, that cannot exist
of course, a BETTER
protection scheme). I hope that many other +hcukers will
Enjoy this nice essay by Ozymandias and enjoy Opera, the BEST browser of this
planet by far! BTW, I have added a small addition at the bottom.
At any rate, as I said, this may be too simple; it is my first
"unassisted" reverse, and took me a total of three hours (two minutes,
therefore, for someone more practiced, I'm sure.) Still, it is not for
your education, but rather for the education of other poor lost souls
like myself... or more accurately, as I was before finding Fravia+ and
Target: Opera 3.21
Borland Resources Workshop 4.5
This is a very simple little reverse, it is the first program I have ever done
without the assistance of an essay of some sort. The protection is very
simple - I expected it to be much harder to reverse, but decided to give it a
I used the software for a few days before attempting to reverse it, writing
down any text I felt was relevant; although I have learned a great deal of
Soft-Ice, as yet I am more comfortable with the dead listing approaches. Go
through Fravia+'s "Cracking for Dummies" series (all two lessons) for a quick
intro to this approach.
First thing I did was to make a backup copy. Then I made another backup to
save myself some time. While I set Wdasm to work on one copy, I opened the
other in BRW. There are a ton of stringtables in there, and not all of them
are caught by Wdasm.
By searching through the stringtables, I found the following "relevant"
20092 - "Opera 3.21 - Evaluation" ;This is the title of the program
20095 - "This evaluation copy of Opera has expired..." ;and so on,
20099 - "Invalid Registration code" ;also self explanatory
21106 - "Please enter both name and organization" ;this seems pretty
;simple - remember
;it, we'll see it
21107 - "Could not open registration file" ;a mystery - this string
;is never used
21110 - "Opera 3.21" ;This is the "good" version of the first string
21425 - "Your timed evaluation has %i days left..." ;another obvious one
32888 - "This is a restricted version of Opera..." ;another mystery
32889 - "This evaluation copy has expired" ;obvious
By the time I had searched through the entire stringtable (it's really
large) Wdasm had finished decompiling. I saved a text file of it and pulled
it up in UlraEdit, where I began my search.
Because this is a beginner's essay (both on this end and the receiving end)
I will go through some of the more tedious steps that I went through rather
than just skipping to the end.
Although I "fished" for all the strings listed above, the only ones that
proved to be really useful were the "Please enter both name and organization"
string and the "Invalid Registration code" string. The reason will become
apparent as you fish for the others.
Opera has a process set aside to draw the error boxes: finding it does you
no good, as there are several hundred dummy calls to the routine. You can't
backtrace your way through the call, so the strings don't get you anywhere.
EXCEPT for these two error messages.
Opera displays the first message when you attempt to register the software
without a user name or organization. The important part for us is that this
error message is stored in the registration routine itself, NOT in the
process with the other codes. As far as I can understand it, the problem is
that the registration routine cannot run without the name and organization;
without the reg routine, the proper flags don't go into place, and the
screen-drawing routine can't run properly. But that's not important.
The second message is stored just before the end of the registration routine.
It seems that when you are unregistered, instead of returning a "bad" flag it
simply continues through the routine, making it appear that this is not the
reg routine itself.
Here's the routine as disassembled by Wdasm with my own comments on the
* Referenced by a CALL at Address: |:00477D6B
| ;This is the registration sub
:0044AC2A 55 push ebp
:0044AC2B 8BEC mov epb, esp
there are several lines of code, then the first je:
:0044AC31 8BF1 mov esi, ecx
:0044AC33 397DOC cmp dword ptr [ebp+0C], edi
:0044AC36 0F842A010000 je 0044AD66 ;This jumps to the error
As you scroll down the call, there are several of these je's, all preceded
by the same pattern - a mov statement, a cmp, and the je. All of them go to
this error message. But down at the very bottom there are two other jumps;
look closely, just before the bad message, is a series of calls, followed
by the same mov and cmp pattern we saw all through this routine - but
reversed. And then there's one more call, and finally a "test eax, eax"
statement, followed by the familiar conditional jump - but this time, it's
a jne. And after looking more closely, we see that it doesn't go to the same
place as the others - 44AD3D instead of 44AD66. And then there's another je,
to another spot in the same routine - where the "bad guy" message is
The jne jump is out of pattern, so let's see where it goes. Hmmm... another
subroutine. How dull. But the final jump is to the screen drawing routine.
Let's see - if we force the jump to this routine, do we get regged?
Well, let's switch it.
Line :0044AD0B 7530 jne 0044AD3D.
Hunt it up in HeD (search for FF B6 C8 06 00 00 first, then search for
7530 - it's easier that way.) Let's change this jne to a jmp, by changing
it from 75 30 to EB 30. Same jump, but now it's forced...
We load up Opera, type in a name and an org, some random number in the reg
box, and click register. The box vanishes, and away we go. No error
messages. But is it really regged?
Close Opera. Open it again. ARRRRGH! That same box! Wailing and gnashing
of teeth ensues...
But wait. We know that should be the right routine (alright, OK, I
cheated - I pulled a valid reg from a friend and used it to see if there
was a "Thank you" type screen if we register. There isn't.) So why isn't
it completing the registration process?
As it happens, this would PROBABLY work; you would just be annoyed a lot.
But this is a dirty reverse, not up to our high standards. Let's look again...
Well, what about these calls? Where do they go? Let's find out...
Go back into the code. Trace back to the last call before that jne we
changed. There it is,
:0044AD04 E84B010000 call 0044AE54.
This call is deep and convoluted. I followed all the calls tracing out what
it did, and there are at least two points where things get to be 4 calls
deep. What IS all this?
Well, only 4 registers really change - and only one, eax, is tested when we
return. Where does eax change for the last time? Don't look too hard - at
the very end of the top routine, there is the following code sequence:
:0044AEA0 7405 je 044AEA7 ;jump to ret
:0044AEA2 6A01 push 00000001 ;put 1 on the top of the
:0044AEA4 58 pop eax ;pull the top of the
;stack - 1 - into eax
:0044AEA5 eb02 jmp 0044AEA9 ;jump to ret
:0044AEA7 33C0 xor eax,eax ;zeroes eax = BAD FLAG!
:0044AEA9 5E pop esi
:0044AEAA C9 leave
:0044AEAB C20400 ret 0004
That's it. After all that run around, the flag is a 1 in the eax reg.
There are dozens of ways to reverse it; I chose a 4 byte reverse that was
very easy to do...
I selected the very first jump in the call, this one here...
:0044AE60 7445 je 0044AEA7
Originally, this was a test for a bad flag, so I could just reverse it -
make it a jne - along with every other conditional jump. That would work,
but there are dozens of calls.
So instead, I redirected it, as follows...
:0044AE60 EB40 jmp 0044AEA2
As you can see, I made it a jmp, so it ALWAYS follows the jump - even if
I put in a correct code, an incorrect code, or no code at all - and I
shortened the offset to put it right on the "push" statement above. That
way, we get the "good guy" flag, the rest of the routine runs normally,
and we got no troubles, no worries...
I just want to throw in a "Thank you" to Fravia+, +Gthorne, all the +HCUkers,
and, of course, +ORC... questions, comments, death threats, suggestions can
all be sent to kofk(at)usa(dot)net, they'll eventually reach me, after being
bounced around a few times. On second thought, send the death threats to
Bill@Micro$oft.com... he deserves them more than I do...
(c) Ozymandias 1998.
WARNING: this tutorial is published for EDUCATIONAL PURPOSES only! Nobody
except you is responsible for what you do with the things you read here.
Also, if you
intend to use shareware programs for a period longer than the
allowed one remember that you have to BUY them!
A small addition, by Fravia+, 17 July 1998
Well, I use a french version of Opera 3.21, and I have noticed that
the same scheme is still used, albeit in different locations:
:0044AB07 55 push ebp
:0044AB08 8BEC mov ebp, esp
:0044AB0A 83EC10 sub esp, 00000010
:0044AB0D 56 push esi
:0044AB0E 8B7508 mov esi, dword ptr [ebp+08] ;; see if param=0
:0044AB11 85F6 test esi, esi ;; if zero then bad luser
:0044AB13 7445 je 0044AB5A ;; ** this is Ozymandias' jump, just patch it
:0044AB15 56 push esi ;; to jmp :0044AB55 and get a good flag
:0044AB16 E835910700 call 004C3C50
:0044AB45 7513 jne 0044AB5A ;; ax=1? --> bad luser
:0044AB47 0FBE06 movsx eax, byte ptr [esi]
:0044AB4A 50 push eax
:0044AB4B E8E09A0700 call 004C4630
:0044AB50 85C0 test eax, eax
:0044AB52 59 pop ecx
:0044AB53 7405 je 0044AB5A ;; ax=0? --> bad luser
:0044AB55 6A01 push 00000001 ;; good registered hero
:0044AB57 58 pop eax ;; flag popped in ax
:0044AB58 EB02 jmp 0044AB5C
* Referenced by a Jump at Addresses:0044AB13(C), :0044AB1F(C), :0044AB45(C), :x0044AB53(C)
:0044AB5A 33C0 xor eax, eax ;; bad luser flag in ax
* Referenced by a Jump at Address:0044AB58(U)
:0044AB5C 5E pop esi
:0044AB5D C9 leave
:0044AB5E C20400 ret 0004 ;; back to caller
... so, there you're, use Opera, reverse it black and blue, but then REGISTER
YOUR COPY! Those guys that developed this juwel and are bravely fighting against
the browsersaurii deserve it! (And yes, I did register my cracked copy... see mal eine an!)
You are deep inside Fravia's page of reverse engineering, choose your
search_forms +ORC students' essays academy database
tools anonymity academy cocktails
antismut CGI-scripts mail_Fravia
Is reverse engineering legal?