From e332988c75c5427088e4559d4e0f0b386a562314 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 5 Dec 2013 01:36:29 -0500 Subject: Don't pack struct. --- image-parser.c | 63 ++++++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 33 deletions(-) (limited to 'image-parser.c') diff --git a/image-parser.c b/image-parser.c index cb385cc..b135101 100644 --- a/image-parser.c +++ b/image-parser.c @@ -16,24 +16,21 @@ #include #include -#define MAGIC 0xFEEDBABE - -struct Header { /* Big Endian */ - uint32_t magic; /* 0xFEEDBABE */ - uint32_t len; /* Length of file excluding header */ - uint32_t checksum; /* 32-bit sum of all bytes in file and header, excluding checksum */ - uint32_t counter; /* Unknown */ - uint32_t start_offset; /* Unknown */ - char name[0x80]; /* File name */ -} __attribute__((packed)); - +#define RG_MAGIC 0xFEEDBABE +#define HEADER_SIZE ( sizeof(uint32_t) * 5 + 0x80 ) struct File { - struct Header header; - uint8_t *data; - uint32_t decompressed_size; - uint8_t *decompressed_data; + uint32_t magic; /* FEEDBABE */ + uint32_t size; /* Length of file excluding header */ + uint32_t checksum; /* 32-bit sum of all bytes in file and header, excluding checksum */ + uint32_t counter; /* Unknown */ + uint32_t start_offset; /* Unknown */ + char name[0x80]; /* Filename */ + uint8_t *data; /* Pointer to mmap'd or allocated data of file */ + uint32_t decompressed_size; /* Decompressed length of file */ + uint8_t *decompressed_data; /* Pointer to allocated decompressed data */ }; + uint8_t* decompress_data(uint8_t *data, uint32_t compressed_length, uint32_t decompressed_length) { uint8_t *decompressed_data; @@ -81,7 +78,7 @@ uint32_t checksum(uint8_t *data, uint32_t length) while (length--) { /* The checksum does not include itself, so we skip that field. */ - if (length >= offsetof(struct Header, checksum) && length < offsetof(struct Header, counter)) + if (length >= 8 && length < 12) continue; sum += data[length]; } @@ -91,33 +88,33 @@ uint32_t checksum(uint8_t *data, uint32_t length) bool read_file(uint8_t *data, struct File *file) { - memcpy(&file->header, data, sizeof(file->header)); - file->header.magic = be32toh(file->header.magic); - file->header.len = be32toh(file->header.len); - file->header.checksum = be32toh(file->header.checksum); - file->header.counter = be32toh(file->header.counter); - file->header.start_offset = be32toh(file->header.start_offset); - file->header.name[0x7f] = '\0'; - - file->data = data + sizeof(file->header); + uint32_t *packed_integers = (uint32_t *)data; + file->magic = be32toh(packed_integers[0]); + file->size = be32toh(packed_integers[1]); + file->checksum = be32toh(packed_integers[2]); + file->counter = be32toh(packed_integers[3]); + file->start_offset = be32toh(packed_integers[4]); + memcpy(&file->name, &packed_integers[5], sizeof(file->name)); + file->name[0x7f] = '\0'; + file->data = data + HEADER_SIZE; file->decompressed_data = NULL; file->decompressed_size = 0; - if (!strcmp(file->header.name, "rg_conf")) { + if (!strcmp(file->name, "rg_conf")) { /* When the file is gzipped, the length of the decompressed file is * the first four bytes in big endian. */ file->decompressed_size = be32toh(*((uint32_t *)file->data)); - file->decompressed_data = decompress_data(file->data + sizeof(uint32_t), file->header.len - sizeof(uint32_t), file->decompressed_size); + file->decompressed_data = decompress_data(file->data + sizeof(uint32_t), file->size - sizeof(uint32_t), file->decompressed_size); if (!file->decompressed_data) file->decompressed_size = 0; } - return file->header.magic == MAGIC && file->header.checksum == checksum(data, sizeof(file->header) + file->header.len); + return file->magic == RG_MAGIC && file->checksum == checksum(data, HEADER_SIZE + file->size); } void print_file(struct File *file, bool valid) { - printf("==== %s (%s) ====\n", file->header.name, valid ? "Valid Checksum" : "INVALID CHECKSUM"); - printf("Length: %u bytes\n", file->header.len); + printf("==== %s (%s) ====\n", file->name, valid ? "Valid Checksum" : "INVALID CHECKSUM"); + printf("Length: %u bytes\n", file->size); if (file->decompressed_size) printf("Decompressed Length: %u bytes\n", file->decompressed_size); } @@ -128,7 +125,7 @@ void save_file(struct File *file, bool valid, uint32_t offset) char *slash; int fd; - sprintf(filename, "%#.8x-%s%s", offset, file->header.name, valid ? "" : ".corrupt"); + sprintf(filename, "%#.8x-%s%s", offset, file->name, valid ? "" : ".corrupt"); for (slash = filename; (slash = strchr(slash, '/')) != NULL; ++slash) *slash = '_'; @@ -145,7 +142,7 @@ void save_file(struct File *file, bool valid, uint32_t offset) exit(EXIT_FAILURE); } } else { - if (write(fd, file->data, file->header.len) < 0) { + if (write(fd, file->data, file->size) < 0) { perror("write"); exit(EXIT_FAILURE); } @@ -184,7 +181,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - needle = htobe32(MAGIC); + needle = htobe32(RG_MAGIC); next = data; for (;;) { next = memmem(next, sbuf.st_size - (next - data), &needle, sizeof(needle)); -- cgit v1.2.3-59-g8ed1b