From 34fbf4891160f445c773710c73ece973afffd504 Mon Sep 17 00:00:00 2001 From: Sander Vanheule Date: Fri, 3 Feb 2023 23:03:22 +0100 Subject: [PATCH] tplink-safeloader: add vendor info support Some images may contain ASCII vendor info at the start of the image header. Detect this image type, and display the info when requested. Signed-off-by: Sander Vanheule --- src/tplink-safeloader.c | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/tplink-safeloader.c b/src/tplink-safeloader.c index ab08ad1..6937457 100644 --- a/src/tplink-safeloader.c +++ b/src/tplink-safeloader.c @@ -127,8 +127,30 @@ struct __attribute__((__packed__)) soft_version { uint32_t compat_level; }; +/* + * Safeloader image type + * Safeloader images contain a 0x14 byte preamble with image size (big endian + * UINT32) and md5 checksum (16 bytes). + * + * SAFEFLOADER_TYPE_DEFAULT + * Standard preamble with size including preamble length, and checksum. + * Header of 0x1000 bytes, contents of which are not specified. + * Payload starts at offset 0x1014. + * + * SAFELOADER_TYPE_VENDOR + * Standard preamble with size including preamble length, and checksum. + * Header contains up to 0x1000 bytes of vendor data, starting with a big endian + * UINT32 size, followed by that number of bytes containing (text) data. + * Padded with 0xFF. Payload starts at offset 0x1014. + */ +enum safeloader_image_type { + SAFELOADER_TYPE_DEFAULT, + SAFELOADER_TYPE_VENDOR, +}; + /* Internal representation of safeloader image data */ struct safeloader_image_info { + enum safeloader_image_type type; size_t payload_offset; struct flash_partition_entry entries[MAX_PARTITIONS]; }; @@ -3834,6 +3856,11 @@ static void safeloader_parse_image(FILE *input_file, struct safeloader_image_inf if (fread(buf, sizeof(buf), 1, input_file) != 1) error(1, errno, "Can not read image header"); + if (ntohl(*((uint32_t *) &buf[0])) <= SAFELOADER_HEADER_SIZE) + image->type = SAFELOADER_TYPE_VENDOR; + else + image->type = SAFELOADER_TYPE_DEFAULT; + image->payload_offset = SAFELOADER_PAYLOAD_OFFSET; /* Parse image partition table */ @@ -3944,6 +3971,21 @@ static int firmware_info(const char *input) safeloader_parse_image(input_file, &info); + if (info.type == SAFELOADER_TYPE_VENDOR) { + char buf[SAFELOADER_HEADER_SIZE] = {}; + uint32_t vendor_size; + + fseek(input_file, SAFELOADER_PREAMBLE_SIZE, SEEK_SET); + fread(&vendor_size, sizeof(uint32_t), 1, input_file); + + vendor_size = ntohl(vendor_size); + fread(buf, vendor_size, 1, input_file); + + printf("Firmware vendor string:\n"); + fwrite(buf, strnlen(buf, vendor_size), 1, stdout); + printf("\n"); + } + printf("Firmware image partitions:\n"); printf("%-8s %-8s %s\n", "base", "size", "name"); -- 2.30.2