From 43a5ac139b552b23de78434a8ee3df8fc6651b38 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Wed, 29 Apr 2015 12:44:47 +0200 Subject: We have a new format between the former version 1 and 2. So shift version numbers. Add README --- src/export/extract_version_3.c | 170 ++++++++++++++++++++++++++++------------- 1 file changed, 115 insertions(+), 55 deletions(-) (limited to 'src/export/extract_version_3.c') diff --git a/src/export/extract_version_3.c b/src/export/extract_version_3.c index e0e858d..c4914a7 100644 --- a/src/export/extract_version_3.c +++ b/src/export/extract_version_3.c @@ -1,70 +1,130 @@ -#include -#include -#include #include -#include -#include #include "mystdlib.h" +#include +#include +#include +#include -#define XORLEN (29) -#define HUGEBLOCK (8*1024*1024) - -int main(int argc, char **argv) { - unsigned const char xorkey [XORLEN] = "Just for Fun. Linus Torvalds."; - unsigned char input [XORLEN]; - unsigned char output [HUGEBLOCK]; - char respath[32]; /* file_XXXXX\0 */ - int zres = 0, filenum = 0, resfile; - size_t i, offs = 0, reported = 0; - MAP in; - - if( argc != 2 ) exit(111); - in = map_file( argv[1], 1 ); - - z_stream z; memset( &z, 0, sizeof(z)); - - while( offs < in->size ) { - size_t inlen = offs + XORLEN < in->size ? XORLEN : in->size - offs; - for( i=0; iaddr[offs+i] ^ xorkey[i]; - z.next_in = input; z.avail_in = inlen; - z.next_out = output; z.avail_out = HUGEBLOCK; - inflateInit( &z ); zres = inflate( &z, Z_NO_FLUSH ); - if( (zres != Z_OK) && (zres != Z_STREAM_END) ) - goto error_continue; - - z.next_in = in->addr + offs + inlen; - z.avail_in = (unsigned int)(in->size - offs - inlen); - while( zres == Z_OK ) zres = inflate( &z, Z_NO_FLUSH ); - - if( zres != Z_STREAM_END ) { -error_continue: - inflateEnd(&z); memset( &z, 0, sizeof(z)); - offs++; - continue; - } +/* lha header: - sprintf( respath, "file_%05X", filenum++ ); +00 Header length +01 Header checksum [02-length] +02 0x2d ('-') +03 0x6c ('l') +04 0x68 ('h') +05 0x?? ('0' or '5') unsure +06 0x2d ('-') +07 0x?? LSB of compressed size +08 0x?? .. +09 0x00 .. +10 0x00 MSB of compressed size, i.e. 0 +.. +21 Length of path name - resfile = open( respath, O_RDWR | O_CREAT, 0644 ); - if( resfile < 0 ) { - fprintf( stderr, "Could not open output file %s\n", respath ); - exit(1); + +*/ + +static uint8_t mantra_in[] = { 0x68, 0x35, 0x2d, 0x6c }; + +int main( int args, char **argv ) +{ + int filenum = 0, run = 1, first_run = 1; + size_t offset = 0, old_offset = 0, reported = 0, enc_len = 32; + uint8_t mantra[4], id0, id5, *mapped_file; + MAP map; + + /* For streets we do have a enc_len of 34 */ + while( run ) { + switch( getopt( args, argv, ":e:" ) ) { + case -1 : run = 0; break; + case 'e': + enc_len = strtoul( optarg, 0, 0 ); + break; + default: + fputs( "Syntax: %s [-e encrypted_length (default: 32, for streets 34 or 0)] path-to-teiln.dat", stderr ); + exit( 1 ); } - write( resfile, output, z.total_out ); - close( resfile ); - offs += z.total_in; + } + run = 1; + + if( optind == args ) + { fputs( "Missing filename.", stderr ); exit( 1 ); } + + map = map_file( argv[optind], 1 ); + mapped_file = map->addr; - if( reported < ( offs * 10 ) / in->size ) { + mantra[0] = mantra_in[0] ^ mapped_file[4]; + mantra[1] = mantra_in[1] ^ mapped_file[5]; + mantra[2] = mantra_in[2] ^ mapped_file[2]; + mantra[3] = mantra_in[3] ^ mapped_file[3]; + + id0 = mapped_file[0]; + id5 = mapped_file[5]; + + while( run ) + { + while( ( offset < map->size ) && ( + ( mapped_file[ offset + 0 ] != id0 ) || + ( mapped_file[ offset + 2 ] != ( '-' ^ mantra[2] )) || + ( mapped_file[ offset + 3 ] != ( 'l' ^ mantra[3] )) || + ( mapped_file[ offset + 4 ] != ( 'h' ^ mantra[0] )) || + ( mapped_file[ offset + 5 ] != id5 ) || + ( mapped_file[ offset + 6 ] != ( '-' ^ mantra[2] )) + ) ) offset++; + + // printf( "Found an appropriate offset at: %zd\n", offset ); + + if( reported < ( offset * 10 ) / map->size ) + { reported++; printf( "%zd%% ", 10 * reported ); fflush( stdout ); } - inflateEnd(&z); memset( &z, 0, sizeof(z)); + if( offset == map->size ) + run = 0; + + if( !first_run ) + { + uint8_t *mf = mapped_file + old_offset, df[128]; + size_t filename_len, header_len, i; + int fh; + char filename[32]; + + /* De-"crypt" obfuscation to our header copy */ + for( i=0; i header_len ) { + write( fh, df, enc_len ); + write( fh, mf + enc_len, offset - old_offset - enc_len ); + } else { + write( fh, df, header_len ); + write( fh, mf + header_len, offset - old_offset - header_len ); + } + close( fh ); + } + first_run = 0; + old_offset = offset++; } - unmap_file(&in); - if( reported < 10 ) - printf( "100%% " ); - fflush( stdout ); + + unmap_file( &map ); return 0; } -- cgit v1.2.3