首页
社区
课程
招聘
[原创]逆向iReader解读ebk2电子书格式
2012-11-10 22:50 28042

[原创]逆向iReader解读ebk2电子书格式

2012-11-10 22:50
28042
===========================================================

声明:
此文章仅供学习研究之用。
未经许可,请勿转载。


===========================================================

发现从 iReader_1.3.2.0 版本起就采用了动态库把ebk相关解析函数封装了。
因此,这里我用的是iReader_1.3 ,apktool把它转成smali代码。

然后,通过研读smali 代码,初步获得的ebk2文档头结构如下:

  +-------+---+-----------------------------+

   |0 - 3  |4  |  book_id                    |

   +-------+---+-----------------------------+

   |4 - 5  |2  |  head_data_size             |

   +-------+---+-----------------------------+

   |6 - 7  |2  |  ebk_version                |

   +-------+---+-----------------------------+

   |8 -11  |4  |  ebk_size                   |

   +-------+---+-----------------------------+

   |12-75  |64 |  book_name                  |

   +-------+---+-----------------------------+

   |76-79  |4  |  file_size                  |

   +-------+---+-----------------------------+

   |80-83  |4  |  head_compress_size         |

   +-------+---+-----------------------------+

   |84-87  |4  |  first_compress_block_size  |

   +-------+---+-----------------------------+

   |88-89  |2  |  chapter_count              |

   +-------+---+-----------------------------+

   |90-91  |2  |  compress_block_count       |

   +-------+---+-----------------------------+

   |92-95  |4  |  media_count                |

   +-------+---+-----------------------------+

   |96-99  |4  |  media_data_length          |

   +-------+---+-----------------------------+

   |100-103|4  |  txt_compress_size          |

   +-------+---+-----------------------------+


下面来验证一下逆向得出来的这个头结构对不对。
└─[$] <> xxd -l104 《白鹿原》.ebk2  

0000000: 0000 0000 6800 0200 6636 0900 0a30 7d76  ....h...f6...0}v

0000010: 7f9e 9f53 0b30 0000 0000 0000 0000 0000  ...S.0..........

0000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000040: 0000 0000 0000 0000 0000 0000 f036 0e00  .............6..

0000050: 9502 0000 0bab 0000 3000 0f00 0000 0000  ........0.......

0000060: 0000 0000 6933 0900                      ....i3..


0-3 book_id

4 - 5  head_data_size

0068 ,其十进制值为:  104. 这与上图的结构是相符的。即整个ebk2文件头部信息数据总大小为 104个字节。

6-7 字节为 ebk文件版本,上面数据: 0200 ,其十六进制为:0002 ,即表示ebk2格式。

8 -11  |4  |  ebk_size  6636 0900

其十六进制为: 00093666

603750

我们查看下这个ebk2文件大小是不是这么大?
└─[$] <> ll 《白鹿原》.ebk2

-rwxrwxrwx 2 root root 603750 Oct 25 08:39 《白鹿原》.ebk2*


12-75  |64 |  book_name  书名,共64个字节

                                       0a30 7d76  ....h...f6...0}v

0000010: 7f9e 9f53 0b30 0000 0000 0000 0000 0000  ...S.0..........

0000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000040: 0000 0000 0000 0000 0000 0000


白鹿原 UTF-8 十六进制: 767D 9E7F 539F

《白鹿原》UTF-8 十六进制: 300A 767D 9E7F 539F 300B

后面的0000 是空格。

(可新建一文本文档,然后 在linux下用xxd或在windows下用EmEditor或WinHex以十六进制查看,即可查知其十六进制值)

由于一般机器普遍为小端字节序 (LE),因此,这个标题在ebk2文件中应该为:

7D76 7F9E 9F53

看上面的xxd dump出来的数据可知,是对的。

其标题是采用UTF-16LE编码存储的。

76-79  |4  |  file_size 这个应该是解压后txt文件的大小

f036 0e00

000e 36f0 换算为十进制为 931568

└─[$] <> ll 《白鹿原》.ebk2.txt

-rwxrwxrwx 1 root root 931570 Nov  3 16:57 《白鹿原》.ebk2.txt*


为什么是931570 ? 因为加上了两个字节的BOM (FFFE).

80-83  |4  |  head_compress_size   

9502 0000

0000 0295 其十进制值为 661.

84-87  |4  |  first_compress_block_size  

0bab 0000

0000 ab0b 其十进制值为 43787.

88-89  |2  |  chapter_count  章节数量

3000

0030 其十进制值为 48.

用iReader打开这本书看了下,共34章,其中有14章是分为两个章节的。因此,48章是没错的。

90-91  |2  |  compress_block_count  

0f00

000f 为 15 .

64K * 15 = 65536 * 15 = 983040 >  931568 (file_size解压后txt文件大小)

65536 * 14 = 917504 < 931568 ,因此,至少要分15个压缩段。

92-95  |4  |  media_count      

0000 0000

96-99  |4  |  media_data_length   

0000 0000

100-103|4  |  txt_compress_size   

6933 0900

0009 3369 十进制为: 602985

===================================================

到这里,基本可以得出这样一个数量关系:

header.head_data_size + header.head_compress_size + header.txt_compress_size = ebk2文件的大小

三段数据的关系:

104(header.head_data_size) + 661(header.head_compress_size) + 602985(header.txt_compress_size) = 603750 (header.ebk_size)

章节信息索引表的开始位置,应该就是整个ebk2文件从0开始偏移104(header.head_data_size)个字节。

正文的offset 应该是整个ebk2文件从0开始偏移header.head_data_size + header.head_compress_size个字节。

这三段数据里,只有header没有压缩。

===================================================

现在再总结下104个字节的head的结构:

  
 +-------+---+-----------------------------+----------------------------------------+


   |0 - 3  |4  |  book_id                    |一般为全0                               |

   +-------+---+-----------------------------+----------------------------------------+

   |4 - 5  |2  |  head_data_size             |ebk2文件的head大小,一般为104字节       |

   +-------+---+-----------------------------+----------------------------------------+

   |6 - 7  |2  |  ebk_version                |ebk文件的版本                           |

   +-------+---+-----------------------------+----------------------------------------+

   |8 -11  |4  |  ebk_size                   |ebk2文件大小                            |

   +-------+---+-----------------------------+----------------------------------------+

   |12-75  |64 |  book_name                  |书名                                    |

   +-------+---+-----------------------------+----------------------------------------+

   |76-79  |4  |  file_size                  |解压后txt文件的大小(包括章节名和内容) |

   +-------+---+-----------------------------+----------------------------------------+

   |80-83  |4  |  head_compress_size         |章节信息索引表的大小(压缩后的)        |

   +-------+---+-----------------------------+----------------------------------------+

   |84-87  |4  |  first_compress_block_size  |第一个压缩块的大小                      | 

   +-------+---+-----------------------------+----------------------------------------+

   |88-89  |2  |  chapter_count              |章节数                                  |

   +-------+---+-----------------------------+----------------------------------------+

   |90-91  |2  |  compress_block_count       |小说内容压缩段的数量                    |

   +-------+---+-----------------------------+----------------------------------------+

   |92-95  |4  |  media_count                |媒体数量                                |

   +-------+---+-----------------------------+----------------------------------------+

   |96-99  |4  |  media_data_length          |媒体数据长度                            |

   +-------+---+-----------------------------+----------------------------------------+

   |100-103|4  |  txt_compress_size          |压缩后的小说正文内容大小                |

   +-------+---+-----------------------------+----------------------------------------+


根据逆向的结果,可以这样定义其章节的结构:

struct ebk_chapter_info_tag

{

    unsinged char chapter_name[大小未知];

    unsigned int length;

    unsigned int offset;

};


压缩块的结构:

struct ebk_compress_block_data_tag

{

    unsigned int length;

    unsigned int offset;

};


即一个压缩块占用8个字节。

媒体:

struct ebk_media_data_tag

{

    unsigned int data_offset;

    unsigned int length;

    unsigned int media_type;

    unsigned int offset;

};


因此,ebk2文件的结构应该是:

header

head_compress (章节和压缩块信息)

compressed_txt (正文,多个压缩块)


测试书名:


/*

 * =====================================================================================

 *

 *       Filename:  test.c

 *

 *    Description:

 *

 *        Version:  1.0

 *        Created:  10/21/2012 07:01:50 PM

 *       Revision:  none

 *       Compiler:  gcc

 *

 *         Author:  荒野无灯 

 *   Organization:

 *

 * =====================================================================================

 */

#include 

#include 




#include "util.h"




int main()

{

    FILE * fp = fopen("foo.ebk2","rw");

    fseek(fp,12,SEEK_SET);

    char data[64];

    char out[64];

    int outlen = 64;

    int inlen  = 64;

    fread(data,1,64,fp);

    fclose(fp);

    printf("%02x ",data);

    char *in  = data;

    charset_convert("UTF-16LE","utf-8",in,inlen,out,outlen);

    printf("%s\n",out);

    return 0;

}



gcc -c util.c


gcc -c test.c


gcc -otest util.o test.o


└─[$] <> ./test

bf874cb0 《白鹿原》


===================================================================

接下来看看章节索引表

/*

 * =====================================================================================

 *

 *       Filename:  z.c

 *

 *    Description:

 *

 *        Version:  1.0

 *        Created:  10/21/2012 11:56:55 PM

 *       Revision:  none

 *       Compiler:  gcc

 *

 *         Author:  荒野无灯 @ihacklog.com

 *   Organization:

 *

 * =====================================================================================

 */

#include 

#include 

#include 

#include 




int main()

{

    unsigned char src[661];

    FILE *fp0 = fopen("bailuyuan.ebk2","rb");

    if(NULL == fp0 )

    {

        fprintf(stderr,"error open file!");

        return -1;

    }

    fseek(fp0,104,SEEK_SET);

    fread(src,1,661,fp0);

    fclose(fp0);




    uLongf srclen = 661;

    uLongf destlen = 4096;

    unsigned char *dest  = (unsigned char *) malloc(destlen+1);

    if( NULL == dest )

    {

        fprintf(stderr,"mallloc error");

        return -1;

    }

    unsigned char *pdest = dest;

    int err     = 0;

    err         =  uncompress(dest,&destlen,src,srclen);

    if(Z_OK != err )

    {

        fprintf(stderr,"error no: %d\n",err);

        return -1;

    }







    FILE *fp = fopen("chapter.dat","wb");

    fwrite(dest,1,4096,fp);

    fclose(fp);




    printf("destlen: %d\n",destlen);

        return 0;


}


gcc -c -g test_chapter_head.c


gcc -otest_chapter_head test_chapter_head.o -lz


./test_chapter_head


看看解压后的章节数据:

第 一 章

7B2C 4E00 7AE0

其UTF-16LE编码应该为: 2c7b 004e e07a

16×4  = 68

接下来的0000 0000四个字节应该是相对偏移(这里由于是第一章,所以是0)

然后,0e50 0000 是长度。

0000 500e

接下来又是2c7b (第) ...

因此,到这里,我们终于知道了其ebk_chapter_info结构的大小为 64 + 4 + 4 = 72个字节。

再往下看,第3个2c7b前面8个字节: 0e50 0000 e644 0000

0e50 0000 正好是前面的长度.表示它要相对于第一章偏移0000 500e (20494)个字节。

因此,上面逆向出来的那个结构是有错误的,应该修正为:

struct ebk_chapter_info_tag

{

    unsinged char chapter_name[64];

    unsigned int offset;


    unsigned int length;

};


└─[$] <> xxd chapter.dat                              

0000000: 2c7b 004e e07a 0000 0000 0000 0000 0000  ,{.N.z..........

0000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000040: 0000 0000 0e50 0000 2c7b 8c4e e07a 0000  .....P..,{.N.z..

0000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000080: 0000 0000 0000 0000 0e50 0000 e644 0000  .........P...D..

0000090: 2c7b 094e e07a 0000 0000 0000 0000 0000  ,{.N.z..........

00000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00000d0: f494 0000 e448 0000 2c7b db56 e07a 0000  .....H..,{.V.z..

00000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00000f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000100: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000110: 0000 0000 0000 0000 d8dd 0000 6a4f 0000  ............jO..

0000120: 2c7b 944e e07a 0000 0000 0000 0000 0000  ,{.N.z..........

0000130: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000140: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000150: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000160: 422d 0100 8e4f 0000 2c7b 6d51 e07a 0000  B-...O..,{mQ.z..

0000170: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000180: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000190: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00001a0: 0000 0000 0000 0000 d07c 0100 da66 0000  .........|...f..

00001b0: 2c7b 034e e07a 0000 0000 0000 0000 0000  ,{.N.z..........

00001c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00001f0: aae3 0100 4c4a 0000 2c7b 6b51 e07a 0000  ....LJ..,{kQ.z..

0000200: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000210: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000220: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000230: 0000 0000 0000 0000 f62d 0200 785b 0000  .........-..x[..

0000240: 2c7b 5d4e e07a 2000 08ff 004e 09ff 0000  ,{]N.z ....N....

0000250: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000260: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000270: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000280: 6e89 0200 665d 0000 2c7b 5d4e e07a 2000  n...f]..,{]N.z .

0000290: 08ff 8c4e 09ff 0000 0000 0000 0000 0000  ...N............

00002a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00002b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00002c0: 0000 0000 0000 0000 d4e6 0200 0c15 0000  ................

00002d0: 2c7b 4153 e07a 0000 0000 0000 0000 0000  ,{AS.z..........

00002e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00002f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000300: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000310: e0fb 0200 3e5f 0000 2c7b 4153 004e e07a  ....>_..,{AS.N.z

0000320: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000330: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000340: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000350: 0000 0000 0000 0000 1e5b 0300 ca51 0000  .........[...Q..

0000360: 2c7b 4153 8c4e e07a 0000 0000 0000 0000  ,{AS.N.z........

0000370: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000380: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000390: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00003a0: e8ac 0300 dc6e 0000 2c7b 4153 094e e07a  .....n..,{AS.N.z

00003b0: 2000 08ff 004e 09ff 0000 0000 0000 0000   ....N..........

00003c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00003d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00003e0: 0000 0000 0000 0000 c41b 0400 7864 0000  ............xd..

00003f0: 2c7b 4153 094e e07a 2000 08ff 8c4e 09ff  ,{AS.N.z ....N..

0000400: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000410: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000420: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000430: 3c80 0400 f418 0000 2c7b 4153 db56 e07a  <.......,{AS.V.z

0000440: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000450: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000460: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000470: 0000 0000 0000 0000 3099 0400 0a68 0000  ........0....h..

0000480: 2c7b 4153 944e e07a 0000 0000 0000 0000  ,{AS.N.z........

0000490: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00004a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00004b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00004c0: 3a01 0500 fa6a 0000 2c7b 4153 6d51 e07a  :....j..,{ASmQ.z

00004d0: 2000 08ff 004e 09ff 0000 0000 0000 0000   ....N..........

00004e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00004f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000500: 0000 0000 0000 0000 346c 0500 5c37 0000  ........4l..\7..

0000510: 2c7b 4153 6d51 e07a 2000 08ff 8c4e 09ff  ,{ASmQ.z ....N..

0000520: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000530: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000540: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000550: 90a3 0500 803a 0000 2c7b 4153 034e e07a  .....:..,{AS.N.z

0000560: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000570: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000580: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000590: 0000 0000 0000 0000 10de 0500 6264 0000  ............bd..

00005a0: 2c7b 4153 6b51 e07a 0000 0000 0000 0000  ,{ASkQ.z........

00005b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00005c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00005d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00005e0: 7242 0600 3069 0000 2c7b 4153 5d4e e07a  rB..0i..,{AS]N.z

00005f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000600: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000610: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000620: 0000 0000 0000 0000 a2ab 0600 3a68 0000  ............:h..

0000630: 2c7b 8c4e 4153 e07a 0000 0000 0000 0000  ,{.NAS.z........

0000640: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000650: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000660: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000670: dc13 0700 8864 0000 2c7b 8c4e 4153 004e  .....d..,{.NAS.N

0000680: e07a 0000 0000 0000 0000 0000 0000 0000  .z..............

0000690: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00006a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00006b0: 0000 0000 0000 0000 6478 0700 5062 0000  ........dx..Pb..

00006c0: 2c7b 8c4e 4153 8c4e e07a 0000 0000 0000  ,{.NAS.N.z......

00006d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00006e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00006f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000700: b4da 0700 f86b 0000 2c7b 8c4e 4153 094e  .....k..,{.NAS.N

0000710: e07a 2000 08ff 004e 09ff 0000 0000 0000  .z ....N........

0000720: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000730: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000740: 0000 0000 0000 0000 ac46 0800 1457 0000  .........F...W..

0000750: 2c7b 8c4e 4153 094e e07a 2000 08ff 8c4e  ,{.NAS.N.z ....N

0000760: 09ff 0000 0000 0000 0000 0000 0000 0000  ................

0000770: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000780: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000790: c09d 0800 e831 0000 2c7b 8c4e 4153 db56  .....1..,{.NAS.V

00007a0: e07a 2000 08ff 004e 09ff 0000 0000 0000  .z ....N........

00007b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00007c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00007d0: 0000 0000 0000 0000 a8cf 0800 da50 0000  .............P..

00007e0: 2c7b 8c4e 4153 db56 e07a 2000 08ff 8c4e  ,{.NAS.V.z ....N

00007f0: 09ff 0000 0000 0000 0000 0000 0000 0000  ................

0000800: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000810: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000820: 8220 0900 bc36 0000 2c7b 8c4e 4153 944e  . ...6..,{.NAS.N

0000830: e07a 2000 08ff 004e 09ff 0000 0000 0000  .z ....N........

0000840: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000850: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000860: 0000 0000 0000 0000 3e57 0900 e852 0000  ........>W...R..

0000870: 2c7b 8c4e 4153 944e e07a 2000 08ff 8c4e  ,{.NAS.N.z ....N

0000880: 09ff 0000 0000 0000 0000 0000 0000 0000  ................

0000890: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00008a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00008b0: 26aa 0900 9c35 0000 2c7b 8c4e 4153 6d51  &....5..,{.NASmQ

00008c0: e07a 2000 08ff 004e 09ff 0000 0000 0000  .z ....N........

00008d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00008e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00008f0: 0000 0000 0000 0000 c2df 0900 103e 0000  .............>..

0000900: 2c7b 8c4e 4153 6d51 e07a 2000 08ff 8c4e  ,{.NASmQ.z ....N

0000910: 09ff 0000 0000 0000 0000 0000 0000 0000  ................

0000920: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000930: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000940: d21d 0a00 3c42 0000 2c7b 8c4e 4153 034e  ....

0000950: e07a 2000 08ff 004e 09ff 0000 0000 0000  .z ....N........

0000960: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000970: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000980: 0000 0000 0000 0000 0e60 0a00 d254 0000  .........`...T..

0000990: 2c7b 8c4e 4153 034e e07a 2000 08ff 8c4e  ,{.NAS.N.z ....N

00009a0: 09ff 0000 0000 0000 0000 0000 0000 0000  ................

00009b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00009c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

00009d0: e0b4 0a00 3030 0000 2c7b 8c4e 4153 6b51  ....00..,{.NASkQ

00009e0: e07a 2000 08ff 004e 09ff 0000 0000 0000  .z ....N........

00009f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000a00: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000a10: 0000 0000 0000 0000 10e5 0a00 764f 0000  ............vO..

0000a20: 2c7b 8c4e 4153 6b51 e07a 2000 08ff 8c4e  ,{.NASkQ.z ....N

0000a30: 09ff 0000 0000 0000 0000 0000 0000 0000  ................

0000a40: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000a50: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000a60: 8634 0b00 4031 0000 2c7b 8c4e 4153 5d4e  .4..@1..,{.NAS]N

0000a70: e07a 2000 08ff 004e 09ff 0000 0000 0000  .z ....N........

0000a80: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000a90: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000aa0: 0000 0000 0000 0000 c665 0b00 7a59 0000  .........e..zY..

0000ab0: 2c7b 8c4e 4153 5d4e e07a 2000 08ff 8c4e  ,{.NAS]N.z ....N

0000ac0: 09ff 0000 0000 0000 0000 0000 0000 0000  ................

0000ad0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ae0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000af0: 40bf 0b00 681f 0000 2c7b 094e 4153 e07a  @...h...,{.NAS.z

0000b00: 2000 08ff 004e 09ff 0000 0000 0000 0000   ....N..........

0000b10: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000b20: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000b30: 0000 0000 0000 0000 a8de 0b00 ee54 0000  .............T..

0000b40: 2c7b 094e 4153 e07a 2000 08ff 8c4e 09ff  ,{.NAS.z ....N..

0000b50: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000b60: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000b70: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000b80: 9633 0c00 1425 0000 2c7b 094e 4153 004e  .3...%..,{.NAS.N

0000b90: e07a 2000 08ff 004e 09ff 0000 0000 0000  .z ....N........

0000ba0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000bb0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000bc0: 0000 0000 0000 0000 aa58 0c00 f463 0000  .........X...c..

0000bd0: 2c7b 094e 4153 004e e07a 2000 08ff 8c4e  ,{.NAS.N.z ....N

0000be0: 09ff 0000 0000 0000 0000 0000 0000 0000  ................

0000bf0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000c00: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000c10: 9ebc 0c00 761d 0000 2c7b 094e 4153 8c4e  ....v...,{.NAS.N

0000c20: e07a 2000 08ff 004e 09ff 0000 0000 0000  .z ....N........

0000c30: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000c40: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000c50: 0000 0000 0000 0000 14da 0c00 c05a 0000  .............Z..

0000c60: 2c7b 094e 4153 8c4e e07a 2000 08ff 8c4e  ,{.NAS.N.z ....N

0000c70: 09ff 0000 0000 0000 0000 0000 0000 0000  ................

0000c80: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000c90: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ca0: d434 0d00 5a28 0000 2c7b 094e 4153 094e  .4..Z(..,{.NAS.N

0000cb0: e07a 0000 0000 0000 0000 0000 0000 0000  .z..............

0000cc0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000cd0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ce0: 0000 0000 0000 0000 2e5d 0d00 fc6d 0000  .........]...m..

0000cf0: 2c7b 094e 4153 db56 e07a 2000 08ff 004e  ,{.NAS.V.z ....N

0000d00: 09ff 0000 0000 0000 0000 0000 0000 0000  ................

0000d10: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000d20: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000d30: 2acb 0d00 5248 0000 2c7b 094e 4153 db56  *...RH..,{.NAS.V

0000d40: e07a 2000 08ff 8c4e 09ff 0000 0000 0000  .z ....N........

0000d50: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000d60: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000d70: 0000 0000 0000 0000 7c13 0e00 7423 0000  ........|...t#..

0000d80: 0000 0000 0bab 0000 0bab 0000 2ea7 0000  ................

0000d90: 3952 0100 a3a2 0000 dcf4 0100 dfa4 0000  9R..............

0000da0: bb99 0200 f8a1 0000 b33b 0300 45a7 0000  .........;..E...

0000db0: f8e2 0300 c8a7 0000 c08a 0400 61a4 0000  ............a...

0000dc0: 212f 0500 66a3 0000 87d2 0500 84a4 0000  !/..f...........

0000dd0: 0b77 0600 7da6 0000 881d 0700 51a4 0000  .w..}.......Q...

0000de0: d9c1 0700 efa3 0000 c865 0800 a5a6 0000  .........e......

0000df0: 6d0c 0900 fc26 0000 0000 0000 0000 0000  m....&..........

0000e00: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000e10: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000e20: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000e30: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000e40: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000e50: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000e60: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000e70: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000e80: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000e90: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ea0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000eb0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ec0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ed0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ee0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ef0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000f00: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000f10: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000f20: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000f30: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000f40: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000f50: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000f60: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000f70: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000f80: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000f90: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000fa0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000fb0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000fc0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000fd0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000fe0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

0000ff0: 0000 0000 0000 0000 0000 0000 0000 0000  ................


由于未解压前的小说内容是分为多个段压缩存储的,

也就是说未解压前的数据是不具备搜索功能的。

因此,我们可以确定,偏移的这0000 500e (20494)个字节是解压后的。

仔细观察还可以看到,后面一部分数据中没有出现2c7b(第)。这部分就是

压缩数据块信息了。解压分成了很多数据块的正文需要这个信息。

====================================================================

实际上我后面试验了下,把导出的txt文件只保留第一章,然后统计其字节数:

└─[$] <> wc -c aaa.txt

20496 aaa.txt

可以看到是20496 (为什么?前面有两个字节的BOM)

这是后话了。

====================================================================

现在该是时候总结下104个字节的head的结构的作用了:

  

   |0 - 3  |4  |  book_id                    |一般为全0                               |

   |4 - 5  |2  |  head_data_size             |ebk2文件的head大小,一般为104字节       |

  这个主要是让程序读取head时,知道它该读取多长的数据。

   |6 - 7  |2  |  ebk_version                |ebk文件的版本                           |

  标明当前文件的版本(版本不同,解析方法不同)。

   |8 -11  |4  |  ebk_size                   |ebk2文件大小                            |

    这个应该是用于快速判断ebk2文件是否完整。

   |12-75  |64 |  book_name                  |书名                                    |

  这个就不用说了。

   |76-79  |4  |  file_size                  |解压后txt文件的大小(包括章节名和内容) |

   可以用于判断解压后的txt是否完整~~

   |80-83  |4  |  head_compress_size         |章节信息索引表和压缩块信息的大小(压缩后的)|

这个主要用来确定章节信息索引表和压缩块信息的压缩数据的大小,在后面定位小说正文偏移也要用到。

在header之后就是这个数据,这个值是告诉程序header往后再读取这么多个字节来解压。

   |84-87  |4  |  first_compress_block_size  |第一个压缩块的大小                      |

第一个小说正文压缩块的大小

   |88-89  |2  |  chapter_count              |章节数                                  |

   |90-91  |2  |  compress_block_count       |小说内容压缩段的数量                    |

这个主要用于后面分段解压后再合并。

   |92-95  |4  |  media_count                |媒体数量                                |

   +-------+---+-----------------------------+----------------------------------------+

   |96-99  |4  |  media_data_length          |媒体数据长度                            |

   +-------+---+-----------------------------+----------------------------------------+

   |100-103|4  |  txt_compress_size          |压缩后的小说正文内容大小                |

现在,再次深入到ebk2文件了。

ebk2文件的结构应该修正为:

header (一般是104字节)

head_compress (章节信息+压缩块信息)

compressed_txt (正文,多个压缩块)

下面想一下解压思路吧。

读取第4-5字节,获知 header->head_data_size (104) 。

然后,读取 header->head_data_size 个字节,获知整个ebk2文件的头信息。

从header->book_name可以获取UTF-16LE编码的书名。

然后,根据header->head_compress_size 读取压缩的header信息(包括章节信息和压缩块信息)

解压出压缩的header信息,

根据chapter_count 和 compress_block_count ,把相应的数据复制过来,即得到章节列表信息和压缩列表信息。

如果只需要解压为一个txt文件,那么只需要用到压缩块信息。如果需要提取单个章节,那就需要章节信息。

这里假设我们要解压ekb2文件为一个txt文件。

接下来根据压缩块信息和 header->compress_block_count

从header.head_data_size + header.head_compress_size 偏移处开始,对于每个压缩块,进行解压。

每解压一个数据块就写入到文件。如此进行header->compress_block_count次后,即得到解压后的txt文件。

再根据header->file_size  可判断解压是否成功。

花了一些时间,写出转换程序。
在Archlinux 32位下测试成功。
然后就是在windows 下的编译了。。。windows下的编译比Linux下麻烦得多。最终我用Code::Blocks搞定。

===========================================================
ebk2 转 txt windows 32位,动态链接版 下载
myebk2txt-v1.0-动态链接版.zip

EOF===========================================================

[培训]内核驱动高级班,冲击BAT一流互联网大厂工 作,每周日13:00-18:00直播授课

上传的附件:
收藏
点赞3
打赏
分享
最新回复 (11)
雪    币: 190
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
kxzjchen 2012-11-10 23:12
2
0
貌似不错,顶个,以后再看
雪    币: 55
活跃值: (519)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
hrpirip 1 2012-11-10 23:33
3
0
果断收藏。
123456
雪    币: 114
活跃值: (155)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qqlinhai 2012-11-11 00:03
4
0
V5,支持~~
雪    币: 182
活跃值: (111)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Aaah 2012-11-19 09:21
5
0
smali完全不懂.lz功力深厚.
雪    币: 146
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
蓝冰love 2012-11-20 00:06
6
0
不错 果断的收藏一下
雪    币: 240
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yinghetao 2013-1-3 19:29
7
0
介绍ebk2格式的,学习一下
雪    币: 341
活跃值: (133)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
地狱怪客 2 2013-4-19 06:23
8
0
牛掰。。。http://e.dangdang.com/datasvr/permissionAuth.do?bookUid=bb.132584588115452082&pageNo=1


偶遇这个http://e.dangdang.com/datasvr/admin/   
当当网Reader.swf
dangdangReader.rar
上传的附件:
雪    币: 406
活跃值: (164)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
荒野无灯 5 2013-4-19 09:52
9
0
这个swf文件你从中找可利用的地方没有?
雪    币: 259
活跃值: (249)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
健力宝 2013-4-19 11:11
10
0
怪客。。。明显就是。。。intrude
雪    币: 341
活跃值: (133)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
地狱怪客 2 2013-4-19 12:04
11
0
嘿嘿..暂时没看.打游戏了....
雪    币: 18
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
trisinker 2015-5-20 13:29
12
0
现在不用这么麻烦了,下载iReader for Windows Phone, ebk2和ebk3立破!
游客
登录 | 注册 方可回帖
返回