[loader]add mkidb for loader

This commit is contained in:
JianjunJiang 2024-09-30 16:06:11 +08:00
parent e3b96e5dd8
commit 583fe4a9ee
2 changed files with 249 additions and 0 deletions

245
loader.c
View File

@ -1,5 +1,247 @@
#include <loader.h>
struct idblock0_t {
uint32_t signature;
uint8_t reserved0[4];
uint32_t disable_rc4;
uint16_t bootcode1_offset;
uint16_t bootcode2_offset;
uint8_t reserved1[490];
uint16_t flash_data_size;
uint16_t flash_boot_size;
uint16_t crc;
};
struct idblock1_t {
uint16_t sys_reserved_block;
uint16_t disk0_size;
uint16_t disk1_size;
uint16_t disk2_size;
uint16_t disk3_size;
uint32_t chip_tag;
uint32_t machine_id;
uint16_t loader_year;
uint16_t loader_date;
uint16_t loader_ver;
uint8_t reserved0[72];
uint16_t flash_data_offset;
uint16_t flash_data_len;
uint8_t reserved1[384];
uint32_t flash_chip_size;
uint8_t reserved2;
uint8_t access_time;
uint16_t phy_block_size;
uint8_t phy_page_size;
uint8_t ecc_bits;
uint8_t reserved3[8];
uint16_t id_block0;
uint16_t id_block1;
uint16_t id_block2;
uint16_t id_block3;
uint16_t id_block4;
};
struct idblock2_t {
uint16_t chip_info_size;
uint8_t chip_info[16];
uint8_t reserved[473];
uint8_t sz_vc_tag[3];
uint16_t sec0_crc;
uint16_t sec1_crc;
uint32_t boot_code_crc;
uint16_t sec3_custom_data_offset;
uint16_t sec3_custom_data_size;
uint8_t sz_crc_tag[4];
uint16_t sec3_crc;
};
struct idblock3_t {
uint16_t sn_size;
uint8_t sn[60];
uint8_t reserved[382];
uint8_t wifi_size;
uint8_t wifi_addr[6];
uint8_t imei_size;
uint8_t imei[15];
uint8_t uid_size;
uint8_t uid[30];
uint8_t bluetooth_size;
uint8_t bluetooth_addr[6];
uint8_t mac_size;
uint8_t mac_addr[6];
};
static inline uint32_t loader_align_size(uint32_t len)
{
uint32_t t = (len - 1) / 512 + 1;
return ((t - 1) / 4 + 1) * 2048;
}
static void idb_rc4(char * buf, int len)
{
struct rc4_ctx_t ctx;
uint8_t key[16] = { 124, 78, 3, 4, 85, 5, 9, 7, 45, 44, 123, 56, 23, 13, 23, 17 };
rc4_setkey(&ctx, key, sizeof(key));
rc4_crypt(&ctx, (uint8_t *)buf, len);
}
static void rkloader_ctx_mkidb(struct rkloader_ctx_t * ctx)
{
if(ctx->is_newidb)
{
ctx->idblen = 0;
for(int i = 0; i < ctx->nentry; i++)
{
struct rkloader_entry_t * e = ctx->entry[i];
if(e->type == RKLOADER_ENTRY_LOADER)
ctx->idblen += loader_align_size(get_unaligned_le32(&e->data_size));
}
if(ctx->idblen > 0)
{
ctx->idbbuf = calloc(1, ctx->idblen);
if(ctx->idbbuf)
{
int flash_head_index = 0;
uint32_t idblen = 0;
for(flash_head_index = 0; flash_head_index < ctx->nentry; flash_head_index++)
{
struct rkloader_entry_t * e = ctx->entry[flash_head_index];
if(e->type == RKLOADER_ENTRY_LOADER)
{
char str[256];
loader_wide2str(str, (uint8_t *)&e->name[0], sizeof(e->name));
if(strcmp(str, "FlashHead") == 0)
{
uint32_t len = loader_align_size(get_unaligned_le32(&e->data_size));
memset((char *)ctx->idbbuf + idblen, 0, len);
memcpy((char *)ctx->idbbuf + idblen, (char *)ctx->buffer + get_unaligned_le32(&e->data_offset), get_unaligned_le32(&e->data_size));
if(!ctx->is_rc4on)
{
for(int i = 0; i < (len / 512); i++)
idb_rc4((char *)ctx->idbbuf + idblen + 512 * i, 512);
}
idblen += len;
break;
}
}
}
for(int idx = 0; idx < ctx->nentry; idx++)
{
struct rkloader_entry_t * e = ctx->entry[idx];
if((e->type == RKLOADER_ENTRY_LOADER) && (idx != flash_head_index))
{
uint32_t len = loader_align_size(get_unaligned_le32(&e->data_size));
memset((char *)ctx->idbbuf + idblen, 0, len);
memcpy((char *)ctx->idbbuf + idblen, (char *)ctx->buffer + get_unaligned_le32(&e->data_offset), get_unaligned_le32(&e->data_size));
if(!ctx->is_rc4on)
{
for(int i = 0; i < (len / 512); i++)
idb_rc4((char *)ctx->idbbuf + idblen + 512 * i, 512);
}
idblen += len;
}
}
}
}
}
else
{
ctx->idblen = 0;
for(int i = 0; i < ctx->nentry; i++)
{
struct rkloader_entry_t * e = ctx->entry[i];
if(e->type == RKLOADER_ENTRY_LOADER)
{
char str[256];
loader_wide2str(str, (uint8_t *)&e->name[0], sizeof(e->name));
if((strcmp(str, "FlashBoot") == 0) || (strcmp(str, "FlashData") == 0))
ctx->idblen += loader_align_size(get_unaligned_le32(&e->data_size));
}
}
if(ctx->idblen > 0)
{
ctx->idblen += sizeof(struct idblock0_t) + sizeof(struct idblock1_t) + sizeof(struct idblock2_t) + sizeof(struct idblock3_t);
ctx->idbbuf = calloc(1, ctx->idblen);
if(ctx->idbbuf)
{
struct rkloader_entry_t * flash_data = NULL;
struct rkloader_entry_t * flash_boot = NULL;
uint32_t idblen = 0;
uint32_t len;
for(int i = 0; i < ctx->nentry; i++)
{
struct rkloader_entry_t * e = ctx->entry[i];
if(e->type == RKLOADER_ENTRY_LOADER)
{
char str[256];
loader_wide2str(str, (uint8_t *)&e->name[0], sizeof(e->name));
if(strcmp(str, "FlashData") == 0)
flash_data = e;
else if(strcmp(str, "FlashBoot") == 0)
flash_boot = e;
}
}
struct idblock0_t * idb0 = (struct idblock0_t *)((char *)ctx->idbbuf + idblen);
idb0->signature = 0x0ff0aa55;
idb0->disable_rc4 = ctx->is_rc4on ? 0 : 1;
idb0->bootcode1_offset = 4;
idb0->bootcode2_offset = 4;
idb0->flash_data_size = loader_align_size(get_unaligned_le32(&flash_data->data_size)) / 512;
idb0->flash_boot_size = loader_align_size(get_unaligned_le32(&flash_data->data_size)) / 512 + loader_align_size(get_unaligned_le32(&flash_boot->data_size)) / 512;
idblen += 512;
struct idblock1_t * idb1 = (struct idblock1_t *)((char *)ctx->idbbuf + idblen);
idb1->sys_reserved_block = 0xc;
idb1->disk0_size = 0xffff;
idb1->chip_tag = 0x38324b52;
idblen += 512;
struct idblock2_t * idb2 = (struct idblock2_t *)((char *)ctx->idbbuf + idblen);
strcpy((char *)idb2->sz_vc_tag, "VC");
strcpy((char *)idb2->sz_crc_tag, "CRC");
idblen += 512;
struct idblock3_t * idb3 = (struct idblock3_t *)((char *)ctx->idbbuf + idblen);
memset(idb3, 0, sizeof(struct idblock3_t));
idblen += 512;
len = loader_align_size(get_unaligned_le32(&flash_data->data_size));
memset((char *)ctx->idbbuf + idblen, 0, len);
memcpy((char *)ctx->idbbuf + idblen, (char *)ctx->buffer + get_unaligned_le32(&flash_data->data_offset), get_unaligned_le32(&flash_data->data_size));
if(idb0->disable_rc4)
{
for(int i = 0; i < (len / 512); i++)
idb_rc4((char *)ctx->idbbuf + idblen + 512 * i, 512);
}
idblen += len;
len = loader_align_size(get_unaligned_le32(&flash_boot->data_size));
memset((char *)ctx->idbbuf + idblen, 0, len);
memcpy((char *)ctx->idbbuf + idblen, (char *)ctx->buffer + get_unaligned_le32(&flash_boot->data_offset), get_unaligned_le32(&flash_boot->data_size));
if(idb0->disable_rc4)
{
for(int i = 0; i < (len / 512); i++)
idb_rc4((char *)ctx->idbbuf + idblen + 512 * i, 512);
}
idblen += len;
idb2->sec0_crc = crc16_sum(0xffff, (const uint8_t *)idb0, 512);
idb2->sec1_crc = crc16_sum(0xffff, (const uint8_t *)idb1, 512);
idb2->sec3_crc = crc16_sum(0xffff, (const uint8_t *)idb3, 512);
idb_rc4((char *)idb0, sizeof(struct idblock0_t));
idb_rc4((char *)idb2, sizeof(struct idblock2_t));
idb_rc4((char *)idb3, sizeof(struct idblock3_t));
}
}
}
}
char * loader_wide2str(char * str, uint8_t * wide, int len)
{
int i;
@ -90,6 +332,7 @@ struct rkloader_ctx_t * rkloader_ctx_alloc(const char * filename)
return NULL;
}
rkloader_ctx_mkidb(ctx);
return ctx;
}
@ -99,6 +342,8 @@ void rkloader_ctx_free(struct rkloader_ctx_t * ctx)
{
if(ctx->buffer)
free(ctx->buffer);
if(ctx->idbbuf)
free(ctx->idbbuf);
free(ctx);
}
}

View File

@ -6,6 +6,8 @@ extern "C" {
#endif
#include <x.h>
#include <rc4.h>
#include <crc16.h>
#include <crc32.h>
#include <misc.h>
@ -63,6 +65,8 @@ struct rkloader_ctx_t {
struct rkloader_header_t * header;
struct rkloader_entry_t * entry[32];
int nentry;
void * idbbuf;
uint64_t idblen;
};
char * loader_wide2str(char * str, uint8_t * wide, int len);