(以内容“某文件格式 mac.afs: found records @ tail 1st filename @ 2C6000 2nd filename @ 2C6030 3rd filename @ 2C6060 -> file record: 0x30 = 48 bytes 1st record: 0x2C6000 ...”创建新页面) |
|||
第1行: | 第1行: | ||
某文件格式 | 某文件格式 | ||
+ | <pre> | ||
mac.afs: | mac.afs: | ||
第13行: | 第14行: | ||
0x2C6024 0D 00 0A 00 | 0x2C6024 0D 00 0A 00 | ||
0x2C6028 06 00 20 00 -> + 00 00 02 00 | 0x2C6028 06 00 20 00 -> + 00 00 02 00 | ||
− | 0x2C602C 31 01 00 00 305 | + | 0x2C602C 31 01 00 00 305 -> file count? |
2nd record: | 2nd record: | ||
0x2C6030 KA01.BIP 00..00 | 0x2C6030 KA01.BIP 00..00 | ||
− | 0x2C6050 D9 07 08 00 | + | 0x2C6050 D9 07 08 00 -> static |
− | 0x2C6054 0D 00 0A 00 | + | 0x2C6054 0D 00 0A 00 -> static |
− | 0x2C6058 06 00 22 00 | + | 0x2C6058 06 00 22 00 -> increasing ? |
− | 0x2C605C 00 10 00 00 4096 | + | 0x2C605C 00 10 00 00 4096 -> 1st start |
3rd record: | 3rd record: | ||
0x2C6060 KA02.BIP 00..00 | 0x2C6060 KA02.BIP 00..00 | ||
第25行: | 第26行: | ||
0x2C6080 0D 00 0A 00 | 0x2C6080 0D 00 0A 00 | ||
0x2C6080 06 00 24 00 | 0x2C6080 06 00 24 00 | ||
− | 0x2C6080 7F 13 00 00 4991 | + | 0x2C6080 7F 13 00 00 4991 -> 1st size |
Last record @ 0x2C9900 Total: 305 = 0x131 records | Last record @ 0x2C9900 Total: 305 = 0x131 records | ||
第31行: | 第32行: | ||
Last file start @ 2C5800 | Last file start @ 2C5800 | ||
-> Min block size: 0x200 = 512 bytes | -> Min block size: 0x200 = 512 bytes | ||
− | 1st / 2nd start @ 0x1000 -? 0x237F size: 0x137F | + | 1st / 2nd start @ 0x1000 -? 0x237F size: 0x137F -> KA02.BIP |
− | next start @ 0x2800 diff: 0x4000 -? | + | next start @ 0x2800 diff: 0x4000 -? 0x65B8 size: 0x3DB8 -> KA04.BIP |
− | next start @ 0x6800 diff: 0x4000 | + | next start @ 0x6800 diff: 0x4000 size: 0xC63C -> KA06.BIP |
− | next start @ 0xA800 -? | + | next start @ 0xA800 size: 0x379C -> KA08.BIP |
+ | next start @ 0xE000 -? 0x1335A size: 0x535A diff: 0x5800 -> KAO.BIP | ||
next start @ 0x13800 diff: | next start @ 0x13800 diff: | ||
+ | |||
+ | Header: 0x00 AFS\0 | ||
+ | 0x0004 31 01 00 00 -> 0x131 = 305: record count | ||
+ | 0x0008 00 10 00 00 -> 1st start | ||
+ | 0x000C 7F 13 00 00 -> 1st size | ||
+ | 0001000: 0823 0000 ff09 0f06 0000 6008 005f 0900 .#........`.._.. | ||
+ | 0001010: 0860 fff5 f009 f9f0 ff4c 008c 0012 0319 .`.......L...... | ||
+ | 0001020: 00ff 1a00 6580 0100 65a0 ff01 0033 0100 ....e...e....3.. | ||
+ | 0001030: 01ff 10bb 3510 e8f3 6400 02eb f0c0 8fff ....5...d....... | ||
+ | 0001040: 1e00 0f2b 0231 0fea f165 ff02 5a00 6520 ...+.1...e..Z.e | ||
+ | 0x0010 00 28 00 00 -> 2nd start | ||
+ | 0x0014 B8 3D 00 00 -> 2nd size | ||
+ | 0002800: 0c6d 0000 ff09 0f06 0000 6008 00ff 1203 .m........`..... | ||
+ | 0002810: 1900 1a00 6580 ff1e 0065 a001 0033 01bf ....e....e...3.. | ||
+ | 0002820: 0001 ff10 0010 e8f3 65ff 0201 0065 2001 ........e....e . | ||
+ | 0002830: 0009 ef00 0860 0a19 0009 6014 b619 0001 .....`....`..... | ||
+ | 0002840: a0ec f000 0229 0203 be29 021a 6000 004c .....)...)..`..L | ||
+ | 0x0018 00 68 00 00 -> 3rd start | ||
+ | 0x001C C6 3C 00 00 -> 3rd size | ||
+ | 0006800: 6367 0000 ff09 0f06 0000 6008 00df 0900 cg........`..... | ||
+ | 0006810: 0860 0af5 f009 60ff 1900 4c00 4f00 5300 .`....`...L.O.S. | ||
+ | 0006820: ff74 1065 8001 0065 a0ff 0100 3301 0001 .t.e...e....3... | ||
+ | 0006830: ff10 bb4f 10e8 f364 0002 ebf0 c08f ff2d ...O...d.......- | ||
+ | 0006840: 000f 2902 2f0f eaf1 41ff 043f 0340 003e ..)./...A..?.@.> | ||
+ | 0x0020 00 A8 00 00 -> 4th start | ||
+ | 0x0024 9C 37 00 00 -> 4th size | ||
+ | 000a800: b163 0000 ff09 0f06 0000 6008 00df 0900 .c........`..... | ||
+ | 000a810: 0860 0af5 f009 60ff 1b00 4c00 5200 5300 .`....`...L.R.S. | ||
+ | 000a820: ff70 1065 8001 0065 a0ff 0100 3301 0001 .p.e...e....3... | ||
+ | 000a830: ff10 fb0a 10e8 f341 043f 0340 ff00 3e00 .......A.?.@..>. | ||
+ | 000a840: 3b80 3c80 3bff 8039 033a 0038 000f ff00 ;.<.;..9.:.8.... | ||
+ | 0x0028 00 E0 00 00 -> 5th start | ||
+ | 0x002C 5A 53 00 00 -> 5th size | ||
+ | 0x0030 00 38 01 00 -> 6th start | ||
+ | |||
+ | 于是可以解出来 但是貌似多数文件都压缩了…… | ||
+ | ADX = Ogg | ||
+ | BIP: Many possible formats... | ||
+ | T2P: Image, ... | ||
+ | </pre> | ||
+ | |||
+ | <source lang="cpp"> | ||
+ | #include <iostream> | ||
+ | #include <fcntl.h> | ||
+ | #include <vector> | ||
+ | #include <string> | ||
+ | #include <sys/endian.h> | ||
+ | #include <errno.h> | ||
+ | #include <sys/stat.h> | ||
+ | #include <zlib.h> | ||
+ | using namespace std; | ||
+ | |||
+ | typedef unsigned char uchar; | ||
+ | |||
+ | int uncompress(char *buf, int size, char *newbuf, int newsize) | ||
+ | { | ||
+ | int ret; | ||
+ | z_stream strm; | ||
+ | |||
+ | /* allocate inflate state */ | ||
+ | strm.zalloc = Z_NULL; | ||
+ | strm.zfree = Z_NULL; | ||
+ | strm.opaque = Z_NULL; | ||
+ | strm.avail_in = 0; | ||
+ | strm.next_in = Z_NULL; | ||
+ | ret = inflateInit(&strm); | ||
+ | if (ret != Z_OK) | ||
+ | return ret; | ||
+ | |||
+ | /* decompress until deflate stream ends or end of file */ | ||
+ | strm.avail_in = size; | ||
+ | strm.next_in = (Bytef *)buf; | ||
+ | |||
+ | /* run inflate() on input until output buffer not full */ | ||
+ | strm.avail_out = newsize; | ||
+ | strm.next_out = (Bytef *)newbuf; | ||
+ | ret = inflate(&strm, Z_NO_FLUSH); | ||
+ | if(ret == Z_STREAM_ERROR) /* state not clobbered */ | ||
+ | return ret; | ||
+ | switch (ret) { | ||
+ | case Z_NEED_DICT: | ||
+ | ret = Z_DATA_ERROR; /* and fall through */ | ||
+ | case Z_DATA_ERROR: | ||
+ | case Z_MEM_ERROR: | ||
+ | (void)inflateEnd(&strm); | ||
+ | return ret; | ||
+ | } | ||
+ | |||
+ | /* done when inflate() says it's done */ | ||
+ | |||
+ | /* clean up and return */ | ||
+ | (void)inflateEnd(&strm); | ||
+ | return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; | ||
+ | |||
+ | } | ||
+ | |||
+ | string dump(unsigned char *data) | ||
+ | { | ||
+ | char buf[20]; | ||
+ | snprintf(buf, 20, "%02x %02x %02x %02x", data[0], data[1], data[2], data[3]); | ||
+ | return string(buf); | ||
+ | } | ||
+ | |||
+ | void toh(uint32_t &x) | ||
+ | { | ||
+ | x = le32toh(x); | ||
+ | } | ||
+ | |||
+ | class File { | ||
+ | int size, offset; | ||
+ | uchar sig1[4], sig2[4], mark[4], xx[4]; | ||
+ | string name; | ||
+ | public: | ||
+ | File(int _offset, int _size) : size(_size), offset(_offset) {} | ||
+ | int get_size() { return size; } | ||
+ | int get_offset() { return offset; } | ||
+ | const string & get_name() { return name; } | ||
+ | void set_info(const string& _name, uchar *_sig1, uchar *_sig2, uchar *_mark, uchar *_xx) | ||
+ | { | ||
+ | name = _name; | ||
+ | memcpy(sig1, _sig1, 4); | ||
+ | memcpy(sig2, _sig1, 4); | ||
+ | memcpy(mark, _mark, 4); | ||
+ | memcpy(xx, _xx, 4); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | |||
+ | int main(int argc, char **argv) | ||
+ | { | ||
+ | if (argc < 2) | ||
+ | { | ||
+ | cout << "usage: " << argv[0] << " <afs file> [<output dir>]" << endl; | ||
+ | return -1; | ||
+ | } | ||
+ | char head[4]; | ||
+ | int f = open(argv[1], O_RDONLY); | ||
+ | if (f < 0) | ||
+ | { | ||
+ | cout << "fail to open file: " << errno << endl; | ||
+ | return -2; | ||
+ | } | ||
+ | read(f, head, 4); | ||
+ | if (memcmp(head, "AFS\0", 4) != 0) | ||
+ | { | ||
+ | cout << "signature mismatch!\n" << endl; | ||
+ | close(f); | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | vector<File> files; | ||
+ | uint32_t filecount; | ||
+ | read(f, &filecount, 4); | ||
+ | filecount = le32toh(filecount); | ||
+ | cout << "file count: " << filecount << endl; | ||
+ | // last file: directory | ||
+ | for (int i=0; i<filecount+1; i++) | ||
+ | { | ||
+ | uint32_t offset, size; | ||
+ | read(f, &offset, 4); | ||
+ | read(f, &size, 4); | ||
+ | toh(offset); | ||
+ | toh(size); | ||
+ | if ((size == 0) && (i == filecount)) | ||
+ | { // ugly state: no last record | ||
+ | int x = files[i-1].get_offset() + files[i-1].get_size() + 1; | ||
+ | lseek(f, x, SEEK_SET); | ||
+ | char ch; | ||
+ | read(f, &ch, 1); | ||
+ | while (ch == 0) | ||
+ | { | ||
+ | read(f, &ch, 1); | ||
+ | x++; | ||
+ | } | ||
+ | offset = x; | ||
+ | size = 0x30 * filecount; | ||
+ | } | ||
+ | |||
+ | files.push_back(File(offset, size)); | ||
+ | // cout << "File " << i << ": offset=" << hex << files[i].get_offset() << ",size=" << size << "#" << dec << size << dec << endl; | ||
+ | } | ||
+ | for (int i=0; i<filecount; i++) | ||
+ | { | ||
+ | lseek(f, files[filecount].get_offset() + 0x30 * i, SEEK_SET); | ||
+ | char name[33]; | ||
+ | name[32] = '\0'; | ||
+ | read(f, name, 32); | ||
+ | string sname(name); | ||
+ | unsigned char sig1[4]; | ||
+ | unsigned char sig2[4]; | ||
+ | read(f, sig1, 4); | ||
+ | read(f, sig2, 4); | ||
+ | unsigned char mark[4]; | ||
+ | read(f, mark, 4); | ||
+ | unsigned char xx[4]; | ||
+ | read(f, xx, 4); | ||
+ | files[i].set_info(sname, sig1, sig2, mark, xx); | ||
+ | cout << "File " << i << ": name=" << sname << ",offset=" << hex << files[i].get_offset() << ",size=" << files[i].get_size() << dec << endl; | ||
+ | cout << "sig1=" << dump(sig1) << ",sig2=" << dump(sig2) << ",mark=" << dump(mark) << ",mock=" << dump(xx) << endl; | ||
+ | } | ||
+ | if (argc > 2) | ||
+ | { | ||
+ | string destdir = argv[2]; | ||
+ | mkdir(destdir.c_str(), 0755); | ||
+ | int bufsize = 0; | ||
+ | char *buf = NULL; | ||
+ | char *unbuf = NULL; | ||
+ | int unbufsize = 0; | ||
+ | for (int i=0; i<filecount; i++) | ||
+ | { | ||
+ | File &frec = files[i]; | ||
+ | lseek(f, frec.get_offset(), SEEK_SET); | ||
+ | if (frec.get_size() > bufsize) | ||
+ | { | ||
+ | if (buf) | ||
+ | delete []buf; | ||
+ | buf = new char[frec.get_size()]; | ||
+ | } | ||
+ | int cnt = read(f, buf, frec.get_size()); | ||
+ | if (cnt != frec.get_size()) | ||
+ | { | ||
+ | cerr << "warning: partial read for " << frec.get_name() << " " << cnt << " instead of " << frec.get_size() << " errno " << errno << endl; | ||
+ | } | ||
+ | string destpath = destdir + "/" + frec.get_name(); | ||
+ | int outf = open(destpath.c_str(), O_WRONLY | O_CREAT, 0644); | ||
+ | if (outf < 0) | ||
+ | { | ||
+ | cerr << "failed to open output file for " << destpath << " : " << errno << endl; | ||
+ | } else { | ||
+ | cout << "writing to " << destpath << " size: " << cnt << endl; | ||
+ | write(outf, buf, cnt); | ||
+ | close(outf); | ||
+ | } | ||
+ | |||
+ | if (argc > 3) | ||
+ | { | ||
+ | // uncompress, does not work... | ||
+ | uint32_t oldsize; | ||
+ | memcpy(&oldsize, buf, 4); | ||
+ | toh(oldsize); | ||
+ | if (oldsize > unbufsize) | ||
+ | { | ||
+ | if (unbuf) | ||
+ | delete []unbuf; | ||
+ | unbuf = new char[oldsize]; | ||
+ | } | ||
+ | |||
+ | int ret = uncompress(buf+0x8, cnt-0x8, unbuf, oldsize); | ||
+ | if (ret != Z_OK) | ||
+ | { | ||
+ | cerr << "uncompress failed! " << ret << endl; | ||
+ | } else { | ||
+ | string undest = destdir + "/" + "_" + frec.get_name(); | ||
+ | int outunf = open(undest.c_str(), O_WRONLY | O_CREAT, 0644); | ||
+ | if (outunf < 0) | ||
+ | { | ||
+ | cerr << "failed to open output file for " << undest << " : " << errno << endl; | ||
+ | } else { | ||
+ | cout << "writing to " << undest << " size: " << oldsize << endl; | ||
+ | write(outunf, unbuf, oldsize); | ||
+ | close(outunf); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </source> |
2012年1月9日 (一) 08:32的版本
某文件格式
mac.afs: found records @ tail 1st filename @ 2C6000 2nd filename @ 2C6030 3rd filename @ 2C6060 -> file record: 0x30 = 48 bytes 1st record: 0x2C6000 BAD.BIP 00..00 0x2C6020 D9 07 08 00 0x2C6024 0D 00 0A 00 0x2C6028 06 00 20 00 -> + 00 00 02 00 0x2C602C 31 01 00 00 305 -> file count? 2nd record: 0x2C6030 KA01.BIP 00..00 0x2C6050 D9 07 08 00 -> static 0x2C6054 0D 00 0A 00 -> static 0x2C6058 06 00 22 00 -> increasing ? 0x2C605C 00 10 00 00 4096 -> 1st start 3rd record: 0x2C6060 KA02.BIP 00..00 0x2C6080 D9 07 08 00 0x2C6080 0D 00 0A 00 0x2C6080 06 00 24 00 0x2C6080 7F 13 00 00 4991 -> 1st size Last record @ 0x2C9900 Total: 305 = 0x131 records Last file start @ 2C5800 -> Min block size: 0x200 = 512 bytes 1st / 2nd start @ 0x1000 -? 0x237F size: 0x137F -> KA02.BIP next start @ 0x2800 diff: 0x4000 -? 0x65B8 size: 0x3DB8 -> KA04.BIP next start @ 0x6800 diff: 0x4000 size: 0xC63C -> KA06.BIP next start @ 0xA800 size: 0x379C -> KA08.BIP next start @ 0xE000 -? 0x1335A size: 0x535A diff: 0x5800 -> KAO.BIP next start @ 0x13800 diff: Header: 0x00 AFS\0 0x0004 31 01 00 00 -> 0x131 = 305: record count 0x0008 00 10 00 00 -> 1st start 0x000C 7F 13 00 00 -> 1st size 0001000: 0823 0000 ff09 0f06 0000 6008 005f 0900 .#........`.._.. 0001010: 0860 fff5 f009 f9f0 ff4c 008c 0012 0319 .`.......L...... 0001020: 00ff 1a00 6580 0100 65a0 ff01 0033 0100 ....e...e....3.. 0001030: 01ff 10bb 3510 e8f3 6400 02eb f0c0 8fff ....5...d....... 0001040: 1e00 0f2b 0231 0fea f165 ff02 5a00 6520 ...+.1...e..Z.e 0x0010 00 28 00 00 -> 2nd start 0x0014 B8 3D 00 00 -> 2nd size 0002800: 0c6d 0000 ff09 0f06 0000 6008 00ff 1203 .m........`..... 0002810: 1900 1a00 6580 ff1e 0065 a001 0033 01bf ....e....e...3.. 0002820: 0001 ff10 0010 e8f3 65ff 0201 0065 2001 ........e....e . 0002830: 0009 ef00 0860 0a19 0009 6014 b619 0001 .....`....`..... 0002840: a0ec f000 0229 0203 be29 021a 6000 004c .....)...)..`..L 0x0018 00 68 00 00 -> 3rd start 0x001C C6 3C 00 00 -> 3rd size 0006800: 6367 0000 ff09 0f06 0000 6008 00df 0900 cg........`..... 0006810: 0860 0af5 f009 60ff 1900 4c00 4f00 5300 .`....`...L.O.S. 0006820: ff74 1065 8001 0065 a0ff 0100 3301 0001 .t.e...e....3... 0006830: ff10 bb4f 10e8 f364 0002 ebf0 c08f ff2d ...O...d.......- 0006840: 000f 2902 2f0f eaf1 41ff 043f 0340 003e ..)./...A..?.@.> 0x0020 00 A8 00 00 -> 4th start 0x0024 9C 37 00 00 -> 4th size 000a800: b163 0000 ff09 0f06 0000 6008 00df 0900 .c........`..... 000a810: 0860 0af5 f009 60ff 1b00 4c00 5200 5300 .`....`...L.R.S. 000a820: ff70 1065 8001 0065 a0ff 0100 3301 0001 .p.e...e....3... 000a830: ff10 fb0a 10e8 f341 043f 0340 ff00 3e00 .......A.?.@..>. 000a840: 3b80 3c80 3bff 8039 033a 0038 000f ff00 ;.<.;..9.:.8.... 0x0028 00 E0 00 00 -> 5th start 0x002C 5A 53 00 00 -> 5th size 0x0030 00 38 01 00 -> 6th start 于是可以解出来 但是貌似多数文件都压缩了…… ADX = Ogg BIP: Many possible formats... T2P: Image, ...
#include <iostream>
#include <fcntl.h>
#include <vector>
#include <string>
#include <sys/endian.h>
#include <errno.h>
#include <sys/stat.h>
#include <zlib.h>
using namespace std;
typedef unsigned char uchar;
int uncompress(char *buf, int size, char *newbuf, int newsize)
{
int ret;
z_stream strm;
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
/* decompress until deflate stream ends or end of file */
strm.avail_in = size;
strm.next_in = (Bytef *)buf;
/* run inflate() on input until output buffer not full */
strm.avail_out = newsize;
strm.next_out = (Bytef *)newbuf;
ret = inflate(&strm, Z_NO_FLUSH);
if(ret == Z_STREAM_ERROR) /* state not clobbered */
return ret;
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
/* done when inflate() says it's done */
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
string dump(unsigned char *data)
{
char buf[20];
snprintf(buf, 20, "%02x %02x %02x %02x", data[0], data[1], data[2], data[3]);
return string(buf);
}
void toh(uint32_t &x)
{
x = le32toh(x);
}
class File {
int size, offset;
uchar sig1[4], sig2[4], mark[4], xx[4];
string name;
public:
File(int _offset, int _size) : size(_size), offset(_offset) {}
int get_size() { return size; }
int get_offset() { return offset; }
const string & get_name() { return name; }
void set_info(const string& _name, uchar *_sig1, uchar *_sig2, uchar *_mark, uchar *_xx)
{
name = _name;
memcpy(sig1, _sig1, 4);
memcpy(sig2, _sig1, 4);
memcpy(mark, _mark, 4);
memcpy(xx, _xx, 4);
}
};
int main(int argc, char **argv)
{
if (argc < 2)
{
cout << "usage: " << argv[0] << " <afs file> [<output dir>]" << endl;
return -1;
}
char head[4];
int f = open(argv[1], O_RDONLY);
if (f < 0)
{
cout << "fail to open file: " << errno << endl;
return -2;
}
read(f, head, 4);
if (memcmp(head, "AFS\0", 4) != 0)
{
cout << "signature mismatch!\n" << endl;
close(f);
return 1;
}
vector<File> files;
uint32_t filecount;
read(f, &filecount, 4);
filecount = le32toh(filecount);
cout << "file count: " << filecount << endl;
// last file: directory
for (int i=0; i<filecount+1; i++)
{
uint32_t offset, size;
read(f, &offset, 4);
read(f, &size, 4);
toh(offset);
toh(size);
if ((size == 0) && (i == filecount))
{ // ugly state: no last record
int x = files[i-1].get_offset() + files[i-1].get_size() + 1;
lseek(f, x, SEEK_SET);
char ch;
read(f, &ch, 1);
while (ch == 0)
{
read(f, &ch, 1);
x++;
}
offset = x;
size = 0x30 * filecount;
}
files.push_back(File(offset, size));
// cout << "File " << i << ": offset=" << hex << files[i].get_offset() << ",size=" << size << "#" << dec << size << dec << endl;
}
for (int i=0; i<filecount; i++)
{
lseek(f, files[filecount].get_offset() + 0x30 * i, SEEK_SET);
char name[33];
name[32] = '\0';
read(f, name, 32);
string sname(name);
unsigned char sig1[4];
unsigned char sig2[4];
read(f, sig1, 4);
read(f, sig2, 4);
unsigned char mark[4];
read(f, mark, 4);
unsigned char xx[4];
read(f, xx, 4);
files[i].set_info(sname, sig1, sig2, mark, xx);
cout << "File " << i << ": name=" << sname << ",offset=" << hex << files[i].get_offset() << ",size=" << files[i].get_size() << dec << endl;
cout << "sig1=" << dump(sig1) << ",sig2=" << dump(sig2) << ",mark=" << dump(mark) << ",mock=" << dump(xx) << endl;
}
if (argc > 2)
{
string destdir = argv[2];
mkdir(destdir.c_str(), 0755);
int bufsize = 0;
char *buf = NULL;
char *unbuf = NULL;
int unbufsize = 0;
for (int i=0; i<filecount; i++)
{
File &frec = files[i];
lseek(f, frec.get_offset(), SEEK_SET);
if (frec.get_size() > bufsize)
{
if (buf)
delete []buf;
buf = new char[frec.get_size()];
}
int cnt = read(f, buf, frec.get_size());
if (cnt != frec.get_size())
{
cerr << "warning: partial read for " << frec.get_name() << " " << cnt << " instead of " << frec.get_size() << " errno " << errno << endl;
}
string destpath = destdir + "/" + frec.get_name();
int outf = open(destpath.c_str(), O_WRONLY | O_CREAT, 0644);
if (outf < 0)
{
cerr << "failed to open output file for " << destpath << " : " << errno << endl;
} else {
cout << "writing to " << destpath << " size: " << cnt << endl;
write(outf, buf, cnt);
close(outf);
}
if (argc > 3)
{
// uncompress, does not work...
uint32_t oldsize;
memcpy(&oldsize, buf, 4);
toh(oldsize);
if (oldsize > unbufsize)
{
if (unbuf)
delete []unbuf;
unbuf = new char[oldsize];
}
int ret = uncompress(buf+0x8, cnt-0x8, unbuf, oldsize);
if (ret != Z_OK)
{
cerr << "uncompress failed! " << ret << endl;
} else {
string undest = destdir + "/" + "_" + frec.get_name();
int outunf = open(undest.c_str(), O_WRONLY | O_CREAT, 0644);
if (outunf < 0)
{
cerr << "failed to open output file for " << undest << " : " << errno << endl;
} else {
cout << "writing to " << undest << " size: " << oldsize << endl;
write(outunf, unbuf, oldsize);
close(outunf);
}
}
}
}
}
}