nyx: boost dump pkg1/2 functionality

The tool can now dump main and safe pkg1/2.
Additionally, it can identify if FS is exfat or not and set the proper filename.
(FAT32 only FS will still use FS.kip1)
Lastly, this will also dump and decrypt the main/safe BCT structures.
This commit is contained in:
CTCaer
2025-08-08 15:34:17 +03:00
parent 885cc195c0
commit b33ab240f2
2 changed files with 322 additions and 240 deletions

View File

@@ -28,6 +28,7 @@
#include "../hos/pkg1.h" #include "../hos/pkg1.h"
#include "../hos/pkg2.h" #include "../hos/pkg2.h"
#include "../hos/hos.h" #include "../hos/hos.h"
#include <libs/compr/blz.h>
#include <libs/fatfs/ff.h> #include <libs/fatfs/ff.h>
extern volatile boot_cfg_t *b_cfg; extern volatile boot_cfg_t *b_cfg;
@@ -1131,7 +1132,16 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
lv_obj_set_style(lb_desc, &monospace_text); lv_obj_set_style(lb_desc, &monospace_text);
lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK); lv_label_set_long_mode(lb_desc, LV_LABEL_LONG_BREAK);
lv_label_set_recolor(lb_desc, true); lv_label_set_recolor(lb_desc, true);
lv_obj_set_width(lb_desc, lv_obj_get_width(desc)); lv_obj_set_width(lb_desc, lv_obj_get_width(desc) / 2);
lv_obj_t *lb_desc2 = lv_label_create(desc, NULL);
lv_obj_set_style(lb_desc2, &monospace_text);
lv_label_set_long_mode(lb_desc2, LV_LABEL_LONG_BREAK);
lv_label_set_recolor(lb_desc2, true);
lv_obj_set_width(lb_desc2, lv_obj_get_width(desc) / 2);
lv_label_set_text(lb_desc2, " ");
lv_obj_align(lb_desc2, lb_desc, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
if (!sd_mount()) if (!sd_mount())
{ {
@@ -1147,7 +1157,7 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
u8 *warmboot = (u8 *)zalloc(SZ_256K); u8 *warmboot = (u8 *)zalloc(SZ_256K);
u8 *secmon = (u8 *)zalloc(SZ_256K); u8 *secmon = (u8 *)zalloc(SZ_256K);
u8 *loader = (u8 *)zalloc(SZ_256K); u8 *loader = (u8 *)zalloc(SZ_256K);
u8 *pkg2 = NULL; u8 *pkg2 = (u8 *)zalloc(SZ_8M);
char *txt_buf = (char *)malloc(SZ_16K); char *txt_buf = (char *)malloc(SZ_16K);
@@ -1158,43 +1168,80 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
goto out_free; goto out_free;
} }
emmc_set_partition(EMMC_BOOT0); char *bct_paths[2] = {
"/pkg/main",
"/pkg/safe"
};
char *pkg1_paths[2] = {
"/pkg/main/pkg1",
"/pkg/safe/pkg1"
};
char *pkg2_partitions[2] = {
"BCPKG2-1-Normal-Main",
"BCPKG2-3-SafeMode-Main"
};
char *pkg2_paths[2] = {
"/pkg/main/pkg2",
"/pkg/safe/pkg2"
};
char *pkg2ini_paths[2] = {
"/pkg/main/pkg2/ini",
"/pkg/safe/pkg2/ini"
};
// Create main directories.
emmcsn_path_impl(path, "/pkg", "", &emmc_storage);
emmcsn_path_impl(path, "/pkg/main", "", &emmc_storage);
emmcsn_path_impl(path, "/pkg/safe", "", &emmc_storage);
// Parse eMMC GPT.
emmc_set_partition(EMMC_GPP);
LIST_INIT(gpt);
emmc_gpt_parse(&gpt);
lv_obj_t *lb_log = lb_desc;
for (u32 idx = 0; idx < 2; idx++)
{
if (idx)
lb_log = lb_desc2;
// Read package1. // Read package1.
static const u32 BOOTLOADER_SIZE = SZ_256K;
static const u32 BOOTLOADER_MAIN_OFFSET = 0x100000;
static const u32 HOS_EKS_OFFSET = 0x180000;
char *build_date = malloc(32); char *build_date = malloc(32);
u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header. u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header.
sdmmc_storage_read(&emmc_storage, BOOTLOADER_MAIN_OFFSET / EMMC_BLOCKSIZE, BOOTLOADER_SIZE / EMMC_BLOCKSIZE, pkg1); emmc_set_partition(!idx ? EMMC_BOOT0 : EMMC_BOOT1);
sdmmc_storage_read(&emmc_storage,
!idx ? PKG1_BOOTLOADER_MAIN_OFFSET : PKG1_BOOTLOADER_SAFE_OFFSET, PKG1_BOOTLOADER_SIZE / EMMC_BLOCKSIZE, pkg1);
const pkg1_id_t *pkg1_id = pkg1_identify(pkg1 + pk1_offset, build_date); const pkg1_id_t *pkg1_id = pkg1_identify(pkg1 + pk1_offset, build_date);
s_printf(txt_buf, "#00DDFF Found pkg1 ('%s')#\n\n", build_date); s_printf(txt_buf, "#00DDFF Found %s pkg1 ('%s')#\n\n", !idx ? "Main" : "Safe", build_date);
free(build_date); lv_label_set_text(lb_log, txt_buf);
lv_label_set_text(lb_desc, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
free(build_date);
// Dump package1 in its encrypted state. // Dump package1 in its encrypted state.
emmcsn_path_impl(path, "/pkg1", "pkg1_enc.bin", &emmc_storage); emmcsn_path_impl(path, pkg1_paths[idx], "pkg1_enc.bin", &emmc_storage);
bool res = sd_save_to_file(pkg1, BOOTLOADER_SIZE, path); bool res = sd_save_to_file(pkg1, PKG1_BOOTLOADER_SIZE, path);
// Exit if unknown. // Exit if unknown.
if (!pkg1_id) if (!pkg1_id)
{ {
strcat(txt_buf, "#FFDD00 Unknown pkg1 version!#"); strcat(txt_buf, "#FFDD00 Unknown pkg1 version!#");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
if (!res) if (!res)
{ {
strcat(txt_buf, "\nEncrypted pkg1 dumped to pkg1_enc.bin"); strcat(txt_buf, "\nEncrypted pkg1 extracted to pkg1_enc.bin");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
} }
goto out_free; goto out;
} }
mkey = pkg1_id->mkey; mkey = pkg1_id->mkey;
@@ -1208,13 +1255,14 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
const u32 eks_size = sizeof(pkg1_eks_t); const u32 eks_size = sizeof(pkg1_eks_t);
pkg1_eks_t *eks = (pkg1_eks_t *)malloc(eks_size); pkg1_eks_t *eks = (pkg1_eks_t *)malloc(eks_size);
emmc_set_partition(EMMC_BOOT0); emmc_set_partition(EMMC_BOOT0);
sdmmc_storage_read(&emmc_storage, HOS_EKS_OFFSET + (mkey * eks_size) / EMMC_BLOCKSIZE, sdmmc_storage_read(&emmc_storage, PKG1_HOS_EKS_OFFSET + (mkey * eks_size) / EMMC_BLOCKSIZE,
eks_size / EMMC_BLOCKSIZE, eks); eks_size / EMMC_BLOCKSIZE, eks);
// Generate keys. // Generate keys.
hos_keygen(eks, mkey, &tsec_ctxt); hos_keygen(eks, mkey, &tsec_ctxt);
free(eks); free(eks);
// Decrypt.
if (h_cfg.t210b01 || mkey <= HOS_MKEY_VER_600) if (h_cfg.t210b01 || mkey <= HOS_MKEY_VER_600)
{ {
if (!pkg1_decrypt(pkg1_id, pkg1)) if (!pkg1_decrypt(pkg1_id, pkg1))
@@ -1222,11 +1270,29 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
strcat(txt_buf, "#FFDD00 Pkg1 decryption failed!#\n"); strcat(txt_buf, "#FFDD00 Pkg1 decryption failed!#\n");
if (h_cfg.t210b01) if (h_cfg.t210b01)
strcat(txt_buf, "#FFDD00 Is BEK missing?#\n"); strcat(txt_buf, "#FFDD00 Is BEK missing?#\n");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
goto out_free; goto out;
} }
} }
// Dump the BCTs from blocks 2/3 (backup) which are normally valid.
static const u32 BCT_SIZE = 0x2800;
static const u32 BLK_SIZE = SZ_16K / EMMC_BLOCKSIZE;
u8 *bct = (u8 *)zalloc(BCT_SIZE);
sdmmc_storage_read(&emmc_storage, BLK_SIZE * 2 + BLK_SIZE * idx, BCT_SIZE / EMMC_BLOCKSIZE, bct);
emmcsn_path_impl(path, bct_paths[idx], "bct.bin", &emmc_storage);
if (sd_save_to_file(bct, 0x2800, path))
goto out;
if (h_cfg.t210b01)
{
se_aes_iv_clear(13);
se_aes_crypt_cbc(13, DECRYPT, bct + 0x480, BCT_SIZE - 0x480, bct + 0x480, BCT_SIZE - 0x480);
emmcsn_path_impl(path, bct_paths[idx], "bct_decr.bin", &emmc_storage);
if (sd_save_to_file(bct, 0x2800, path))
goto out;
}
// Dump package1.1 contents.
if (h_cfg.t210b01 || mkey <= HOS_MKEY_VER_620) if (h_cfg.t210b01 || mkey <= HOS_MKEY_VER_620)
{ {
pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1 + pk1_offset); pkg1_unpack(warmboot, secmon, loader, pkg1_id, pkg1 + pk1_offset);
@@ -1235,43 +1301,41 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Display info. // Display info.
s_printf(txt_buf + strlen(txt_buf), s_printf(txt_buf + strlen(txt_buf),
"#C7EA46 NX Bootloader size: #0x%05X\n" "#C7EA46 NX Bootloader size: #0x%05X\n"
"#C7EA46 Secure monitor addr: #0x%05X\n"
"#C7EA46 Secure monitor size: #0x%05X\n" "#C7EA46 Secure monitor size: #0x%05X\n"
"#C7EA46 Warmboot addr: #0x%05X\n"
"#C7EA46 Warmboot size: #0x%05X\n\n", "#C7EA46 Warmboot size: #0x%05X\n\n",
hdr_pk11->ldr_size, pkg1_id->secmon_base, hdr_pk11->sm_size, pkg1_id->warmboot_base, hdr_pk11->wb_size); hdr_pk11->ldr_size, hdr_pk11->sm_size, hdr_pk11->wb_size);
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
// Dump package1.1. // Dump package1.1.
emmcsn_path_impl(path, "/pkg1", "pkg1_decr.bin", &emmc_storage); emmcsn_path_impl(path, pkg1_paths[idx], "pkg1_decr.bin", &emmc_storage);
if (sd_save_to_file(pkg1, SZ_256K, path)) if (sd_save_to_file(pkg1, SZ_256K, path))
goto out_free; goto out;
strcat(txt_buf, "pkg1 dumped to pkg1_decr.bin\n"); strcat(txt_buf, "Package1 extracted to pkg1_decr.bin\n");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
// Dump nxbootloader. // Dump nxbootloader.
emmcsn_path_impl(path, "/pkg1", "nxloader.bin", &emmc_storage); emmcsn_path_impl(path, pkg1_paths[idx], "nxloader.bin", &emmc_storage);
if (sd_save_to_file(loader, hdr_pk11->ldr_size, path)) if (sd_save_to_file(loader, hdr_pk11->ldr_size, path))
goto out_free; goto out;
strcat(txt_buf, "NX Bootloader dumped to nxloader.bin\n"); strcat(txt_buf, "NX Bootloader extracted to nxloader.bin\n");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
// Dump secmon. // Dump secmon.
emmcsn_path_impl(path, "/pkg1", "secmon.bin", &emmc_storage); emmcsn_path_impl(path, pkg1_paths[idx], "secmon.bin", &emmc_storage);
if (sd_save_to_file(secmon, hdr_pk11->sm_size, path)) if (sd_save_to_file(secmon, hdr_pk11->sm_size, path))
goto out_free; goto out;
strcat(txt_buf, "Secure Monitor dumped to secmon.bin\n"); strcat(txt_buf, "Secure Monitor extracted to secmon.bin\n");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
// Dump warmboot. // Dump warmboot.
emmcsn_path_impl(path, "/pkg1", "warmboot.bin", &emmc_storage); emmcsn_path_impl(path, pkg1_paths[idx], "warmboot.bin", &emmc_storage);
if (sd_save_to_file(warmboot, hdr_pk11->wb_size, path)) if (sd_save_to_file(warmboot, hdr_pk11->wb_size, path))
goto out_free; goto out;
// If T210B01, save a copy of decrypted warmboot binary also. // If T210B01, save a copy of decrypted warmboot binary also.
if (h_cfg.t210b01) if (h_cfg.t210b01)
{ {
@@ -1279,39 +1343,35 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
se_aes_iv_clear(13); se_aes_iv_clear(13);
se_aes_crypt_cbc(13, DECRYPT, warmboot + 0x330, hdr_pk11->wb_size - 0x330, se_aes_crypt_cbc(13, DECRYPT, warmboot + 0x330, hdr_pk11->wb_size - 0x330,
warmboot + 0x330, hdr_pk11->wb_size - 0x330); warmboot + 0x330, hdr_pk11->wb_size - 0x330);
emmcsn_path_impl(path, "/pkg1", "warmboot_dec.bin", &emmc_storage); emmcsn_path_impl(path, pkg1_paths[idx], "warmboot_dec.bin", &emmc_storage);
if (sd_save_to_file(warmboot, hdr_pk11->wb_size, path)) if (sd_save_to_file(warmboot, hdr_pk11->wb_size, path))
goto out_free; goto out;
} }
strcat(txt_buf, "Warmboot dumped to warmboot.bin\n\n"); strcat(txt_buf, "Warmboot extracted to warmboot.bin\n\n");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
} }
// Dump package2.1. // Find and dump package2 partition.
emmc_set_partition(EMMC_GPP); emmc_set_partition(EMMC_GPP);
// Parse eMMC GPT. emmc_part_t *pkg2_part = emmc_part_find(&gpt, pkg2_partitions[idx]);
LIST_INIT(gpt);
emmc_gpt_parse(&gpt);
// Find package2 partition.
emmc_part_t *pkg2_part = emmc_part_find(&gpt, "BCPKG2-1-Normal-Main");
if (!pkg2_part) if (!pkg2_part)
goto out; goto out;
// Read in package2 header and get package2 real size. // Read in package2 header and get package2 real size.
static const u32 PKG2_OFFSET = 0x4000;
u8 *tmp = (u8 *)malloc(EMMC_BLOCKSIZE); u8 *tmp = (u8 *)malloc(EMMC_BLOCKSIZE);
emmc_part_read(pkg2_part, 0x4000 / EMMC_BLOCKSIZE, 1, tmp); emmc_part_read(pkg2_part, PKG2_OFFSET / EMMC_BLOCKSIZE, 1, tmp);
u32 *hdr_pkg2_raw = (u32 *)(tmp + 0x100); u32 *hdr_pkg2_raw = (u32 *)(tmp + 0x100);
u32 pkg2_size = hdr_pkg2_raw[0] ^ hdr_pkg2_raw[2] ^ hdr_pkg2_raw[3]; u32 pkg2_size = hdr_pkg2_raw[0] ^ hdr_pkg2_raw[2] ^ hdr_pkg2_raw[3];
free(tmp); free(tmp);
// Read in package2. // Read in package2.
u32 pkg2_size_aligned = ALIGN(pkg2_size, EMMC_BLOCKSIZE); u32 pkg2_size_aligned = ALIGN(pkg2_size, EMMC_BLOCKSIZE);
pkg2 = malloc(pkg2_size_aligned); emmc_part_read(pkg2_part, PKG2_OFFSET / EMMC_BLOCKSIZE, pkg2_size_aligned / EMMC_BLOCKSIZE, pkg2);
emmc_part_read(pkg2_part, 0x4000 / EMMC_BLOCKSIZE,
pkg2_size_aligned / EMMC_BLOCKSIZE, pkg2);
// Dump encrypted package2. // Dump encrypted package2.
emmcsn_path_impl(path, "/pkg2", "pkg2_encr.bin", &emmc_storage); emmcsn_path_impl(path, pkg2_paths[idx], "pkg2_encr.bin", &emmc_storage);
res = sd_save_to_file(pkg2, pkg2_size, path); res = sd_save_to_file(pkg2, pkg2_size, path);
// Decrypt package2 and parse KIP1 blobs in INI1 section. // Decrypt package2 and parse KIP1 blobs in INI1 section.
@@ -1319,13 +1379,13 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
if (!pkg2_hdr) if (!pkg2_hdr)
{ {
strcat(txt_buf, "#FFDD00 Pkg2 decryption failed!#"); strcat(txt_buf, "#FFDD00 Pkg2 decryption failed!#");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
if (!res) if (!res)
{ {
strcat(txt_buf, "\npkg2 encrypted dumped to pkg2_encr.bin\n"); strcat(txt_buf, "\npkg2 encrypted extracted to pkg2_encr.bin\n");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
} }
@@ -1337,27 +1397,27 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
// Display info. // Display info.
s_printf(txt_buf + strlen(txt_buf), s_printf(txt_buf + strlen(txt_buf),
"#C7EA46 Kernel size: #0x%05X\n" "#C7EA46 Kernel size: #0x%06X\n"
"#C7EA46 INI1 size: #0x%05X\n\n", "#C7EA46 INI1 size: #0x%06X\n\n",
pkg2_hdr->sec_size[PKG2_SEC_KERNEL], pkg2_hdr->sec_size[PKG2_SEC_INI1]); pkg2_hdr->sec_size[PKG2_SEC_KERNEL], pkg2_hdr->sec_size[PKG2_SEC_INI1]);
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
// Dump pkg2.1. // Dump pkg2.1.
emmcsn_path_impl(path, "/pkg2", "pkg2_decr.bin", &emmc_storage); emmcsn_path_impl(path, pkg2_paths[idx], "pkg2_decr.bin", &emmc_storage);
if (sd_save_to_file(pkg2, pkg2_hdr->sec_size[PKG2_SEC_KERNEL] + pkg2_hdr->sec_size[PKG2_SEC_INI1], path)) if (sd_save_to_file(pkg2, pkg2_hdr->sec_size[PKG2_SEC_KERNEL] + pkg2_hdr->sec_size[PKG2_SEC_INI1], path))
goto out; goto out;
strcat(txt_buf, "pkg2 dumped to pkg2_decr.bin\n"); strcat(txt_buf, "Package2 extracted to pkg2_decr.bin\n");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
// Dump kernel. // Dump kernel.
emmcsn_path_impl(path, "/pkg2", "kernel.bin", &emmc_storage); emmcsn_path_impl(path, pkg2_paths[idx], "kernel.bin", &emmc_storage);
if (sd_save_to_file(pkg2_hdr->data, pkg2_hdr->sec_size[PKG2_SEC_KERNEL], path)) if (sd_save_to_file(pkg2_hdr->data, pkg2_hdr->sec_size[PKG2_SEC_KERNEL], path))
goto out; goto out;
strcat(txt_buf, "Kernel dumped to kernel.bin\n"); strcat(txt_buf, "Kernel extracted to kernel.bin\n");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
// Dump INI1. // Dump INI1.
@@ -1377,12 +1437,12 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
} }
pkg2_ini1_t *ini1 = (pkg2_ini1_t *)(pkg2_hdr->data + ini1_off); pkg2_ini1_t *ini1 = (pkg2_ini1_t *)(pkg2_hdr->data + ini1_off);
emmcsn_path_impl(path, "/pkg2", "ini1.bin", &emmc_storage); emmcsn_path_impl(path, pkg2_paths[idx], "ini1.bin", &emmc_storage);
if (sd_save_to_file(ini1, ini1_size, path)) if (sd_save_to_file(ini1, ini1_size, path))
goto out; goto out;
strcat(txt_buf, "INI1 dumped to ini1.bin\n\n"); strcat(txt_buf, "INI1 extracted to ini1.bin\n");
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
char filename[32]; char filename[32];
@@ -1390,34 +1450,50 @@ static lv_res_t _create_window_dump_pk12_tool(lv_obj_t *btn)
ptr += sizeof(pkg2_ini1_t); ptr += sizeof(pkg2_ini1_t);
// Dump all kips. // Dump all kips.
u8 *kip_buffer = (u8 *)malloc(SZ_4M);
for (u32 i = 0; i < ini1->num_procs; i++) for (u32 i = 0; i < ini1->num_procs; i++)
{ {
pkg2_kip1_t *kip1 = (pkg2_kip1_t *)ptr; pkg2_kip1_t *kip1 = (pkg2_kip1_t *)ptr;
u32 kip1_size = pkg2_calc_kip1_size(kip1); u32 kip1_size = pkg2_calc_kip1_size(kip1);
char *kip_name = kip1->name;
s_printf(filename, "%s.kip1", kip1->name); // Check if FS supports exFAT.
if ((u32)kip1 % 8) if (!strcmp("FS", kip_name))
{ {
memcpy(kip_buffer, kip1, kip1_size); u8 *ro_data = malloc(SZ_4M);
kip1 = (pkg2_kip1_t *)kip_buffer; u32 offset = (kip1->flags & BIT(KIP_TEXT)) ? kip1->sections[KIP_TEXT].size_comp :
kip1->sections[KIP_TEXT].size_decomp;
u32 size_comp = kip1->sections[KIP_RODATA].size_comp;
u32 size_decomp = kip1->sections[KIP_RODATA].size_decomp;
if (kip1->flags & BIT(KIP_RODATA))
blz_uncompress_srcdest(&kip1->data[offset], size_comp, ro_data, size_decomp);
else
memcpy(ro_data, &kip1->data[offset], size_decomp);
for (u32 i = 0; i < 0x100; i+= sizeof(u32))
{
// Check size and name of nss matches.
if (*(u32 *)&ro_data[i] == 8 && !memcmp("fs.exfat", &ro_data[i + 4], 8))
{
kip_name = "FS_exfat";
break;
}
} }
emmcsn_path_impl(path, "/pkg2/ini1", filename, &emmc_storage); free(ro_data);
}
s_printf(filename, "%s.kip1", kip_name);
emmcsn_path_impl(path, pkg2ini_paths[idx], filename, &emmc_storage);
if (sd_save_to_file(kip1, kip1_size, path)) if (sd_save_to_file(kip1, kip1_size, path))
{
free(kip_buffer);
goto out; goto out;
}
s_printf(txt_buf + strlen(txt_buf), "%s kip dumped to %s.kip1\n", kip1->name, kip1->name); s_printf(txt_buf + strlen(txt_buf), "- Extracted %s.kip1\n", kip_name);
lv_label_set_text(lb_desc, txt_buf); lv_label_set_text(lb_log, txt_buf);
manual_system_maintenance(true); manual_system_maintenance(true);
ptr += kip1_size; ptr += kip1_size;
} }
free(kip_buffer); }
out: out:
emmc_gpt_free(&gpt); emmc_gpt_free(&gpt);

View File

@@ -26,6 +26,12 @@
#define PK11_SECTION_LD 1 #define PK11_SECTION_LD 1
#define PK11_SECTION_SM 2 #define PK11_SECTION_SM 2
#define PKG1_BOOTLOADER_SIZE SZ_256K
#define PKG1_BOOTLOADER_MAIN_OFFSET (0x100000 / EMMC_BLOCKSIZE)
#define PKG1_BOOTLOADER_BACKUP_OFFSET (0x140000 / EMMC_BLOCKSIZE)
#define PKG1_BOOTLOADER_SAFE_OFFSET (0x000000 / EMMC_BLOCKSIZE)
#define PKG1_HOS_EKS_OFFSET (0x180000 / EMMC_BLOCKSIZE)
typedef struct _bl_hdr_t210b01_t typedef struct _bl_hdr_t210b01_t
{ {
/* 0x000 */ u8 aes_mac[0x10]; /* 0x000 */ u8 aes_mac[0x10];