Dot eating

Eolass patent bites the dust

This patch is not supported nor functional anymore. Please check follow-up solution by XenoAntares - http://my.opera.com/XAntares/blog/xanocta
Or read below if you like reading.

Some background:
Eolas (E) is a company that patented a certain way of interacting with embedded objects on web pages. This is why in Opera, you sometimes have to click (for example) a flash player to "activate" it before it can actually be controlled. That sucks.

Opera is the only browser that I know of, that currently have this annoying system in place. IE had it, but it reached to a pocket full of money to buy a license from E.

Other (open source) browsers don't implement this mechanism because E was kind enough to commit not to pursue legal actions against open source browsers that are violating its patent. Why? I guess because it wouldn't really be able to enforce that anyway. Builds without this future would pop up everywhere in no-time.

Solution:
Make a "custom" Opera build.

Now I look at it, finding out how to bypass this system took more time then it had to.

My starting point was to grab onto the string "Click to activate and use this control". It's displayed in status bar when hovering over non-activated embed.
It can be found in english.lng listed as:
-191213401="Click to activate and use this control"

Looks like Opera is using signed long's to identify strings. We can't just search for this number in opera.dll file and expect to find it there. Storing numbers as strings would be highly inefficient. Programs store numbers in hexadecimal instead so we have to convert this value to hex. Even windows calc will do the job in Scientific mode.
decimal -191213401 is 0xF49A50A7 in hex but we won't find that too in compiled file (even if we do, it won't be relevant to what we are looking for). PC's use little endian byte order so we have to search for reversed bytes: 0xA7509AF4, actually.

In a build I've been working on, this address was found twice in opera.dll. Those were the places where Opera actually referenced this string and as there were only two of those, it wasn't really hard to figure out that first one was the one I was looking for.

Found that out by setting a breakpoint in both of them and reloading a page that contained "non-activated" embed. Only one of those breakpoints triggered.

Tracing back from a code that references string, I eventually came to a code that created an "overlay" window. This is how Opera implemented "click-to-activate" thing. Invisible window is being positioned on top of non-activated embed and prevents interaction with it until clicked (when it is destroyed).

Cutting story short (I don't recall exact steps of this process as I've done that months ago - only some residual logs made this post possible), I've traced back again to find out where Opera decided to call CreateWindowEx function, that created our evil overlay. And below are the results of this work.

Patch:
For current versions of Opera 10 (alpha) and Opera 9.64 this change does the trick:
search: F7 D8 1B C0 F7 D8 C2 04 00 FF 74
replace: F7 D8 1B C0 B0 01 C2 04 00 FF 74

For Opera 9.63 (thanks Lex1 for correcting):
search: F7 D8 1B C0 F7 D8 5B C2 04 00
replace: F7 D8 1B C0 B0 01 5B C2 04 00

In 10alpha, search pattern can be found two times but only first one is relevant. Second match is actually involved in HTTPS related stuff so better not touch it.

Before hexediting opera.dll it has to be unpacked first. Use UPX command: "upx -d opera.dll"
For hex editing free XVI32 will do the job (not very friendly hexeditor though).

Download:
If you prefer to use a "ready to go" package then download this file, extract to Opera directory and run patch_click_to_activate.bat.
Patch for Opera 9.64 and Opera 10: opera-c2a.zip

For some 32/64 bit linux distributions use this patch script (thanks kylebaker for structuring script nicely): click-to-activate-removal-opera-10.sh
To use, download to any directory and execute these commands as a root:
chmod +x click-to-activate-removal-opera-10.sh
./click-to-activate-removal-opera-10.sh

PS. Pun intended in title ;>

Updated Gallery Viewer to v1.2Better Gmail title tweak

Comments

z@h3kZAHEK Tuesday, February 3, 2009 10:12:26 PM

ooh thanks smile

Daniel Davistagawa Thursday, February 5, 2009 12:37:21 AM

I wish their patent really would bite the dust - one of the most ridiculous hindrances to usability.

Thanks for posting your work.

João EirasxErath Thursday, February 5, 2009 12:46:15 AM

cool! what about a one-click patch file ?

Kyle Bakerkyleabaker Thursday, February 5, 2009 3:35:06 AM

Excellent write-up! I toyed around in Ubuntu trying to see if I could find the same hex strings to replace, but returned with no luck. I guess I need to unpack it first, but I'm really not sure how to do that on Linux.

@xErath
+1

It would be really cool to see a multi-platform (open source) patch tool for Opera. wink I'll dig around in Linux and see what I can come up with, but a tool should definitely be made!

Rafald.i.z. Thursday, February 5, 2009 10:45:01 AM

xErath: added patches.

kylebaker: I doubt that opera executable is packed in linux. Still unlikely to find that code there as different compilers produce different code.

Wasacz Thursday, February 5, 2009 12:17:44 PM

Awesome job, thanks aka dzięki bigsmile

Tamil Thursday, February 5, 2009 12:23:05 PM

FataL Thursday, February 5, 2009 7:50:37 PM

Great! up

Kyle Bakerkyleabaker Thursday, February 5, 2009 9:54:56 PM

@d.i.z.
Where is the lang file or what's it called in Windows so I can try to find the same in Linux? If I can come across it then I'll contribute that here to further extend your project!

Tamil Thursday, February 5, 2009 9:57:37 PM

Originally posted by kyleabaker:

Where is the lang file or what's it called in Windows

english.lng in Opera installation directory.

Kyle Bakerkyleabaker Thursday, February 5, 2009 10:11:28 PM

@Tamil
Thanks, looks like I'll have to do some snooping in Linux. So far I've found A7509AF4 in the /usr/lib/opera/10.00/opera file. So should the find and replace be in the same file or a different one if it's even the same in the Linux build?

Rafald.i.z. Thursday, February 5, 2009 10:17:05 PM

opera IS the file you would have to modify.

Now you found those bytes in opera, you would have to find some debugger that you could use to set a breakpoint on that memory location.

Or wait, I can try to find that location in disassembler...

Kyle Bakerkyleabaker Thursday, February 5, 2009 10:25:06 PM

@d.i.z.
I can wait. p Just having fun learning a thing or two from your approach to this. bigsmile

Rafald.i.z. Thursday, February 5, 2009 10:57:27 PM

for opera linux, at offset 0x254E6E there should be 0F95C0. Try changing to B00190

Not tested (based on dead listing only) but code looks a bit similar to windows code so that might be it.

EDIT: just realized that offset will probably vary from type of build you have (shared, static, qt3/4 etc.).
I've been analyzing opera-10.00-4126.gcc4-qt4.i386

Kyle Bakerkyleabaker Thursday, February 5, 2009 11:53:14 PM

@d.i.z.
Yes, they are different depending on how they were compiled.

I've disassembled it and was before using a regular hex editor, but I have no clue how you were able to find that point without using break points. I've given it a good look over, but I think I need to learn a little more about that stuff first. bigsmile

It would be interesting if I could figure out how you pin pointed that chunk and knew what to change it to, because I was thinking about writing a script that would disassemble, find the chunk to change and what to change it to and print it out...possibly auto-hex edit if possible all from a script, but that's not looking too promising at this point.

Rafald.i.z. Friday, February 6, 2009 12:30:33 AM

I have used windows build as a reference.

I have found where language id is moved into memory location in the disassembled code (just searched for string hex id).
In this very same function where that is done, several lines up, there is a call to the function that needs patching. I have found it in windows build by searching for that magic bytes mentioned in the post.

In linux builds, similar looking call is also located several lines up from where string id is copied into memory.

Windows:
.text:67BE82A4 arg_0           = dword ptr  4
.text:67BE82A4
.text:67BE82A4                 push    0
.text:67BE82A6                 xor     eax, eax
.text:67BE82A8                 inc     eax
.text:67BE82A9                 push    eax
.text:67BE82AA                 push    [esp+8+arg_0]
.text:67BE82AE                 mov     dx, 2Ah
.text:67BE82B2                 push    17h
.text:67BE82B4                 pop     ecx
.text:67BE82B5                 call    sub_678983E0
.text:67BE82BA                 neg     eax
.text:67BE82BC                 sbb     eax, eax
.text:67BE82BE                 neg     eax
.text:67BE82C0                 retn    4
.text:67BE82C0 sub_67BE82A4    endp


Linux
.text:0829CE30 var_18          = dword ptr -18h
.text:0829CE30 var_14          = dword ptr -14h
.text:0829CE30 var_10          = dword ptr -10h
.text:0829CE30 var_C           = dword ptr -0Ch
.text:0829CE30 var_8           = dword ptr -8
.text:0829CE30 var_4           = dword ptr -4
.text:0829CE30 arg_0           = dword ptr  8
.text:0829CE30
.text:0829CE30                 push    ebp
.text:0829CE31                 mov     eax, 1
.text:0829CE36                 mov     ebp, esp
.text:0829CE38                 sub     esp, 18h
.text:0829CE3B                 mov     [esp+18h+var_4], eax
.text:0829CE3F                 mov     eax, 17h
.text:0829CE44                 mov     [esp+18h+var_8], eax
.text:0829CE48                 xor     eax, eax
.text:0829CE4A                 mov     [esp+18h+var_C], eax
.text:0829CE4E                 mov     eax, 1
.text:0829CE53                 mov     [esp+18h+var_10], eax
.text:0829CE57                 mov     eax, 2Ah
.text:0829CE5C                 mov     [esp+18h+var_14], eax
.text:0829CE60                 mov     eax, [ebp+arg_0]
.text:0829CE63                 mov     [esp+18h+var_18], eax
.text:0829CE66                 call    sub_82974B0
.text:0829CE6B                 leave
.text:0829CE6C                 test    eax, eax
.text:0829CE6E                 setnz   al
.text:0829CE71                 movzx   eax, al
.text:0829CE74                 retn
.text:0829CE74 sub_829CE30     endp



Looks similar (while using very different instructions) to me.

I have a linux patch that one can try. Go to where opera binary is and run this lengthy command:
sed -e 's/\xB8\x2A\x00\x00\x00\x89\x44\x24\x04\x8B\x45\x08\x89\x04\x24\xE8\(....\)\xC9\x85\xC0\x0F\x95\xC0\x0F\xB6\xC0\xC3\x90/\xB8\x2A\x00\x00\x00\x89\x44\x24\x04\x8B\x45\x08\x89\x04\x24\xE8\1\xC9\x85\xC0\xB0\x01\x90\x0F\xB6\xC0\xC3\x90/' opera > opera_patched

opera_patched should have no more c2a. Maybe... not tested.

Kyle Bakerkyleabaker Friday, February 6, 2009 12:47:45 AM

haha, wow. I'll give it a shot and let you know..

Artur „Jurgi” JurgawkaJurgi Friday, February 6, 2009 9:26:20 AM

Good job in an oldschool way. sherlock

Rafald.i.z. Sunday, February 8, 2009 3:29:28 PM

Bytes I've posted above generally works for current Linux build but not when using sed.
I've upload shell script here:
http://files.myopera.com/d.i.z./files/patch10.sh
which tries to patch opera binary in two different ways (because different builds have different compiled code).

To use, download to some directory and execute those commands as a root:
chmod +x patch10.sh
./patch10.sh
(rather poor try at shell programming but works for me)

Kyle Bakerkyleabaker Wednesday, February 11, 2009 4:09:52 AM

@d.i.z.
For the script I get:
"Search pattern couldn't be found. File NOT patched."

I checked out the script, but haven't found a fix.

Rafald.i.z. Wednesday, February 11, 2009 8:50:03 AM

http://snapshot.opera.com/unix/snapshot-4126/
Which build are you using exactly?

Rafald.i.z. Wednesday, February 11, 2009 7:20:58 PM

Hmm, 64bit, no wonder it doesn't work.
Freeware IDA does not support 64bit binaries. Oh well.

João EirasxErath Wednesday, February 11, 2009 7:58:37 PM

d.i.z., the linux patch should actually tell if it's for 32 or 64 bits, the cpu and qt version.
Type opera--full-version to get that info.

Kyle Bakerkyleabaker Wednesday, February 11, 2009 8:41:38 PM

@xErath
Good call on that command, just to correct it a little..there should actually be a space after opera.."opera --full-version".

@d.i.z.
After checking for 32 vs 64 your script could apply the correct operation still. I can pastebin the hex if that would help.

EDIT:
You could use the following (or flip it):

#!/bin/sh

opera=`opera --full-version | grep "x86_64"`
if [ "$opera" != "" ]; then
	echo "64"
	#64-bit operations here..
else
	echo "32"
	#32-bit operations here..
fi

Rafald.i.z. Wednesday, February 11, 2009 9:52:31 PM

Kyle Bakerkyleabaker Wednesday, February 11, 2009 10:19:37 PM

@d.i.z.
It's missing a closing "fi" for the 64 case, other than that it works. I think I'm going to extend it a bit more though. Thanks!

Rafald.i.z. Wednesday, February 11, 2009 10:27:03 PM

Thanks for testing. Corrected.
It's likely to break for never builds though seeing how random gcc can be.

EDIT: also forgot about renaming patched binary and chmod. corrected now

Kyle Bakerkyleabaker Wednesday, February 11, 2009 11:49:34 PM

I've cleaned up the file a bit to make it easier to update and added some output to give a better idea of the code flow.

http://kyleabaker.com/downloads/opera/scripts/patches/click-to-activate-removal-opera-10.sh

I could write a script to analyze an objdump of the file to pin point the spot to edit if I understood how you are finding it...and that should make the patch apply across all unix systems instead of matching 32/64 and only having a few to test.

Kyle Bakerkyleabaker Thursday, February 12, 2009 1:09:59 AM

Patch Results thus far for Unix:
----
# intel-linux (32 bit)
----
# Method 1
opera_10.00.4126.gcc4.qt3_i386
opera_10.00.4126.gcc4.qt4_i386
opera-10.00-4126.gcc4-qt4.i386
opera-10.00-4126.gcc4-static-qt3.i386
opera-static_10.00.4126.gcc4.qt3_i386

# Method 2
opera-10.00-4126.gcc4-shared-qt3.i386

# Failed
opera-10.00-4126.gcc295-static-qt3.i386
opera-static_10.00.4126.gcc295.qt3_i386

----
# x86_64-linux/
----
# Method 1
opera-10.00-4126.gcc4-shared-qt3.x86_64
opera_10.00.4126.gcc4.qt3_amd64

# Failed
(none)

Kyle Bakerkyleabaker Thursday, February 12, 2009 8:07:33 AM

I'm working on back-tracking what you've done to make a universal patch for all. The only problem is that I'm using objdump and the output is ~230 mb per file. Using grep I should be able to grab the needed hex points or asm points that we're looking for using regex, but I just don't know exactly how you're eye-balling these differences.

This is definitely helping me understand the underlying level of how binary works. p

Rafald.i.z. Thursday, February 12, 2009 8:36:52 AM

Reliable method for auto discovering that code would be tricky I guess.

When I find the string I just go up where the next ret instruction is and first call after that is the one we are looking for.

Inside the call there must be:
test eax,eax
setzn al
movzx eax,al
(in case of 64 bit it's a bit different AFAIR)
and you have to also include a lot of code before that in a pattern, so that match is found only in this specific function (there are a lot other functions that have same piece of code).

Pattern matches 4 "any" (.{4}) bytes. This is a call pointer which must be matched this way because it will always be different in different builds.

Also it would be nice to check if only one pattern matched in a file. I failed to implement that check in a shell script.
It should be done, because if there are multiple matches, it should not proceed cause that can cause problems.

Kyle Bakerkyleabaker Thursday, February 12, 2009 9:05:24 AM

If anything else, it gives me something to do with my free time. p My only problem (other than pin-pointing the location to change...and I think I can find a way) is that I don't know how you are replacing it with what you do. So the hex that you're using in place is derived from what?

Mulitple matches...I think I can do that with a loop regex or something. If you can coach me through the process I can put a universal script together. wink I just very new to this and doing the best I can with hex. smile

Rafald.i.z. Thursday, February 12, 2009 10:01:22 AM

0F 95 C0 setnz al

In OllyDbg (windows) I've entered mov al,1 instead of it and it assembled it into B0 01 90.
I don't have all assembler opcodes in my head so I wouldn't be able to do that as easily in plain hex. smile

Kyle Bakerkyleabaker Thursday, February 12, 2009 12:10:37 PM

The true test is to see if this script carries over to the next snapshot..testing now..

EDIT:
Patch still works! And the underlining spell checker is much improved in this build!

A.RuzanovLex1 Saturday, February 14, 2009 11:41:33 AM

Thanks, it fine work in Opera 10 (win). But opera.dll from Opera 9.63 non contains «F7 D8 1B C0 F7 D8 C2 04 00 FF 74».

Found with Olly. «F7 D8 1B C0 F7 D8 5B C2 04 00» need replace to «F7 D8 1B C0 B0 01 5B C2 04 00»

kslee Saturday, February 14, 2009 3:58:36 PM

Originally posted by Lex1:

«F7 D8 1B C0 F7 D8 5B C2 04 00» need replace to «F7 D8 1B C0 B0 01 5B C2 04 00»


Yes, and there are two sets of "F7 D8 1B C0 F7 D8 5B C2 04 00" in 9.63.

Originally posted by d.i.z.:

In 10alpha, search pattern can be found two times but only second one is relevant.


I can find only one set of "F7 D8 1B C0 F7 D8 C2 04 00 FF 74" in 10 alpha.
Isn't it the other way round? And thank you!

Rafald.i.z. Saturday, February 14, 2009 8:03:04 PM

Originally posted by Lex1:

But opera.dll from Opera 9.63 non contains


Ops, yes. I've tested on 9.63 Ibis build which I though would be the same as normal.

Originally posted by kslee:

I can find only one set of "F7 D8 1B C0 F7 D8 C2 04 00 FF 74" in 10 alpha.
Isn't it the other way round? And thank you!


Actually that varied from build to build so I'm not sure now.

Eventually I'll clean this mess and upload updated 9.6x patch.

lolfangStahn Tuesday, March 3, 2009 9:10:38 AM

Pleaassseeee make this compatible with 9.6x =)

A.RuzanovLex1 Tuesday, March 3, 2009 9:32:31 AM

Use patch for Opera 10. It's work with Opera 9.64.

Rafald.i.z. Monday, March 9, 2009 9:56:59 PM

I've refactored patch. Available here opera-c2a.zip.

It's much better and even intelligent in some sense:
  • works for Opera 9.64 and Opera 10 (current and hopefully future versions)
  • replaces only first found match
  • detects situation when file is already patched and does not proceed then
  • made in perl so can be adopted to linux easily (it should be enough to modify hex values and use shell script as a frontend for perl script)

Rafald.i.z. Friday, April 3, 2009 9:14:49 PM

Updated patch to work with 1413.
It was picking wrong place to patch. I've made it look for more known bytes before patching.
Available at same place.

Martin RauscherHades32 Saturday, April 25, 2009 1:50:59 PM

1456 has problems. Patched successfully but the slides on the right on http://www.socialmediaclub.org/ still show "click to activate"... :-/

Rafald.i.z. Saturday, April 25, 2009 2:01:18 PM

Originally posted by Hades32:

1456 has problems. Patched successfully but the slides on the right on http://www.socialmediaclub.org/ still show "click to activate"... :-/


Works for me. Be sure you have latest patch. It wasn't updated since March 9 but maybe you still have some older version.

Martin RauscherHades32 Saturday, April 25, 2009 3:17:40 PM

Originally posted by d.i.z.:

Works for me. Be sure you have latest patch. It wasn't updated since March 9 but maybe you still have some older version.


whistle Ups, my fault. Accidentally patched my old Opera 9 *g* Everything works fine, now. Thanks anyway

sacharja Thursday, June 18, 2009 10:39:43 PM

Thx for the patch.

BTW with there's an open source one file patcher: http://sourceforge.net/projects/hexpatcher/#item3rd-3

Maybe better than the perl implementation.

Rafald.i.z. Friday, June 19, 2009 7:32:27 AM

Thanks but it looks like it does not support regexp which I use in patches.

sacharja Friday, June 19, 2009 2:38:15 PM

You can search for "F7 D8 1B C0 F7 D8 C2 04 00 FF 74" directly and replace it one time. BTW: it also seems to support ? to replace one character.

A more professional tool (but not open-source): http://www.softpedia.com/get/Programming/Patchers/diablo2oo2-Universal-Patcher.shtml

Martin RauscherHades32 Friday, June 19, 2009 6:34:51 PM

I don't like Perl, but I think it's much better this way as you can easily see what the script is doing with your browser...

Rafald.i.z. Friday, June 19, 2009 6:56:34 PM

In perl I like its speed and ease of programming.

To use that freeware patching tool, everything would have to be rewritten for batch files. Batch's are a bit messy and not friendly to program in. At least for me.

How to use Quote function:

  1. Select some text
  2. Click on the Quote link

Write a comment

Comment
(BBcode and HTML is turned off for anonymous user comments.)

If you can't read the words, press the small reload icon.


Smilies