1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Björn Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 int iaudio_decode(char *iname
, char *oname
);
31 unsigned int le2int(unsigned char* buf
)
33 unsigned int res
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
38 void int2le(unsigned int val
, unsigned char* addr
)
41 addr
[1] = (val
>> 8) & 0xff;
42 addr
[2] = (val
>> 16) & 0xff;
43 addr
[3] = (val
>> 24) & 0xff;
48 printf("usage: descramble [options] <input file> <output file>\n");
50 "\t-fm Archos FM recorder format\n"
51 "\t-v2 Archos V2 recorder format\n"
52 "\t-mm Archos Multimedia format\n"
53 "\t-iriver iRiver format\n"
54 "\t-gigabeat Toshiba Gigabeat format\n"
55 "\t-iaudio iAudio format\n"
56 "\nNo option assumes Archos standard player/recorder format.\n");
60 int main (int argc
, char** argv
)
62 unsigned long length
,i
,slen
;
63 unsigned char *inbuf
,*outbuf
;
64 char *iname
= argv
[1];
65 char *oname
= argv
[2];
66 unsigned char header
[32];
75 if (!strcmp(argv
[1], "-fm") || !strcmp(argv
[1], "-v2")) {
81 if (!strcmp(argv
[1], "-mm")) {
88 if(!strcmp(argv
[1], "-iriver")) {
89 /* iRiver code dealt with in the iriver.c code */
92 return iriver_decode(iname
, oname
, FALSE
, STRIP_NONE
) ? -1 : 0;
94 if(!strcmp(argv
[1], "-gigabeat")) {
97 gigabeat_code(iname
, oname
);
101 if(!strcmp(argv
[1], "-iaudio")) {
104 return iaudio_decode(iname
, oname
);
107 /* open file and check size */
108 file
= fopen(iname
,"rb");
113 fseek(file
,0,SEEK_END
);
114 length
= ftell(file
) - headerlen
; /* skip header */
115 fseek(file
,0,SEEK_SET
);
116 i
= fread(header
, 1, headerlen
, file
);
122 inbuf
= malloc(length
);
123 outbuf
= malloc(length
);
124 if ( !inbuf
|| !outbuf
) {
125 printf("out of memory!\n");
130 i
=fread(inbuf
,1,length
,file
);
140 for (i
= 0; i
< length
; i
++) {
141 unsigned long addr
= ((i
% slen
) << 2) + i
/slen
;
142 unsigned char data
= inbuf
[i
];
143 data
= ~((data
>> 1) | ((data
<< 7) & 0x80)); /* poor man's ROR */
152 unsigned char xorstring
[32];
154 unpackedsize
= header
[4] | header
[5] << 8;
155 unpackedsize
|= header
[6] << 16 | header
[7] << 24;
157 length
= header
[8] | header
[9] << 8;
158 length
|= header
[10] << 16 | header
[11] << 24;
160 /* calculate the xor string used */
161 for (i
=0; i
<(unsigned long)stringlen
; i
++) {
162 int top
=0, topchar
=0, c
;
164 memset(bytecount
, 0, sizeof(bytecount
));
166 /* gather byte frequency statistics */
167 for (c
=i
; c
<(int)length
; c
+=stringlen
)
168 bytecount
[inbuf
[c
]]++;
170 /* find the most frequent byte */
171 for (c
=0; c
<256; c
++) {
172 if (bytecount
[c
] > top
) {
177 xorstring
[i
] = topchar
;
179 printf("XOR string: %.*s\n", stringlen
, xorstring
);
182 for (i
=0; i
<length
; i
++)
183 outbuf
[i
] = inbuf
[i
] ^ xorstring
[i
& (stringlen
-1)];
186 tmpptr
= realloc(inbuf
, unpackedsize
);
187 memset(tmpptr
, 0, unpackedsize
);
191 for (i
=0; i
<length
;) {
193 int head
= inbuf
[i
++];
195 for (bit
=0; bit
<8 && i
<length
; bit
++) {
196 if (head
& (1 << (bit
))) {
197 outbuf
[j
++] = inbuf
[i
++];
201 int byte1
= inbuf
[i
];
202 int byte2
= inbuf
[i
+1];
203 int count
= (byte2
& 0x0f) + 3;
205 (j
& 0xfffff000) + (byte1
| ((byte2
& 0xf0)<<4)) + 18;
209 for (x
=0; x
<count
; x
++)
210 outbuf
[j
++] = outbuf
[src
+x
];
219 file
= fopen(oname
,"wb");
224 if ( !fwrite(outbuf
,length
,1,file
) ) {
236 int iaudio_decode(char *iname
, char *oname
)
243 unsigned char sum
= 0;
244 unsigned char filesum
;
246 file
= fopen(iname
, "rb");
251 fseek(file
,0,SEEK_END
);
252 length
= ftell(file
);
254 fseek(file
,0,SEEK_SET
);
255 outbuf
= malloc(length
);
258 printf("out of memory!\n");
262 len
= fread(outbuf
, 1, length
, file
);
263 if(len
< (size_t)length
) {
270 for(i
= 0; i
< length
-0x1030;i
++)
271 sum
+= outbuf
[0x1030 + i
];
273 filesum
= outbuf
[0x102b];
276 printf("Checksum mismatch!\n");
280 file
= fopen(oname
, "wb");
286 len
= fwrite(outbuf
+0x1030, 1, length
-0x1030, file
);
287 if(len
< (size_t)length
-0x1030) {