summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2014-01-12 22:07:32 +0100
committerDirk Engling <erdgeist@erdgeist.org>2014-01-12 22:07:32 +0100
commitf2df25ca202300fe04672703ea7fb30d8431b302 (patch)
tree23c4fe224266a3c76d18af359247eba8c428cb07 /src
parenta5e0e84b98553c3198b6d78a095e96baa57e1fed (diff)
Make extract code for old phone books much more generic and detect necessary values automatically
Diffstat (limited to 'src')
-rw-r--r--src/extractblocks_new.c121
1 files changed, 80 insertions, 41 deletions
diff --git a/src/extractblocks_new.c b/src/extractblocks_new.c
index 94ab0b7..53c16f2 100644
--- a/src/extractblocks_new.c
+++ b/src/extractblocks_new.c
@@ -5,76 +5,115 @@
5#include <stdint.h> 5#include <stdint.h>
6#include <unistd.h> 6#include <unistd.h>
7 7
8/* lha header:
9
1000 Header length
1101 Header checksum [02-length]
1202 0x2d ('-')
1303 0x6c ('l')
1404 0x68 ('h')
1505 0x?? ('0' or '5') unsure
1606 0x2d ('-')
1707 0x?? LSB of compressed size
1808 0x?? ..
1909 0x00 ..
2010 0x00 MSB of compressed size, i.e. 0
21..
2221 Length of path name
23
24
25*/
26
27static uint8_t mantra_in[] = { 0x68, 0x00, 0x2d, 0x6c };
28
8int main( int args, char **argv ) 29int main( int args, char **argv )
9{ 30{
10 int filenum = 0; 31 int filenum = 0, run = 1;
11 size_t offset = 0, oldoffset = -1; 32 size_t offset = 0, oldoffset = -1, enc_len = 32;
12 uint8_t *mappedfile; 33 uint8_t mantra[4], id0, id5, *mappedfile;
13 MAP map; 34 MAP map;
14 35
15 uint8_t mantra0 = 0x1b, mantra1 = 0x35, mantra2 = 0x2d, mantra3 = 0x6c; /* clean*/ 36 /* For streets we do have a enc_len of 34 */
16// unsigned char mantra0 = 0x08, mantra1 = 0x57, mantra2 = 0x64, mantra3 = 0x69; /* 98 H */ 37 while( run ) {
17// unsigned char mantra0 = 0x13, mantra1 = 0xe4, mantra2 = 0x55, mantra3 = 0x05; /* 99 F */ 38 switch( getopt( args, argv, ":e:" ) ) {
18// unsigned char mantra0 = 0x12, mantra1 = 0x08, mantra2 = 0x23, mantra3 = 0x01; /* 99 H */ 39 case -1 : run = 0; break;
40 case 'e':
41 enc_len = atol( optarg );
42 break;
43 default:
44 fputs( "Syntax: %s [-e encrypted_length (default: 32, for streets 34 or 0)] path-to-teiln.dat", stderr ); exit( 1 );
45 break;
46 }
47 }
48 run = 1;
19 49
20 if( args != 2 ) 50 if( optind == args )
21 { fputs( "Missing filenames.", stderr ); exit( 1 ); } 51 { fputs( "Missing filename.", stderr ); exit( 1 ); }
22 52
23 map = map_file( argv[1], 1 ); 53 map = map_file( argv[optind], 1 );
24 mappedfile = map->addr; 54 mappedfile = map->addr;
25 55
26 mantra0 ^= mappedfile[0]; 56 mantra[0] = mantra_in[0] ^ mappedfile[4];
27 mantra1 ^= mappedfile[5]; 57 mantra[1] = mantra_in[1] ^ mappedfile[9];
28 mantra2 ^= mappedfile[2]; 58 mantra[2] = mantra_in[2] ^ mappedfile[2];
29 mantra3 ^= mappedfile[3]; 59 mantra[3] = mantra_in[3] ^ mappedfile[3];
60
61 id0 = mappedfile[0];
62 id5 = mappedfile[5];
30 63
31 while( 1 ) 64 while( run )
32 { 65 {
33 while( ( offset < map->size ) && ( 66 while( ( offset < map->size ) && (
34 ( mappedfile[ offset + 0 ] != ( 0x1b^ mantra0 )) || 67 ( mappedfile[ offset + 0 ] != id0 ) ||
35 ( mappedfile[ offset + 2 ] != ( '-' ^ mantra2 )) || 68 ( mappedfile[ offset + 2 ] != ( '-' ^ mantra[2] )) ||
36 ( mappedfile[ offset + 3 ] != ( 'l' ^ mantra3 )) || 69 ( mappedfile[ offset + 3 ] != ( 'l' ^ mantra[3] )) ||
37 ( mappedfile[ offset + 4 ] != ( 'h' ^ mantra0 )) || 70 ( mappedfile[ offset + 4 ] != ( 'h' ^ mantra[0] )) ||
38 ( mappedfile[ offset + 5 ] != ( '5' ^ mantra1 )) || 71 ( mappedfile[ offset + 5 ] != id5 ) ||
39 ( mappedfile[ offset + 6 ] != ( '-' ^ mantra2 )) 72 ( mappedfile[ offset + 6 ] != ( '-' ^ mantra[2] ))
40 ) ) offset++; 73 ) ) offset++;
41 74
42 printf( "Found an appropriate offset at: %zd\n", oldoffset ); 75 printf( "Found an appropriate offset at: %zd\n", offset );
43 76
44 if( offset == map->size ) 77 if( offset == map->size )
45 { 78 run = 0;
46 unmap_file( &map );
47 exit(0);
48 }
49 79
50 if( oldoffset != -1 ) 80 if( oldoffset != -1 )
51 { 81 {
52 uint8_t cs = 0, *mf = mappedfile + oldoffset, df[32]; 82 uint8_t *mf = mappedfile + oldoffset, df[128];
53 char filename[20]; 83 size_t filename_len, header_len;
84 char filename_template[32], filename[32];
54 int i; 85 int i;
55 86
56 for( i=0; i<8; ++i) 87 /* De-"crypt" obfuscation to our header copy */
57 { 88 for( i=0; i<enc_len; ++i)
58 df[4*i+0] = mf[4*i+0] ^ mantra0; 89 df[i] = mf[i] ^ mantra[i%4];
59 df[4*i+1] = mf[4*i+1] ^ mantra1; 90
60 df[4*i+2] = mf[4*i+2] ^ mantra2; 91 /* Get values from LHA header */
61 df[4*i+3] = mf[4*i+3] ^ mantra3; 92 header_len = df[0];
62 } 93 filename_len = df[21];
94
95 /* Copy rest of header, so we can checksum */
96 for( i=enc_len; i<header_len+2; ++i)
97 df[i] = mf[i];
63 98
64 snprintf( filename, sizeof( filename ), "%05d.lha", filenum++ ); 99 /* Make up new sequental file name */
65 memcpy( ((uint8_t*)df) + 22, filename, 5); 100 snprintf( filename_template, sizeof(filename_template), "%%0%dd.lha", (int)filename_len );
101 snprintf( filename, sizeof( filename ), filename_template, filenum++ );
102 memcpy( ((uint8_t*)df) + 22, filename, filename_len);
66 103
67 for( i=2; i<29; ++i) cs += ((uint8_t*)df)[i]; 104 /* Recalculate checksum with new file name */
68 ((uint8_t*)df)[1] = cs; 105 df[1] = 0; for( i=2; i<header_len+2; ++i) df[1] += df[i];
69 106
107 /* Open file and dump our de-"crypted" header and then rest of file */
70 i = open( filename, O_CREAT | O_TRUNC | O_WRONLY, 0644 ); 108 i = open( filename, O_CREAT | O_TRUNC | O_WRONLY, 0644 );
71 write( i, df, 32 ); 109 write( i, df, enc_len );
72 write( i, mf + 32, offset - oldoffset - 32 ); 110 write( i, mf + enc_len, offset - oldoffset - enc_len );
73 close( i ); 111 close( i );
74 } 112 }
75 oldoffset = offset; 113 oldoffset = offset;
76 offset++; 114 offset++;
77 } 115 }
78 116
117 unmap_file( &map );
79 return 0; 118 return 0;
80} 119}