Search code examples
operacompressioncomputer-forensicsopera-turbo

How does Opera Turbo compress the data (cache)?


I have an Opera browser with "Opera Turbo" enabled. It is a proxy, which recompress HTML into smaller format. I have a file from opera cache, which was compressed by turbo from 2000 kb to 500 kb. How can I uncompress this file into readable form (the original file have almost no html tags, just 8bit text, "<p>" tags, and html header/footer)?

Here is an example of such file:

.opera$ hexdump -C cache/turbo/g_0000/opr00003.tmp
00000000  78 da 6c 8f bf 4e c4 30  0c c6 67 fa 14 26 48 6c  |xзl▐©Nд0.фgЗ.&Hl|
00000010  a1 1c 12 d3 25 1d f8 37  82 54 f1 02 69 63 48 74  |║..с%.Ь7┌TЯ.icHt|
00000020  69 52 12 97 d2 b7 ed 88  40 80 b8 05 06 06 7a 57  |iR.≈р╥М┬@─╦...zW|
00000030  09 21 84 27 fb f3 cf 9f  6d 61 a8 71 45 26 0c 2a  |.!└'ШСо÷ma╗qE&.*|
00000040  5d 64 3b a2 41 52 60 88  5a 8e 77 9d bd 97 ec 34  |]d;╒AR`┬Z▌w²╫≈Л4|
00000050  78 42 4f fc 7a 68 91 41  3d 57 92 11 3e 50 be 99  |xBOЭzh▒A=W▓.>P╬≥|
00000060  5d 42 6d 54 4c 48 b2 b7  5e 87 3e f1 c5 d1 f1 82  |]BmTLH╡╥^┤>ЯеяЯ┌|
00000070  fd 78 79 d5 a0 64 1a 53  1d 6d 4b 36 f8 5f 26 ef  |Щxyу═d.S.mK6Ь_&О|
00000080  eb 71 fd f5 f8 97 5d e1  d0 87 a8 d3 ff 20 59 72  |КqЩУЬ≈]Ап┤╗сЪ Yr|
00000090  58 94 5d 4a 56 41 f0 40  06 e1 12 09 f6 1b ad 92  |X■]JVAП@.А..Ж.╜▓|
000000a0  59 c2 8c 8a 7c e6 32 91  cf 9f 09 67 fd 0a 22 3a  |Yб▄┼|Ф2▒о÷.gЩ.":|
...

and here is a part of original file (I'm not sure is it the really original file or not, but very likely it is):

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
    <meta name="description" content="статьи">
    <meta name="keywords" content="статьи">
    <title>Russia on the Net &mdash; статьи</title>
</head>
<link rel="stylesheet" href="/rus/style.css">
<body bgcolor="#FFFFFF">
<center>
...

Size of compressed file is 3397 and of original ~ 8913 bytes. Original file is compressible by bzip2 to 3281 byte; by gzip to 3177 byte; by lzma to 2990 byte; by 7z to 3082 byte; by zip to 3291 byte.

Update: I have information (from chrome opera-mini extension http://ompd-proxy.narod.ru/distrib/opera_mini_proxy.crx - unpack it with 7-zip) that opera mini uses this to unpack data webodf/src/core_RawInflate.js Can this file help me?


Solution

  • The first two bytes 78 DA are a valid 2 byte zLib header (see section 2.2 on CMF and FLG) that precedes deflate compressed data. So the file could be compressed using zLib/deflate.

    For a first quick test, you can use my command-line tool Precomp like this:

    precomp -v -c- -slow opr00003.tmp
    

    It will report zLib compressed streams and how big they are decompressed ("... can be decompressed to ... bytes"). If this is successful (returns a decompressed size close to the original filesize you know), use your favourite programming language along with the zLib library to decompress your data.

    Also note that if you're lucky, the stream (or a part of it) can be recompressed bit-to-bit identical by Precomp and the output file opr00003.pcf contains (a part of) the decompressed data preceded by a small header.

    EDIT: As osgx commented and further analysis showed, the data can not be decompressed using zLib/deflate, so this is still an unsolved case.

    EDIT2: The update and especially the linked JS show that it is deflate, but it seems to be some custom variant. Comparison with the original code could help as well as comparison to original zLib source code.

    Additionally, the JS code could of course be used to try to decompress the data. It doesn't seem to handle the 2 byte header, though, so perhaps these have to be skipped.