Eolass patent bites the dust
Wednesday, 28. January 2009, 21:51:34
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 ;>















1 2 Next »
z@h3k # 3. February 2009, 22:12
Daniel Davis # 5. February 2009, 00:37
Thanks for posting your work.
João Eiras # 5. February 2009, 00:46
Kyle Baker # 5. February 2009, 03:35
@xErath
+1
It would be really cool to see a multi-platform (open source) patch tool for Opera.
Rafal # 5. February 2009, 10:45
kylebaker: I doubt that opera executable is packed in linux. Still unlikely to find that code there as different compilers produce different code.
Wasacz # 5. February 2009, 12:17
Tamil # 5. February 2009, 12:23
FataL # 5. February 2009, 19:50
Kyle Baker # 5. February 2009, 21:54
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 # 5. February 2009, 21:57
Originally posted by kyleabaker:
english.lng in Opera installation directory.Kyle Baker # 5. February 2009, 22:11
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?
Rafal # 5. February 2009, 22:17
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 Baker # 5. February 2009, 22:25
I can wait.
Rafal # 5. February 2009, 22:57
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 Baker # 5. February 2009, 23:53
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.
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.
Rafal # 6. February 2009, 00:30
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:
Linux
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 Baker # 6. February 2009, 00:47
Artur "Jurgi" Jurgawka # 6. February 2009, 09:26
Rafal # 8. February 2009, 15:29
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 Baker # 11. February 2009, 04:09
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.
Rafal # 11. February 2009, 08:50
Which build are you using exactly?
Kyle Baker # 11. February 2009, 18:39
Rafal # 11. February 2009, 19:20
Freeware IDA does not support 64bit binaries. Oh well.
João Eiras # 11. February 2009, 19:58
Type opera--full-version to get that info.
Kyle Baker # 11. February 2009, 20:41
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):
Rafal # 11. February 2009, 21:52
Not tested.
Kyle Baker # 11. February 2009, 22:19
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!
Rafal # 11. February 2009, 22:27
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 Baker # 11. February 2009, 23:49
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 Baker # 12. February 2009, 01:09
----
# 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 Baker # 12. February 2009, 08:07
This is definitely helping me understand the underlying level of how binary works.
Rafal # 12. February 2009, 08:36
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 Baker # 12. February 2009, 09:05
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.
Rafal # 12. February 2009, 10:01
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.
Kyle Baker # 12. February 2009, 12:10
EDIT:
Patch still works! And the underlining spell checker is much improved in this build!
A.Ruzanov # 14. February 2009, 11:41
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 # 14. February 2009, 15:58
Originally posted by Lex1:
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.:
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!
Rafal # 14. February 2009, 20:03
Originally posted by Lex1:
Ops, yes. I've tested on 9.63 Ibis build which I though would be the same as normal.
Originally posted by kslee:
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.
Stahn Aileron # 3. March 2009, 09:10
A.Ruzanov # 3. March 2009, 09:32
Rafal # 9. March 2009, 21:56
It's much better and even intelligent in some sense:
Rafal # 3. April 2009, 21:14
It was picking wrong place to patch. I've made it look for more known bytes before patching.
Available at same place.
Martin Rauscher # 25. April 2009, 13:50
Rafal # 25. April 2009, 14:01
Originally posted by Hades32:
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 Rauscher # 25. April 2009, 15:17
Originally posted by d.i.z.:
sebastian schuster # 18. June 2009, 22:39
BTW with there's an open source one file patcher: http://sourceforge.net/projects/hexpatcher/#item3rd-3
Maybe better than the perl implementation.
Rafal # 19. June 2009, 07:32
sebastian schuster # 19. June 2009, 14:38
A more professional tool (but not open-source): http://www.softpedia.com/get/Programming/Patchers/diablo2oo2-Universal-Patcher.shtml
Martin Rauscher # 19. June 2009, 18:34
Rafal # 19. June 2009, 18:56
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.