Opera 3.21 crack
by Ozymandias


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 cracking tutorials with attention and his essay seems easy to understand and well organized. Just a few words about the program: if you haven't tried it yet, DOWNLOAD IT IMMEDIATELY at http://www.operasoftware.com and LEARN how programs should be done! And, of course, if you like it... PAY for it!


At any rate, as I said, this may be too simple; it is my first
"unassisted" crack, 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
the HCU...


Target: Opera 3.21
Protection: 30-day-trial

Tools:
Wdasm 8.9
HeD v1.78b
Borland Resources Workshop 4.5
UltraEdit-32 5.10a

This is a very simple little crack, 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 crack, but decided to give it a
try anyway.

I used the software for a few days before attempting to crack 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"
codes:

Stringtable References:
   20092 - "Opera 3.21 - Evaluation" ;This is the title of the program
                                     ;when unregistered
   20095 - "This evaluation copy of Opera has expired..." ;and so on,
                                                          ;self explanatory
   20099 - "Invalid Registration code" ;also self explanatory
   21106 - "Please enter both name and organization" ;this seems pretty
                                                     ;simple - remember
                                                     ;it, we'll see it
                                                     ;again
   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
right:

* 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
                                                ;message

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
displayed. 

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 crack, 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.

Let's dig...

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
                                                ;stack
: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 crack it; I chose a 4 byte crack 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...

Ozymandias

(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!