Bac d'analyse inversée du logo MTK vers rawx

Puisqu’il s’agit d’ingénierie inverse, bien sûr, cela se fait à l’envers. Regardons d’abord le code source de mkimage.

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

Le dossier contient un total de 3 fichiers, img_hdr.cfg mkimage mkimage20.c sont le fichier de configuration cfg, le fichier binaire exécutable et le code source du fichier exécutable.

1. Analysez le code source

La structure IMG_HDR_T est définie dans le code pour stocker certaines informations de base sur l'image. Nous nous concentrons principalement sur les principales

Vous pouvez voir que pour exécuter mkimage, vous devez inclure trois paramètres Utilisation : ./mkimage <img_path> <cfg_path> > out_image

En fait, la commande d'exécution finale est ./mkimage merge.raw img_hdr_logo.cfg > logo.bin

merge.raw est le fichier brut après compression

img_hdr_logo.cfg Contenu du fichier de configuration NOM = logo

Initialiser les données de base IMG_HDR_T img_hdr

img_hdr.info.dsize = (unsigned int)(filesize(argv[IMG_PATH_IDX]) & 0xffffffff); stocke la taille des données du fichier merge.raw

get_img_hdr_setting_from_cfg(argv[IMG_CFG_IDX], &img_hdr); Analyser les données dans img_hdr_logo.cfg dans la structure img_hdr

img = readfile(argv[1], img_hdr.info.dsize); Lire les données du fichier merge.raw

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

Enfin, les données d'informations d'en-tête, les données de fichier et les données de décalage sont écrites dans logo.bin dans l'ordre.

Le code global est relativement simple : il s'agit d'un code C typique qui lit et écrit des fichiers, mais uniquement selon un format de données spécifique.


#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 <img_path> <cfg_path> > 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);
}

2. Transformez le code source

Vous pouvez voir que le code source ci-dessus ne contient pas de logique de déballage, ce qui nous oblige à l'ajouter nous-mêmes.

Maintenant que nous connaissons le format des données compressées, la structure img_hdr + img data + offset data

Alors l’inverse n’est pas difficile, tout ce dont nous avons besoin c’est de la deuxième partie des données img

Ensuite, vous avez besoin d'une position de départ et d'une position de fin de lecture. Il contient des informations clés img_hdr.info.dsize, qui sont la longueur des données à lire.

La fin de la longueur des données de la structure img_hdr est la position de départ des données img.

Le code suivant a été optimisé, uniquement pour l'empaquetage et le déballage de logo.bin, de sorte que le fichier cfg d'origine est lu et supprimé, et le logo est directement attribué par défaut.

Ajouter un jugement de paramètre, -l pack -d unpack

#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;
	}
}

3. Instructions de compilation

gcc -o mkimage20 mkimage20.c -lz

mkimage20 télécharger

4. Décompressez le fichier bin

Instructions

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

décompresser :
./mkimage20 -d logo.bin logo.raw

Guess you like

Origin blog.csdn.net/u012932409/article/details/133316331