发现从 iReader_1.3.2.0 版本起就采用了动态库把ebk相关解析函数封装了,
逆向iReader解读ebk2电子书格式
。因此,这里我用的是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 - 5head_data_size
0068 ,其十进制值为:104. 这与上图的结构是相符的。即整个ebk2文件头部信息数据总大小为 104个字节。
6-7 字节为 ebk文件版本,上面数据: 0200 ,其十六进制为:0002 ,即表示ebk2格式。
8 -11|4|ebk_size6636 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 Nov3 16:57 《白鹿原》.ebk2.txt*
为什么是931570 ? 因为加上了两个字节的BOM (FFFE).
80-
83|4|head_compress_size9502 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 utlen = 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 0000B-...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 2000n...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 e07arB..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 00009R..............
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 0000m....&..........
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................
由于未解压前的小说内容是分为多个段压缩存储的,
也就是说未解压前的数据是不具备搜索功能的,
电脑资料
《逆向iReader解读ebk2电子书格式》()。因此,我们可以确定,偏移的这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搞定。
EOF===========================================================