#include #include "mystdlib.h" #include #include #include #include /* lha header: 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 */ static uint8_t mantra_in[] = { 0x68, 0x35, 0x2d, 0x6c }; int main( int args, char **argv ) { int filenum = 0, run = 1; size_t offset = 0, reported = 0, enc_len = 32; ssize_t oldoffset = -1; uint8_t mantra[4], id0, id5, *mappedfile; 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 = atol( optarg ); break; default: fputs( "Syntax: %s [-e encrypted_length (default: 32, for streets 34 or 0)] path-to-teiln.dat", stderr ); exit( 1 ); break; } } run = 1; if( optind == args ) { fputs( "Missing filename.", stderr ); exit( 1 ); } map = map_file( argv[optind], 1 ); mappedfile = map->addr; mantra[0] = mantra_in[0] ^ mappedfile[4]; mantra[1] = mantra_in[1] ^ mappedfile[5]; mantra[2] = mantra_in[2] ^ mappedfile[2]; mantra[3] = mantra_in[3] ^ mappedfile[3]; id0 = mappedfile[0]; id5 = mappedfile[5]; while( run ) { while( ( offset < map->size ) && ( ( mappedfile[ offset + 0 ] != id0 ) || ( mappedfile[ offset + 2 ] != ( '-' ^ mantra[2] )) || ( mappedfile[ offset + 3 ] != ( 'l' ^ mantra[3] )) || ( mappedfile[ offset + 4 ] != ( 'h' ^ mantra[0] )) || ( mappedfile[ offset + 5 ] != id5 ) || ( mappedfile[ 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 ); } if( offset == map->size ) run = 0; if( oldoffset != -1 ) { uint8_t *mf = mappedfile + oldoffset, df[128]; size_t filename_len, header_len, i; char filename_template[32], filename[32]; /* De-"crypt" obfuscation to our header copy */ for( i=0; i header_len ) { write( i, df, enc_len ); write( i, mf + enc_len, offset - oldoffset - enc_len ); } else { write( i, df, header_len ); write( i, mf + header_len, offset - oldoffset - header_len ); } close( i ); } oldoffset = offset; offset++; } unmap_file( &map ); return 0; }