Text in fieri, should be ready in a coupla of week time... just writing and adding at the moment...
Cleaning the last version of Opera.

Introduction

Opera is well known as the best browser for the windoze environment.
It has many advantages vis-ą-vis overbloated browsersaurii like Microsoft's Internet Explorer (which, beside being overbloated and buggy, [syphons your data] to third parties) or Netscape (whose code, to state it diplomatically, is quite overbloated and buggy)
To start with, Opera has a "turn images off" on-the-fly button that -you'll have to admit- is something one simply cannot live without any more if he wants to peruse effectively and without eccessives delays the silly advertisement infested web of today.
But there's more: Opera has even a sort of 'anti-popup' function BUILT INSIDE IT: have a look at file ~ preferences ~ windows... see the checkbox for 'allow documents to create windows? Well... uncheck it! What are you waiting for? :-)
You think I have finished with the advantages that Opera offers? Nossir...try this other one: file ~ preferences ~ multimedia... see the checkbox 'enable animation GIF images'? Well... uncheck it! Yep, believe or not: you can selectively kill those useless animated gifs that nobody in his right mind would ever 'prefer' to load! :-)
Of course you can download hic et nunc Opera for LINUX as well...

For a long time Opera was distributed as shareware with an evaluation limit of 30 days, but it has always been so easy to find 'unlocking' serial numbers on the web that many a reverser were wondering if the idea was to let it 'quietly' diffuse in order to compete against the big two obsolete browsersaurii.

Version 5 of Opera is free, but has an horrible bug.
Let's have a look at a version 5 of Opera. I'm using for this lesson a version (Build 828, Platform Win32, System Windows 98) with the executable opera.exe having a length of 1.884.207 bytes.
The target's code triggers -apparently intentionally- an awful 'advertisement banner' inside the main window of the program, this crap moreover 'rotates', souring your eyes with many a vulgar publicity.
Now, even before starting reversing the code, let's point out and underline that it wouldn't be even necessary to work on it as we'll do in a minute: as many of you will already know, there are some very easy ways any zombie could have followed in order to avoid this tasteless advertising feature WITHOUT ANY NEED WHATSOEVER TU STUDY ITS CODE AT ALL:

FIRST METHOD
Voilą, c'est fait.

SECOND METHOD
fish an adequate serial number out of the web (+opera +((ver* OR v.) NEAR "5.0")) +serial -tits for instance)
Voilą, c'est fait.
But I want today to show you the sheer and almighty POWER of software reverse engineering, besides, we are (supposed to be) reversers, not thieves, so let's have a deeper look inside Opera in order to understand how this 'advertisement bug' works.

Descending inside Opera 5.0

As you can see on the big screen behind my shoulders, the advertisement window in Opera 5.0 (this software will be our 'target' today) is located on the top right corner of the main window.
In order to kill it we must identify it inside the code of our target. There are MANY paths that you can follow, I'll show you the 'dimensional' one today.
We'll start from the DIMENSIONS of the advertisement window, they must, of course, result as parameters inside the target's code.
In order to calculate them most reversers would use softice command hwnd -x when Opera is running.
Of course among the many big and small Opera's windows that softice will list, our specific advertisement window will be some sort of multiple document interface (MDI) child window... since Opera is a web browser that uses MDI, so that you don't have to open multiple browsers to view a number of websites at the same time (an important 'secret' of Opera revealed :-)
In this specific case, as we'll see in a second, our advertisement window will be a BLD_MDICHILD class window.
But forget this silly crackers' jargon and reversing approaches: you don't even NEED to know the reversing abc in order to fetch the data you need to kill it: there's a MUCH MORE SIMPLY way to get at the dimensions of this window. In fact, using an utility like the customizer, you'll be able to fetch the exact positional (and "nominal") data of this indecent and soon to be eliminated window of ours:

Thus we fire the customizer... see the yellow ball rolling on the big screen behind my shoulders?
Here we choose the 'edit window' option.
And then, in "windows details", with 'select' checked, we just click onto 'on'.
This approach is so easy that even your aunt, or a microsoft certified software developer could follow it.
Now move slowly the customizer's 'big' cursor towards our target. AH! See how many 'hidden' windows are revealed while we are on our way there?
In fact there are a lot of "hidden processes" going on during any 'normal' windoze's session (and you can bet that someone, somewhere is taking advantage of this matter of fact in order to gather data about you... but that's another story). Let's simply ignore these hidden windows for now, you'll be able to play with the customizer all by yourself another time... we want to tackle our target now...

Identifying the culprit advertisement window

So, here we come to our advertisement window, here are the data read by the customizer reads... "size and position": x position=328, y position=4, height=64 and width=472... and, see, it is indeed a BLD_MDICHILD window... a MDI child window as we supposed.

A small digression about the 'standardized' dimensions of advertisement windows: as it happens advertisement windows have often standard heights and widths: in my experience most advertisement windows are rectangularly shaped in the range 62-64 (height) per 470-478 (width). Why this relation 7:1 (470/62=7; 474/63=7; 478/64=7) should be constant beat's me, but nonetheless what counts is that you can be reasonably sure that somewhere inside the code of your advertisement prone target these values will be pushed on the stack short for the window-drawing call that will paint the silly crap advertisement you're supposed to HAVE TO WATCH all the time.

Let's start with the value we got: as we have seen this Opera's ad-window has following dimensions (which are often enough standard in adwares):

width="472", height="64"

The two decimal numbers 64 & 472 translate into 0x40 and Ox1D8 in hexadecimal. Since these two parameters must be pushed somewhere inside the code, we proceed to disassemble our target (use either wdasm or [IDA]) and then we examine the 'dead listing' of the disassembled code.
What are we looking for? Just the values 40 and 1d8? No: we can be waaay more precise (and we can eventually afterwards always 'fall back' to broader searches if needs be). In fact we "should" find somewhere inside the code of our target BOTH our 40 & 1d8 dimensions-values pushed on the stack.
It's cosmic power! Assembly is assembly: no matter which 'higher' language has been used to program Opera, no matter which compiler has been used to compile its code, a 'long' push is 68xxxxxxxx (with inverted notation for the xxxxxxxx address) whilst a 'short' push is 6Axx, therefore we'll of course look for:
68D8010000 = push 000001D8 (note the inverted notation D801!)
and
6A40 = push 00000040
I wont annoy you now with the possible slack variants or registervariants of these values. Besides there's no point in being excessively cracking-smarties here, since these values are in effect pushed as such inside Opera: note that since these parameters are to be BOTH pushed in order to set the width and height of a given window, they will mostly be situated very near to each other inside the code.
Thus let's simply fetch where "our" width and height values are pushed inside the code.
Jumping here from 6D35(Conditional)...
6D3A A1A8305900   mov eax, dword ptr [005930A8]
6D3F 3BC6         cmp eax, esi
6D41 743D         je 406D80
6D43 6A54         push 54
6D45 6A40         push 40  ;height
6D47 68D8010000   push 1D8 ;change to 6800000000 (push 0) and kill ads
6D4C 81C128FEFFFF add ecx, FFFFFE28
6D52 57           push edi
6D53 51           push ecx
6D54 56           push esi
6D55 FF7014       push [eax+14]
Note that this snippet holds the ONLY TWO references to both
68D8010000 = push 000001D8 and 6A40 = push 00000040
that do exist in the whole 'dead listing' of our target... :-)
That's called a BINGO! in crackers' jargon :-)

We'rnt finished, eh.
As you can see from the snippet above, the routine is conditionally called from 6D35.
Let's have a look
6D18 FF15C8A55500      Call dword ptr [0055A5C8] ;GetClientRect
6D1E 3975DC            cmp dword ptr [ebp-24], esi
6D21 7448              je 6D6B  ;of course an unconditional jump would
avoid the call below: eb48 wuld kill ads as well :-)
6D23 8B4DAC            mov ecx, dword ptr [ebp-54]
6D26 8BD9              mov ebx, ecx
6D28 2B5DA4            sub ebx, dword ptr [ebp-5C]
6D2B 81EBDB010000      sub ebx, 1DB
6D31 6683FB64          cmp bx,  64
6D35 7D03              jge 6D3A ; call "vulgar_advertisment_settings"
6D37 6A64              push 64
6D39 5B                pop ebx


fravia+
#include "standard_disclaimer.h"

to be cleared next week...
the beginning

* Referenced by a Jump at Addresses:00406C18(C), :00406C83(C), :00406C87(C)
|
:00406C9E 0FBF8124030000          movsx eax, word ptr [ecx+00000324]

once here, noway you can avoid the ad-window
looks like this previous step is compelled as well...

* Referenced by a Jump at Addresses:00406BC2(C), :00406BD7(C), :00406BE0(C)
|
:00406BF6 393534D85900            cmp dword ptr [0059D834], esi


da flag... eh?
:00406BC2 7532                    jne 00406BF6
:00406BC4 6A01                    push 00000001
:00406BC6 E8BC170D00              call 004D8387

* Referenced by a Jump at Addresses:00406BAC(C), :00406BB4(C)
|
:00406BCB 8B0DB46C5900            mov ecx, dword ptr [00596CB4]
:00406BD1 39B1AC020000            cmp dword ptr [ecx+2AC], esi
:00406BD7 751D                    jne 00406BF6
:00406BD9 83B99402000001          cmp dword ptr [ecx+294], 00000001
:00406BE0 7414                    je 00406BF6