New weird syntax
[kugel-rb.git] / tools / descramble.c
blob7ed32139c6e5158554d7cd092d5a0ea15259b5e8
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Björn Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include <stdio.h>
21 #include <stdlib.h>
23 int main (int argc, char** argv)
25 unsigned long length,i,slen;
26 unsigned char *inbuf,*outbuf;
27 unsigned char *iname = argv[1];
28 unsigned char *oname = argv[2];
29 unsigned char header[32];
30 int headerlen = 6;
31 int descramble = 1;
32 FILE* file;
34 if (argc < 3) {
35 printf("usage: %s [-fm] [-v2] [-mm] <input file> <output file>\n",
36 argv[0]);
37 return -1;
40 if (!strcmp(argv[1], "-fm") || !strcmp(argv[1], "-v2")) {
41 headerlen = 24;
42 iname = argv[2];
43 oname = argv[3];
46 if (!strcmp(argv[1], "-mm")) {
47 headerlen = 16;
48 iname = argv[2];
49 oname = argv[3];
50 descramble = 0;
53 /* open file and check size */
54 file = fopen(iname,"rb");
55 if (!file) {
56 perror(oname);
57 return -1;
59 fseek(file,0,SEEK_END);
60 length = ftell(file) - headerlen; /* skip header */
61 fseek(file,0,SEEK_SET);
62 i = fread(header, 1, headerlen, file);
63 if ( !i ) {
64 perror(iname);
65 return -1;
68 inbuf = malloc(length);
69 outbuf = malloc(length);
70 if ( !inbuf || !outbuf ) {
71 printf("out of memory!\n");
72 return -1;
75 /* read file */
76 i=fread(inbuf,1,length,file);
77 if ( !i ) {
78 perror(iname);
79 return -1;
81 fclose(file);
83 if (descramble) {
84 /* descramble */
85 slen = length/4;
86 for (i = 0; i < length; i++) {
87 unsigned long addr = ((i % slen) << 2) + i/slen;
88 unsigned char data = inbuf[i];
89 data = ~((data >> 1) | ((data << 7) & 0x80)); /* poor man's ROR */
90 outbuf[addr] = data;
93 else {
94 void* tmpptr;
95 unsigned int j=0;
96 int stringlen = 32;
97 int unpackedsize;
98 unsigned char xorstring[32];
100 unpackedsize = header[4] | header[5] << 8;
101 unpackedsize |= header[6] << 16 | header[7] << 24;
103 length = header[8] | header[9] << 8;
104 length |= header[10] << 16 | header[11] << 24;
106 /* calculate the xor string used */
107 for (i=0; i<stringlen; i++) {
108 int top=0, topchar=0, c;
109 int bytecount[256];
110 memset(bytecount, 0, sizeof(bytecount));
112 /* gather byte frequency statistics */
113 for (c=i; c<length; c+=stringlen)
114 bytecount[inbuf[c]]++;
116 /* find the most frequent byte */
117 for (c=0; c<256; c++) {
118 if (bytecount[c] > top) {
119 top = bytecount[c];
120 topchar = c;
123 xorstring[i] = topchar;
125 printf("XOR string: %.*s\n", stringlen, xorstring);
127 /* xor the buffer */
128 for (i=0; i<length; i++)
129 outbuf[i] = inbuf[i] ^ xorstring[i & (stringlen-1)];
131 /* unpack */
132 tmpptr = realloc(inbuf, unpackedsize);
133 memset(tmpptr, 0, unpackedsize);
134 inbuf = outbuf;
135 outbuf = tmpptr;
137 for (i=0; i<length;) {
138 int bit;
139 int head = inbuf[i++];
141 for (bit=0; bit<8 && i<length; bit++) {
142 if (head & (1 << (bit))) {
143 outbuf[j++] = inbuf[i++];
145 else {
146 int x;
147 int byte1 = inbuf[i];
148 int byte2 = inbuf[i+1];
149 int count = (byte2 & 0x0f) + 3;
150 int src =
151 (j & 0xfffff000) + (byte1 | ((byte2 & 0xf0)<<4)) + 18;
152 if (src > j)
153 src -= 0x1000;
155 for (x=0; x<count; x++)
156 outbuf[j++] = outbuf[src+x];
157 i += 2;
161 length = j;
164 /* write file */
165 file = fopen(oname,"wb");
166 if ( !file ) {
167 perror(argv[2]);
168 return -1;
170 if ( !fwrite(outbuf,length,1,file) ) {
171 perror(argv[2]);
172 return -1;
174 fclose(file);
176 free(inbuf);
177 free(outbuf);
179 return 0;