• MTK Logo 逆向解析之 bin 转 rawx


    既然是逆向,当然是倒着来了,先来看 mkimage 源码

    vendor\mediatek\proprietary\scripts\sign-image_v2\mkimage20\

    文件夹中一共包含3个文件,img_hdr.cfg mkimage mkimage20.c 分别为 cfg 配置文件,可执行二进制文件,可执行文件源码

    一、分析源码

    代码中定义了结构体 IMG_HDR_T 用来存储一些 image 基本信息,我们主要关注 main

    可以看到要想执行 mkimage 必须包含三个参数 Usage: ./mkimage > out_image

    实际上最终执行命令为 ./mkimage merge.raw img_hdr_logo.cfg > logo.bin

    merge.raw 是压缩以后 raw 文件

    img_hdr_logo.cfg 配置文件内容 NAME = logo

    初始化 IMG_HDR_T img_hdr 基本数据

    img_hdr.info.dsize = (unsigned int)(filesize(argv[IMG_PATH_IDX]) & 0xffffffff); 存储 merge.raw 文件数据大小

    get_img_hdr_setting_from_cfg(argv[IMG_CFG_IDX], &img_hdr); 解析 img_hdr_logo.cfg 中数据到结构体 img_hdr 中

    img = readfile(argv[1], img_hdr.info.dsize); 读取 merge.raw 文件数据

    write(STDOUT_FILENO, &img_hdr, sizeof(IMG_HDR_T));
    write(STDOUT_FILENO, img, img_hdr.info.dsize);
    write(STDOUT_FILENO, img_padding, img_padding_size);

    最终将头部信息数据、文件数据、偏移数据依次写入 logo.bin 中

    整体代码比较简单,就是典型 c 代码读取文件写入文件,只是按照特定数据格式

    
    #include <stdint.h>
    #include <unistd.h>
    #include <errno.h>
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    #define IMG_MAGIC         0x58881688
    #define EXT_MAGIC         0x58891689
    
    #define IMG_NAME_SIZE       32
    #define IMG_HDR_SIZE        512
    
    /* image types */
    #define IMG_TYPE_ID_OFFSET           (0)
    #define IMG_TYPE_RESERVED0_OFFSET    (8)
    #define IMG_TYPE_RESERVED1_OFFSET    (16)
    #define IMG_TYPE_GROUP_OFFSET        (24)
    
    #define IMG_TYPE_ID_MASK             (0xffU << IMG_TYPE_ID_OFFSET)
    #define IMG_TYPE_RESERVED0_MASK      (0xffU << IMG_TYPE_RESERVED0_OFFSET)
    #define IMG_TYPE_RESERVED1_MASK      (0xffU << IMG_TYPE_RESERVED1_OFFSET)
    #define IMG_TYPE_GROUP_MASK          (0xffU << IMG_TYPE_GROUP_OFFSET)
    
    #define IMG_TYPE_GROUP_AP            (0x00U << IMG_TYPE_GROUP_OFFSET)
    #define IMG_TYPE_GROUP_MD            (0x01U << IMG_TYPE_GROUP_OFFSET)
    #define IMG_TYPE_GROUP_CERT          (0x02U << IMG_TYPE_GROUP_OFFSET)
    
    /* AP group */
    #define IMG_TYPE_IMG_AP_BIN (0x00 | IMG_TYPE_GROUP_AP)
    
    /* MD group */
    #define IMG_TYPE_IMG_MD_LTE (0x00 | IMG_TYPE_GROUP_MD)
    #define IMG_TYPE_IMG_MD_C2K (0x01 | IMG_TYPE_GROUP_MD)
    
    /* CERT group */
    #define IMG_TYPE_CERT1      (0x00 | IMG_TYPE_GROUP_CERT)
    #define IMG_TYPE_CERT1_MD   (0x01 | IMG_TYPE_GROUP_CERT)
    #define IMG_TYPE_CERT2      (0x02 | IMG_TYPE_GROUP_CERT)
    
    #define HDR_VERSION         1
    
    #define IMG_PATH_IDX        1
    #define IMG_CFG_IDX         2
    
    //#define DEBUG_MODE
    
    typedef union {
    	struct {
    		unsigned int magic;     /* always IMG_MAGIC */
    		unsigned int
    		dsize;     /* image size, image header and padding are not included */
    		char name[IMG_NAME_SIZE];
    		unsigned int maddr;     /* image load address in RAM */
    		unsigned int mode;      /* maddr is counted from the beginning or end of RAM */
    		/* extension */
    		unsigned int ext_magic;    /* always EXT_MAGIC */
    		unsigned int
    		hdr_size;     /* header size is 512 bytes currently, but may extend in the future */
    		unsigned int hdr_version;  /* see HDR_VERSION */
    		unsigned int
    		img_type;     /* please refer to #define beginning with IMG_TYPE_ */
    		unsigned int
    		img_list_end; /* end of image list? 0: this image is followed by another image 1: end */
    		unsigned int
    		align_size;   /* image size alignment setting in bytes, 16 by default for AES encryption */
    		unsigned int
    		dsize_extend; /* high word of image size for 64 bit address support */
    		unsigned int
    		maddr_extend; /* high word of image load address in RAM for 64 bit address support */
    	} info;
    	unsigned char data[IMG_HDR_SIZE];
    } IMG_HDR_T;
    
    unsigned int filesize(char *name)
    {
    	struct stat statbuf;
    
    	if (stat(name, &statbuf) != 0) {
    		fprintf(stderr, "Cannot open file %s\n", name);
    		exit(0);
    	}
    	return statbuf.st_size;
    }
    
    char *readfile(char *name, unsigned int size)
    {
    	FILE *f;
    	char *buf = NULL;
    
    	f = fopen(name, "rb");
    	if (f == NULL) {
    		fprintf(stderr, "Cannot open file %s\n", name);
    		goto _end;
    	}
    
    	buf = (char *)malloc(size);
    	if (!buf) {
    		fprintf(stderr, "error while malloc(%d)\n", size);
    		goto _error;
    	}
    
    	if (fread(buf, 1, size, f) != size) {
    		fprintf(stderr, "Error while reading file %s\n", name);
    		free(buf);
    		buf = NULL;
    		goto _error;
    	}
    
    _error:
    	fclose(f);
    _end:
    	return buf;
    }
    
    char xtod(char c)
    {
    	if (c >= '0' && c <= '9') return c - '0';
    	if (c >= 'A' && c <= 'F') return c - 'A' + 10;
    	if (c >= 'a' && c <= 'f') return c - 'a' + 10;
    	return 0;
    }
    
    unsigned long long hex2dec(char *hex, int l)
    {
    	if (*hex == 0)
    		return l;
    	return hex2dec(hex + 1, l * 16 + xtod(*hex));
    }
    
    unsigned long long xstr2int(char *hex)
    {
    	return hex2dec(hex, 0);
    }
    
    int remove_chr_from_string(char *string, char c)
    {
    	int final_str_len = 0;
    	final_str_len = strlen(string);
    	int i = 0;
    
    	while (i < final_str_len) {
    		if (string[i] == c) {
    			memmove(&string[i], &string[i + 1], final_str_len - i - 1);
    			final_str_len--;
    			string[final_str_len] = 0;
    		}
    		i++;
    	}
    
    	return 0;
    }
    
    int get_img_hdr_setting_from_cfg(const char *cfg_path, IMG_HDR_T *img_hdr)
    {
    #define MAX_LINE_LENGTH  (80)
    	int ret = 0;
    	FILE *fp = NULL;
    	char line[MAX_LINE_LENGTH] = {0};
    
    	fp = fopen(cfg_path, "r");
    	if (NULL == fp) {
    		fprintf(stderr, "Cannot open file %s\n", cfg_path);
    		exit(0);
    	}
    
    	while (fgets(line, MAX_LINE_LENGTH, fp) != NULL) {
    		int i = 0;
    		char *obj_name = NULL;
    		char *obj_value_str = NULL;
    		unsigned int obj_value = 0;
    		ret = remove_chr_from_string(line, ' ');
    		ret = remove_chr_from_string(line, '\n');
    		obj_name  = strtok(line, "=");
    		if (NULL == obj_name)
    			continue;
    		obj_value_str = strtok(NULL, "=");
    		if (NULL == obj_value_str || !strcmp(obj_name, "NAME"))
    			obj_value = 0;
    		else if (obj_value_str[0] == '0' && obj_value_str[1] == 'x')
    			obj_value = xstr2int(obj_value_str);
    		else
    			obj_value = atoi(obj_value_str);
    
    #ifdef DEBUG_MODE
    		fprintf(stderr, "name = %s, value_str = %s, value = %d\n", obj_name,
    			obj_value_str, obj_value);
    #endif
    
    		if (!strcmp(obj_name, "LOAD_ADDR"))
    			img_hdr->info.maddr = obj_value;
    		else if (!strcmp(obj_name, "LOAD_ADDR_H"))
    			img_hdr->info.maddr_extend = obj_value;
    		else if (!strcmp(obj_name, "LOAD_MODE"))
    			img_hdr->info.mode = obj_value;
    		else if (!strcmp(obj_name, "NAME"))
    			strncpy(img_hdr->info.name, obj_value_str, IMG_NAME_SIZE);
    		else if (!strcmp(obj_name, "IMG_TYPE"))
    			img_hdr->info.img_type = obj_value;
    		else if (!strcmp(obj_name, "IMG_LIST_END"))
    			img_hdr->info.img_list_end = obj_value;
    		else if (!strcmp(obj_name, "ALIGN_SIZE"))
    			img_hdr->info.align_size = obj_value;
    		else {
    #ifdef DEBUG_MODE
    			fprintf(stderr, "==> unknown object\n");
    #endif
    		}
    	}
    
    	fclose(fp);
    _end:
    	return ret;
    }
    
    int main(int argc, char *argv[])
    {
    	IMG_HDR_T img_hdr;
    	char *img = NULL;
    	char *img_padding = NULL;
    	uint32_t img_padding_size = 0;
    	int ret = 0;
    
    	if (argc != 3) {
    		fprintf(stderr, "Usage: ./mkimage   > out_image\n");
    		return 0;
    	}
    
    	memset(&img_hdr, 0xff, sizeof(IMG_HDR_T));
    
    	/* legacy fields */
    	img_hdr.info.magic = IMG_MAGIC;
    	img_hdr.info.dsize = (unsigned int)(filesize(argv[IMG_PATH_IDX]) & 0xffffffff);
    	memset(img_hdr.info.name, 0x0, sizeof(img_hdr.info.name));
    	img_hdr.info.maddr = 0xffffffff;
    	img_hdr.info.mode = 0xffffffff;
    
    	/* extension fields */
    	img_hdr.info.ext_magic = EXT_MAGIC;
    	img_hdr.info.hdr_size = IMG_HDR_SIZE;
    	img_hdr.info.hdr_version = HDR_VERSION;
    	img_hdr.info.img_type = IMG_TYPE_IMG_AP_BIN;
    	img_hdr.info.img_list_end = 0;
    	img_hdr.info.align_size = 16;
    	img_hdr.info.dsize_extend = 0;
    	img_hdr.info.maddr_extend = 0;
    
    	/* if external config exists, use it to override */
    	/* add code here */
    	if (argc > IMG_CFG_IDX)
    		ret = get_img_hdr_setting_from_cfg(argv[IMG_CFG_IDX], &img_hdr);
    	if (ret)
    		goto _error;
    
    #ifdef DEBUG_MODE
    	{
    		int i = 0;
    		for (i = 0; i < 512; i++) {
    			fprintf(stderr, "%02x ", img_hdr.data[i]);
    			if ((i + 1) % 16 == 0)
    				fprintf(stderr, "\n");
    		}
    	}
    #endif
    
    	/* current implementation will encounter malloc fail issue if image size is extremely large */
    	img = readfile(argv[1], img_hdr.info.dsize);
    	img_padding_size = ((img_hdr.info.dsize + (img_hdr.info.align_size - 1)) /
    			    img_hdr.info.align_size) * img_hdr.info.align_size - img_hdr.info.dsize;
    #ifdef DEBUG_MODE
    	fprintf(stderr, "img_padding_size = 0x%x\n", img_padding_size);
    #endif
    	img_padding = malloc(img_padding_size);
    	if (img_padding)
    		memset(img_padding, 0x0, img_padding_size);
    
    	/* for linux version mkimage, we only support this method */
    	write(STDOUT_FILENO, &img_hdr, sizeof(IMG_HDR_T));
    	write(STDOUT_FILENO, img, img_hdr.info.dsize);
    	write(STDOUT_FILENO, img_padding, img_padding_size);
    
    	return 0;
    _error:
    	free(img);
    	free(img_padding);
    	exit(1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291

    二、改造源码

    可以看到上面的源码中并不包含解包的逻辑,这就需要我们自己来添加了。

    既然知道了打包的数据格式,结构体 img_hdr + img 数据 + 偏移数据

    那么反过来也不是什么难事,我们需要的仅仅只是第二部分 img 数据

    那就需要一个读取起始位置和结束位置,上面有个关键信息 img_hdr.info.dsize 就是要读取的数据长度

    结构体 img_hdr 数据长度末尾就是要 img 数据起始位置

    下面代码进行了优化,仅仅只为了打包和解包 logo.bin 所以将原来 cfg 文件读取删掉了,直接默认赋值 logo

    增加参数判断,-l 打包 -d 解包

    #include <stdint.h>
    #include <unistd.h>
    #include <errno.h>
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    #define IMG_MAGIC         0x58881688
    #define EXT_MAGIC         0x58891689
    
    #define IMG_NAME_SIZE       32
    #define IMG_HDR_SIZE        512
    
    /* image types */
    #define IMG_TYPE_ID_OFFSET           (0)
    #define IMG_TYPE_RESERVED0_OFFSET    (8)
    #define IMG_TYPE_RESERVED1_OFFSET    (16)
    #define IMG_TYPE_GROUP_OFFSET        (24)
    
    #define IMG_TYPE_ID_MASK             (0xffU << IMG_TYPE_ID_OFFSET)
    #define IMG_TYPE_RESERVED0_MASK      (0xffU << IMG_TYPE_RESERVED0_OFFSET)
    #define IMG_TYPE_RESERVED1_MASK      (0xffU << IMG_TYPE_RESERVED1_OFFSET)
    #define IMG_TYPE_GROUP_MASK          (0xffU << IMG_TYPE_GROUP_OFFSET)
    
    #define IMG_TYPE_GROUP_AP            (0x00U << IMG_TYPE_GROUP_OFFSET)
    #define IMG_TYPE_GROUP_MD            (0x01U << IMG_TYPE_GROUP_OFFSET)
    #define IMG_TYPE_GROUP_CERT          (0x02U << IMG_TYPE_GROUP_OFFSET)
    
    /* AP group */
    #define IMG_TYPE_IMG_AP_BIN (0x00 | IMG_TYPE_GROUP_AP)
    
    /* MD group */
    #define IMG_TYPE_IMG_MD_LTE (0x00 | IMG_TYPE_GROUP_MD)
    #define IMG_TYPE_IMG_MD_C2K (0x01 | IMG_TYPE_GROUP_MD)
    
    /* CERT group */
    #define IMG_TYPE_CERT1      (0x00 | IMG_TYPE_GROUP_CERT)
    #define IMG_TYPE_CERT1_MD   (0x01 | IMG_TYPE_GROUP_CERT)
    #define IMG_TYPE_CERT2      (0x02 | IMG_TYPE_GROUP_CERT)
    
    #define HDR_VERSION         1
    
    #define IMG_PATH_IDX        2
    #define IMG_CFG_IDX         2
    
    #define DEBUG_MODE
    
    typedef union {
    	struct {
    		unsigned int magic;     /* always IMG_MAGIC */
    		unsigned int
    		dsize;     /* image size, image header and padding are not included */
    		char name[IMG_NAME_SIZE];
    		unsigned int maddr;     /* image load address in RAM */
    		unsigned int mode;      /* maddr is counted from the beginning or end of RAM */
    		/* extension */
    		unsigned int ext_magic;    /* always EXT_MAGIC */
    		unsigned int
    		hdr_size;     /* header size is 512 bytes currently, but may extend in the future */
    		unsigned int hdr_version;  /* see HDR_VERSION */
    		unsigned int
    		img_type;     /* please refer to #define beginning with IMG_TYPE_ */
    		unsigned int
    		img_list_end; /* end of image list? 0: this image is followed by another image 1: end */
    		unsigned int
    		align_size;   /* image size alignment setting in bytes, 16 by default for AES encryption */
    		unsigned int
    		dsize_extend; /* high word of image size for 64 bit address support */
    		unsigned int
    		maddr_extend; /* high word of image load address in RAM for 64 bit address support */
    	} info;
    	unsigned char data[IMG_HDR_SIZE];
    } IMG_HDR_T;
    
    unsigned int filesize(char *name)
    {
    	struct stat statbuf;
    
    	if (stat(name, &statbuf) != 0) {
    		fprintf(stderr, "Cannot open file %s\n", name);
    		exit(0);
    	}
    	return statbuf.st_size;
    }
    
    char *readfile(char *name, unsigned int size)
    {
    	FILE *f;
    	char *buf = NULL;
    
    	f = fopen(name, "rb");
    	if (f == NULL) {
    		fprintf(stderr, "Cannot open file %s\n", name);
    		goto _end;
    	}
    
    	buf = (char *)malloc(size);
    	if (!buf) {
    		fprintf(stderr, "error while malloc(%d)\n", size);
    		goto _error;
    	}
    
    	//从文件 f 中读取占用 size*1 个字节的数据,存储到 buf
    	if (fread(buf, 1, size, f) != size) {
    		fprintf(stderr, "Error while reading file %s\n", name);
    		free(buf);
    		buf = NULL;
    		goto _error;
    	}
    
    _error:
    	fclose(f);
    _end:
    	return buf;
    }
    
    char xtod(char c)
    {
    	if (c >= '0' && c <= '9') return c - '0';
    	if (c >= 'A' && c <= 'F') return c - 'A' + 10;
    	if (c >= 'a' && c <= 'f') return c - 'a' + 10;
    	return 0;
    }
    
    unsigned long long hex2dec(char *hex, int l)
    {
    	if (*hex == 0)
    		return l;
    	return hex2dec(hex + 1, l * 16 + xtod(*hex));
    }
    
    unsigned long long xstr2int(char *hex)
    {
    	return hex2dec(hex, 0);
    }
    
    int remove_chr_from_string(char *string, char c)
    {
    	int final_str_len = 0;
    	final_str_len = strlen(string);
    	int i = 0;
    
    	while (i < final_str_len) {
    		if (string[i] == c) {
    			memmove(&string[i], &string[i + 1], final_str_len - i - 1);
    			final_str_len--;
    			string[final_str_len] = 0;
    		}
    		i++;
    	}
    
    	return 0;
    }
    
    int get_img_hdr_setting_from_cfg(const char *cfg_path, IMG_HDR_T *img_hdr)
    {
    #define MAX_LINE_LENGTH  (80)
    	int ret = 0;
    	FILE *fp = NULL;
    	char line[MAX_LINE_LENGTH] = {0};
    
    	fp = fopen(cfg_path, "r");
    	if (NULL == fp) {
    		fprintf(stderr, "Cannot open file %s\n", cfg_path);
    		exit(0);
    	}
    
    	while (fgets(line, MAX_LINE_LENGTH, fp) != NULL) {
    		int i = 0;
    		char *obj_name = NULL;
    		char *obj_value_str = NULL;
    		unsigned int obj_value = 0;
    		ret = remove_chr_from_string(line, ' ');
    		ret = remove_chr_from_string(line, '\n');
    		obj_name  = strtok(line, "=");
    		if (NULL == obj_name)
    			continue;
    		obj_value_str = strtok(NULL, "=");
    		if (NULL == obj_value_str || !strcmp(obj_name, "NAME"))
    			obj_value = 0;
    		else if (obj_value_str[0] == '0' && obj_value_str[1] == 'x')
    			obj_value = xstr2int(obj_value_str);
    		else
    			obj_value = atoi(obj_value_str);
    
    #ifdef DEBUG_MODE
    		fprintf(stderr, "name = %s, value_str = %s, value = %d\n", obj_name,
    			obj_value_str, obj_value);
    #endif
    
    		if (!strcmp(obj_name, "LOAD_ADDR"))
    			img_hdr->info.maddr = obj_value;
    		else if (!strcmp(obj_name, "LOAD_ADDR_H"))
    			img_hdr->info.maddr_extend = obj_value;
    		else if (!strcmp(obj_name, "LOAD_MODE"))
    			img_hdr->info.mode = obj_value;
    		else if (!strcmp(obj_name, "NAME"))
    			strncpy(img_hdr->info.name, obj_value_str, IMG_NAME_SIZE);
    		else if (!strcmp(obj_name, "IMG_TYPE"))
    			img_hdr->info.img_type = obj_value;
    		else if (!strcmp(obj_name, "IMG_LIST_END"))
    			img_hdr->info.img_list_end = obj_value;
    		else if (!strcmp(obj_name, "ALIGN_SIZE"))
    			img_hdr->info.align_size = obj_value;
    		else {
    #ifdef DEBUG_MODE
    			fprintf(stderr, "==> unknown object\n");
    #endif
    		}
    	}
    
    	fclose(fp);
    _end:
    	return ret;
    }
    
    int main(int argc, char *argv[])
    {
    	IMG_HDR_T img_hdr;
    	char *img = NULL;
    	char *img_padding = NULL;
    	uint32_t img_padding_size = 0;
    	int ret = 0;
    
    	if (argc < 2) {
    		fprintf(stderr, "pack:   ./mkimage20 -l logo.raw > logo.bin\n");
    		fprintf(stderr, "unpack: ./mkimage20 -d logo.bin logo.raw \n");
    		return 0;
    	}
    
    	// pack image
    	if(!strcmp(argv[1], "-l"))
    	{
    		//用长度为sizeof(IMG_HDR_T)的初始值0xff 填充 img_hdr 内存
    		memset(&img_hdr, 0xff, sizeof(IMG_HDR_T));
    
    		/* legacy fields */
    		img_hdr.info.magic = IMG_MAGIC;//0x58881688
    		//计算 logo.raw 文件大小
    		img_hdr.info.dsize = (unsigned int)(filesize(argv[IMG_PATH_IDX]) & 0xffffffff);
    		//用长度为sizeof(name)的初始值 0x0 填充 name 内存
    		memset(img_hdr.info.name, 0x0, sizeof(img_hdr.info.name));
    		img_hdr.info.maddr = 0xffffffff;
    		img_hdr.info.mode = 0xffffffff;
    
    		/* extension fields */
    		img_hdr.info.ext_magic = EXT_MAGIC;//0x58891689
    		img_hdr.info.hdr_size = IMG_HDR_SIZE;//512
    		img_hdr.info.hdr_version = HDR_VERSION;//1
    		img_hdr.info.img_type = IMG_TYPE_IMG_AP_BIN;//(0x00 | (0x00U << 24))
    		img_hdr.info.img_list_end = 0;
    		img_hdr.info.align_size = 16;
    		img_hdr.info.dsize_extend = 0;
    		img_hdr.info.maddr_extend = 0;
    
    		/* if external config exists, use it to override */
    		/* add code here */
    		//重新从 cfg 文件中读取 name 值, NAME = logo   img_hdr.info.name=logo
    		strncpy(img_hdr.info.name, "logo", IMG_NAME_SIZE);
    		/*if (argc > IMG_CFG_IDX)
    			ret = get_img_hdr_setting_from_cfg(argv[IMG_CFG_IDX], &img_hdr);
    		if (ret)
    			goto _error;*/
    
    		#ifdef DEBUG_MODE
    			{
    				int i = 0;
    				for (i = 0; i < 512; i++) {
    					fprintf(stderr, "%02x ", img_hdr.data[i]);
    					if ((i + 1) % 16 == 0)
    						fprintf(stderr, "\n");
    				}
    			}
    		#endif
    
    		/* current implementation will encounter malloc fail issue if image size is extremely large */
    		//读取 logo.raw 文件数据
    		img = readfile(argv[IMG_PATH_IDX], img_hdr.info.dsize);
    		//计算偏移数据
    		img_padding_size = ((img_hdr.info.dsize + (img_hdr.info.align_size - 1)) /
    				    img_hdr.info.align_size) * img_hdr.info.align_size - img_hdr.info.dsize;
    	#ifdef DEBUG_MODE
    		fprintf(stderr, "img_padding_size = 0x%x\n", img_padding_size);
    		fprintf(stderr, "info.dsize = 0x%x\n", img_hdr.info.dsize);
    	#endif
    		img_padding = malloc(img_padding_size);
    		if (img_padding)
    			memset(img_padding, 0x0, img_padding_size);
    
    		/* for linux version mkimage, we only support this method */
    		write(STDOUT_FILENO, &img_hdr, sizeof(IMG_HDR_T));
    		write(STDOUT_FILENO, img, img_hdr.info.dsize);
    		write(STDOUT_FILENO, img_padding, img_padding_size);
    
    		return 0;
    	_error:
    		free(img);
    		free(img_padding);
    		exit(1);
    	}
    	else//unpack logo.bin
    	{
    	    FILE *input = fopen(argv[2], "rb");
    	    if (!input) {
    	        perror("Error opening input file");
    	        return 1;
    	    }
    
    	    FILE *output = fopen(argv[3], "wb");
    	    if (!output) {
    	        perror("Error opening output file");
    	        fclose(input);
    	        return 1;
    	    }
    
    	    //读取结构体数据,获取真正raw部分数据长度
    	    // IMG_HDR_T img_hdr;
    	    memset(&img_hdr, 0xff, sizeof(IMG_HDR_T));
    	    int count = fread(&img_hdr, 1, sizeof(IMG_HDR_T), input);
    	#ifdef DEBUG_MODE
    	    fprintf(stderr, "count: %d \n", count);
    	    fprintf(stderr, "align_size: %d \n", img_hdr.info.align_size);
    	    fprintf(stderr, "info.dsize: 0x%x\n", img_hdr.info.dsize);
    	    fprintf(stderr, "info.dsize: %d \n", img_hdr.info.dsize);
    	#endif
    	    // fclose(input);
    
    	    // 跳过头部
    	    if (fseek(input, IMG_HDR_SIZE, SEEK_SET) != 0) {
    	        perror("Error seeking in input file");
    	        fclose(input);
    	        fclose(output);
    	        return 1;
    	    }
    
    	    // 从input复制数据到output
    	    uint8_t buffer[img_hdr.info.dsize];//4096
    	    size_t bytesRead;
    	    while ((bytesRead = fread(buffer, 1, sizeof(buffer), input)) > 0) {
    	    	#ifdef DEBUG_MODE
    	        	fprintf(stderr, "bytesRead: %d \n", bytesRead);
    	        #endif
    	        if (bytesRead == img_hdr.info.dsize)
    	        {
    	            fwrite(buffer, 1, bytesRead, output);
    	        }else{//跳过尾部偏移数据
    	            break;
    	        }
    	    }
    
    	    fclose(input);
    	    fclose(output);
    	    return 0;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358

    三、编译指令

    gcc -o mkimage20 mkimage20.c -lz

    mkimage20下载

    四、解包 bin 文件

    使用方法

    pack:
    ./mkimage20 -l logo.raw > logo.bin

    unpack:
    ./mkimage20 -d logo.bin logo.raw

  • 相关阅读:
    Python 实现单例模式的五种写法
    刷题笔记day01-数组
    【win32_000】视频截图
    股东入股可用的出资形式主要有哪些
    【SpringMVC】集成Web、MVC执行流程、数据响应、数据交互
    vuedraggable插件在弹框中使用时,遇到了哪些问题
    Oracle SQL Developer 中查看表的数据和字段属性、录入数据
    26 mysql 索引的存储更新删除
    一文掌握根轨迹法
    使用SSM为学校医务室开发一套管理系统
  • 原文地址:https://blog.csdn.net/u012932409/article/details/133316331