1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Maurus Cuelenaere
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 ****************************************************************************/
26 #if !defined(__APPLE__)
29 #include "mac-elf.h" /* Mac OS X doesn't distribuate elf.h... */
33 #include "hmac-sha1.h"
35 static const char null_key_v1
[] = "CTL:N0MAD|PDE0.SIGN.";
36 static const char null_key_v2
[] = "CTL:N0MAD|PDE0.DPMP.";
37 static const char null_key_v3
[] = "CTL:Z3N07|PDE0.DPMP.";
38 static const char null_key_v4
[] = "CTL:N0MAD|PDE0.DPFP.";
40 static const struct device_info devices
[] =
42 /* Creative Zen Vision:M */
43 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0:\0M", 42, null_key_v2
},
44 /* Creative Zen Vision:M Go! */
45 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0:\0M\0 \0G\0o\0!", 50, null_key_v2
},
46 /* Creative Zen Vision © TL */
47 /* The "©" should be ANSI encoded or the device won't accept the firmware package. */
48 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0 \0©\0T\0L", 46, null_key_v2
},
50 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0E\0N\0 \0V", 42, null_key_v4
},
52 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0E\0N", 48, null_key_v3
}
56 Create a Zen Vision:M FRESCUE structure file
58 extern void int2le(unsigned int val
, unsigned char* addr
);
59 extern unsigned int le2int(unsigned char* buf
);
62 static int make_ciff_file(const unsigned char *inbuf
, unsigned int length
,
63 unsigned char *outbuf
, int device
)
65 unsigned char key
[20];
66 memcpy(outbuf
, "FFIC", 4);
67 int2le(length
+90, &outbuf
[4]);
68 memcpy(&outbuf
[8], "FNIC", 4);
69 int2le(96, &outbuf
[0xC]);
70 memcpy(&outbuf
[0x10], devices
[device
].cinf
, devices
[device
].cinf_size
);
71 memset(&outbuf
[0x10+devices
[device
].cinf_size
], 0,
72 96 - devices
[device
].cinf_size
);
73 memcpy(&outbuf
[0x70], "ATAD", 4);
74 int2le(length
+32, &outbuf
[0x74]);
75 memcpy(&outbuf
[0x78], "H\0j\0u\0k\0e\0b\0o\0x\0\x32\0.\0j\0r\0m",
76 25); /*Unicode encoded*/
77 memset(&outbuf
[0x78+25], 0, 32);
78 memcpy(&outbuf
[0x98], inbuf
, length
);
79 memcpy(&outbuf
[0x98+length
], "LLUN", 4);
80 int2le(20, &outbuf
[0x98+length
+4]);
82 hmac_sha1((unsigned char *)devices
[device
].null
, strlen(devices
[device
].null
),
83 outbuf
, 0x98+length
, key
);
84 memcpy(&outbuf
[0x98+length
+8], key
, 20);
85 return length
+0x90+0x1C+8;
88 static int elf_convert(const unsigned char *inbuf
, unsigned char *outbuf
)
90 Elf32_Ehdr
*main_header
;
91 Elf32_Shdr
*section_header
;
92 unsigned int i
, j
, sum
;
95 main_header
= (Elf32_Ehdr
*)inbuf
;
96 if( !( main_header
->e_ident
[0] == ELFMAG0
&& main_header
->e_ident
[1] == ELFMAG1
97 && main_header
->e_ident
[2] == ELFMAG2
&& main_header
->e_ident
[3] == ELFMAG3
) )
99 printf("Invalid ELF header!\n");
103 startaddr
= (intptr_t)outbuf
;
105 for(i
= 0; i
< main_header
->e_shnum
; i
++)
107 section_header
= (Elf32_Shdr
*)(inbuf
+main_header
->e_shoff
+i
*sizeof(Elf32_Shdr
));
109 if( (section_header
->sh_flags
& SHF_WRITE
|| section_header
->sh_flags
& SHF_ALLOC
110 || section_header
->sh_flags
& SHF_EXECINSTR
) && section_header
->sh_size
> 0
111 && section_header
->sh_type
!= SHT_NOBITS
)
114 int2le(section_header
->sh_addr
, outbuf
);
117 int2le(section_header
->sh_size
, outbuf
);
121 for(j
=0; j
<section_header
->sh_size
; j
+= 4)
122 sum
+= le2int((unsigned char*)(inbuf
+section_header
->sh_offset
+j
)) + (le2int((unsigned char*)(inbuf
+section_header
->sh_offset
+j
))>>16);
125 memset(outbuf
, 0, 2);
128 memcpy(outbuf
, inbuf
+section_header
->sh_offset
, section_header
->sh_size
);
129 outbuf
+= section_header
->sh_size
;
132 return (int)((intptr_t)outbuf
- startaddr
);
135 static int make_jrm_file(const unsigned char *inbuf
, unsigned char *outbuf
)
139 /* Clear the header area to zero */
140 memset(outbuf
, 0, 0x18);
143 memcpy(outbuf
, "EDOC", 4);
144 /* Total Size: temporarily set to 0 */
145 memset(&outbuf
[0x4], 0, 4);
146 /* 4 bytes of zero */
147 memset(&outbuf
[0x8], 0, 4);
149 length
= elf_convert(inbuf
, &outbuf
[0xC]);
152 /* Now set the actual Total Size */
153 int2le(4+length
, &outbuf
[0x4]);
158 int zvm_encode(const char *iname
, const char *oname
, int device
, bool enable_ciff
)
163 unsigned char *outbuf
;
166 file
= fopen(iname
, "rb");
172 fseek(file
, 0, SEEK_END
);
173 length
= ftell(file
);
175 fseek(file
, 0, SEEK_SET
);
177 buf
= (unsigned char*)malloc(length
);
180 printf("Out of memory!\n");
184 len
= fread(buf
, 1, length
, file
);
185 if(len
< (size_t)length
)
192 outbuf
= (unsigned char*)malloc(length
+0x300);
196 printf("Out of memory!\n");
199 length
= make_jrm_file(buf
, outbuf
);
204 printf("Error in making JRM file!\n");
209 buf
= (unsigned char*)malloc(length
+0x200);
213 printf("Out of memory!\n");
216 memset(buf
, 0, length
+0x200);
217 length
= make_ciff_file(outbuf
, length
, buf
, device
);
223 file
= fopen(oname
, "wb");
231 len
= fwrite(buf
, 1, length
, file
);
232 if(len
< (size_t)length
)