diff options
author | Björn Stenberg <bjorn@haxx.se> | 2004-01-08 00:22:27 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2004-01-08 00:22:27 +0000 |
commit | 7f749b4689dfb212580abbd568818e95a922fe49 (patch) | |
tree | 63b816528108964514178e49d7e188c87094743a | |
parent | a55bfd920468f26a8e97e4387c73d69375f58676 (diff) | |
download | rockbox-7f749b4689dfb212580abbd568818e95a922fe49.tar.gz rockbox-7f749b4689dfb212580abbd568818e95a922fe49.zip |
Added support for multimedia .ajz files
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4199 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | tools/descramble.c | 105 |
1 files changed, 95 insertions, 10 deletions
diff --git a/tools/descramble.c b/tools/descramble.c index d28e18a951..8ba8d4a18f 100644 --- a/tools/descramble.c +++ b/tools/descramble.c | |||
@@ -26,11 +26,14 @@ int main (int argc, char** argv) | |||
26 | unsigned char *inbuf,*outbuf; | 26 | unsigned char *inbuf,*outbuf; |
27 | unsigned char *iname = argv[1]; | 27 | unsigned char *iname = argv[1]; |
28 | unsigned char *oname = argv[2]; | 28 | unsigned char *oname = argv[2]; |
29 | unsigned char header[32]; | ||
29 | int headerlen = 6; | 30 | int headerlen = 6; |
31 | int descramble = 1; | ||
30 | FILE* file; | 32 | FILE* file; |
31 | 33 | ||
32 | if (argc < 3) { | 34 | if (argc < 3) { |
33 | printf("usage: %s [-fm] [-v2] <input file> <output file>\n",argv[0]); | 35 | printf("usage: %s [-fm] [-v2] [-mm] <input file> <output file>\n", |
36 | argv[0]); | ||
34 | return -1; | 37 | return -1; |
35 | } | 38 | } |
36 | 39 | ||
@@ -39,6 +42,13 @@ int main (int argc, char** argv) | |||
39 | iname = argv[2]; | 42 | iname = argv[2]; |
40 | oname = argv[3]; | 43 | oname = argv[3]; |
41 | } | 44 | } |
45 | |||
46 | if (!strcmp(argv[1], "-mm")) { | ||
47 | headerlen = 16; | ||
48 | iname = argv[2]; | ||
49 | oname = argv[3]; | ||
50 | descramble = 0; | ||
51 | } | ||
42 | 52 | ||
43 | /* open file and check size */ | 53 | /* open file and check size */ |
44 | file = fopen(iname,"rb"); | 54 | file = fopen(iname,"rb"); |
@@ -48,7 +58,13 @@ int main (int argc, char** argv) | |||
48 | } | 58 | } |
49 | fseek(file,0,SEEK_END); | 59 | fseek(file,0,SEEK_END); |
50 | length = ftell(file) - headerlen; /* skip header */ | 60 | length = ftell(file) - headerlen; /* skip header */ |
51 | fseek(file,headerlen,SEEK_SET); | 61 | fseek(file,0,SEEK_SET); |
62 | i = fread(header, 1, headerlen, file); | ||
63 | if ( !i ) { | ||
64 | perror(iname); | ||
65 | return -1; | ||
66 | } | ||
67 | |||
52 | inbuf = malloc(length); | 68 | inbuf = malloc(length); |
53 | outbuf = malloc(length); | 69 | outbuf = malloc(length); |
54 | if ( !inbuf || !outbuf ) { | 70 | if ( !inbuf || !outbuf ) { |
@@ -64,15 +80,84 @@ int main (int argc, char** argv) | |||
64 | } | 80 | } |
65 | fclose(file); | 81 | fclose(file); |
66 | 82 | ||
67 | /* descramble */ | 83 | if (descramble) { |
68 | slen = length/4; | 84 | /* descramble */ |
69 | for (i = 0; i < length; i++) { | 85 | slen = length/4; |
70 | unsigned long addr = ((i % slen) << 2) + i/slen; | 86 | for (i = 0; i < length; i++) { |
71 | unsigned char data = inbuf[i]; | 87 | unsigned long addr = ((i % slen) << 2) + i/slen; |
72 | data = ~((data >> 1) | ((data << 7) & 0x80)); /* poor man's ROR */ | 88 | unsigned char data = inbuf[i]; |
73 | outbuf[addr] = data; | 89 | data = ~((data >> 1) | ((data << 7) & 0x80)); /* poor man's ROR */ |
90 | outbuf[addr] = data; | ||
91 | } | ||
74 | } | 92 | } |
75 | 93 | else { | |
94 | void* tmpptr; | ||
95 | unsigned int j=0; | ||
96 | int stringlen = 32; | ||
97 | int unpackedsize; | ||
98 | unsigned char xorstring[32]; | ||
99 | |||
100 | unpackedsize = ((unsigned int*)header)[1]; | ||
101 | length = ((unsigned int*)header)[2]; | ||
102 | |||
103 | /* calculate the xor string used */ | ||
104 | for (i=0; i<stringlen; i++) { | ||
105 | int top=0, topchar=0, c; | ||
106 | int bytecount[256]; | ||
107 | memset(bytecount, 0, sizeof(bytecount)); | ||
108 | |||
109 | /* gather byte frequency statistics */ | ||
110 | for (c=i; c<length; c+=stringlen) | ||
111 | bytecount[inbuf[c]]++; | ||
112 | |||
113 | /* find the most frequent byte */ | ||
114 | for (c=0; c<256; c++) { | ||
115 | if (bytecount[c] > top) { | ||
116 | top = bytecount[c]; | ||
117 | topchar = c; | ||
118 | } | ||
119 | } | ||
120 | xorstring[i] = topchar; | ||
121 | } | ||
122 | printf("XOR string: %.*s\n", stringlen, xorstring); | ||
123 | |||
124 | /* xor the buffer */ | ||
125 | for (i=0; i<length; i++) | ||
126 | outbuf[i] = inbuf[i] ^ xorstring[i & (stringlen-1)]; | ||
127 | |||
128 | /* unpack */ | ||
129 | tmpptr = realloc(inbuf, unpackedsize); | ||
130 | memset(tmpptr, 0, unpackedsize); | ||
131 | inbuf = outbuf; | ||
132 | outbuf = tmpptr; | ||
133 | |||
134 | for (i=0; i<length;) { | ||
135 | int bit; | ||
136 | int head = inbuf[i++]; | ||
137 | |||
138 | for (bit=0; bit<8 && i<length; bit++) { | ||
139 | if (head & (1 << (bit))) { | ||
140 | outbuf[j++] = inbuf[i++]; | ||
141 | } | ||
142 | else { | ||
143 | int x; | ||
144 | int byte1 = inbuf[i]; | ||
145 | int byte2 = inbuf[i+1]; | ||
146 | int count = (byte2 & 0x0f) + 3; | ||
147 | int src = | ||
148 | (j & 0xfffff000) + (byte1 | ((byte2 & 0xf0)<<4)) + 18; | ||
149 | if (src > j) | ||
150 | src -= 0x1000; | ||
151 | |||
152 | for (x=0; x<count; x++) | ||
153 | outbuf[j++] = outbuf[src+x]; | ||
154 | i += 2; | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | length = j; | ||
159 | } | ||
160 | |||
76 | /* write file */ | 161 | /* write file */ |
77 | file = fopen(oname,"wb"); | 162 | file = fopen(oname,"wb"); |
78 | if ( !file ) { | 163 | if ( !file ) { |