die Firmware für 613 beginnt mit einem SHA256-Hash, der mit einem mit einem mir unbekannten Schlüssel verschlüsselt ist.
Alles, was danach kommt, ist allerdings unverschlüsselt. Hier ist Beispielcode zum entpacken der pUSB-Datei. Getestet mit MGF613_614_V2.11G_rel_upd_encrypted.pUSB, erhältlich unter http://www.metz-ce.de/de/fernseher/firm ... loads.html.
Code: Alles auswählen
#include <endian.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct section_header_ch613 {
char name[9];
unsigned int offset;
unsigned int size;
unsigned int crc32;
char version[11];
};
static unsigned int le32tohp(const void *ptr)
{
return le32toh(*(const unsigned int *)ptr);
}
static unsigned int crc32_be(const unsigned char *p, size_t len)
{
unsigned int crc = ~0;
size_t i;
while (len--) {
crc ^= *p++ << 24;
for (i = 0; i < 8; i++)
crc = (crc << 1) ^ ((crc & 0x80000000) ? 0x04c11db7 : 0);
}
return crc;
}
static void rtrim(char *str, size_t n)
{
while (n > 0) {
n--;
if (str[n] != ' ')
break;
str[n] = '\0';
}
}
static int process_file_ch613(FILE *f)
{
unsigned char csum[0x20];
char file_header[0x10];
unsigned char section_header[0x40];
struct section_header_ch613 sh;
unsigned int i;
if (!fread(csum, sizeof(csum), 1, f)) {
printf("Can't read checksum\n");
return 1;
}
if (!fread(file_header, sizeof(file_header), 1, f)) {
printf("Can't read header\n");
return 1;
}
rtrim(&file_header[0], 8);
rtrim(&file_header[8], 8);
printf("File header:\n");
printf(" hardware: '%.8s'\n", &file_header[0]);
printf(" version: '%.8s'\n", &file_header[8]);
printf("\n");
for (i = 0; ; i++) {
fseek(f, 0x30 + (i * 0x40), SEEK_SET);
if (!fread(section_header, sizeof(section_header), 1, f)) {
printf("Cannot read section header\n");
return 1;
}
memcpy(sh.name, §ion_header[0], 8);
sh.offset = le32tohp(§ion_header[8]) + 0x20;
sh.size = le32tohp(§ion_header[12]);
sh.crc32 = le32tohp(§ion_header[16]);
memcpy(sh.version, §ion_header[20], 10);
if (!(sh.offset && sh.size))
break;
rtrim(sh.name, 8);
rtrim(sh.version, 10);
printf("Section %u:\n", i);
printf(" name: '%s'\n", sh.name);
printf(" version: '%s'\n", sh.version);
printf(" offset: %#x (%u)\n", sh.offset, sh.offset);
printf(" size: %#x (%u)\n", sh.size, sh.size);
printf(" crc32: %#x\n", sh.crc32);
printf("\n");
unsigned char *buf = malloc(sh.size);
fseek(f, sh.offset, SEEK_SET);
if (!fread(buf, sh.size, 1, f)) {
printf("Cannot read section %s\n", sh.name);
free(buf);
return 1;
}
if (crc32_be(buf, sh.size) != sh.crc32) {
printf("CRC32 mismatch at section %s\n", sh.name);
free(buf);
return 1;
}
char filename[FILENAME_MAX];
snprintf(filename, FILENAME_MAX, "%s.%s", sh.name, strcmp(sh.name, "PACKET") ? "bin" : "tgz");
FILE *o = fopen(filename, "w");
if (o) {
fwrite(buf, sh.size, 1, o);
fclose(o);
}
free(buf);
}
return 0;
}
int main(int argc, char *argv[])
{
FILE *f;
int ret;
if (argc != 2) {
printf("Need exactly one filename!\n");
return 1;
}
f = fopen(argv[1], "rb");
if (f == NULL) {
perror(argv[1]);
return 1;
}
ret = process_file_ch613(f);
fclose(f);
return ret;
}
meetzee