2018-02-06 23:52:48 +00:00
|
|
|
#ifndef HACTOOL_PACKAGES_H
|
|
|
|
#define HACTOOL_PACKAGES_H
|
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#include "settings.h"
|
2018-02-07 08:10:26 +00:00
|
|
|
#include "kip.h"
|
2018-02-06 23:52:48 +00:00
|
|
|
|
|
|
|
#define MAGIC_PK11 0x31314B50
|
|
|
|
#define MAGIC_PK21 0x31324B50
|
2019-04-25 15:07:08 +00:00
|
|
|
#define MAGIC_KRNLLDR_STRCT_END 0xD51C403E
|
2018-02-06 23:52:48 +00:00
|
|
|
|
|
|
|
typedef struct {
|
2020-06-01 09:19:40 +00:00
|
|
|
unsigned char aes_mac[0x10];
|
|
|
|
unsigned char rsa_sig[0x100];
|
|
|
|
unsigned char salt[0x20];
|
|
|
|
unsigned char hash[0x20];
|
|
|
|
uint32_t bl_version;
|
|
|
|
uint32_t bl_size;
|
|
|
|
uint32_t bl_load_addr;
|
|
|
|
uint32_t bl_entrypoint;
|
|
|
|
unsigned char _0x160[0x10];
|
|
|
|
} pk11_mariko_oem_header_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint32_t ldr_hash;
|
|
|
|
uint32_t sm_hash;
|
|
|
|
uint32_t bl_hash;
|
|
|
|
uint32_t _0xC;
|
|
|
|
char build_date[0xE];
|
|
|
|
unsigned char _0x1E;
|
|
|
|
unsigned char version;
|
|
|
|
} pk11_metadata_t;
|
|
|
|
|
|
|
|
typedef struct {
|
2018-02-06 23:52:48 +00:00
|
|
|
unsigned char stage1[0x3FC0];
|
|
|
|
uint32_t pk11_size;
|
2020-06-01 09:19:40 +00:00
|
|
|
unsigned char _0x3FC4[0xC];
|
2018-02-06 23:52:48 +00:00
|
|
|
unsigned char ctr[0x10];
|
2020-06-01 09:19:40 +00:00
|
|
|
} pk11_legacy_stage1_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
unsigned char stage1[0x6FC0];
|
|
|
|
uint32_t pk11_size;
|
|
|
|
unsigned char _0x6FC4[0xC];
|
|
|
|
unsigned char iv[0x10];
|
|
|
|
} pk11_modern_stage1_t;
|
|
|
|
|
|
|
|
typedef union {
|
|
|
|
pk11_legacy_stage1_t legacy;
|
|
|
|
pk11_modern_stage1_t modern;
|
2018-02-06 23:52:48 +00:00
|
|
|
} pk11_stage1_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint32_t magic;
|
2020-06-01 09:19:40 +00:00
|
|
|
uint32_t wb_size;
|
|
|
|
uint32_t wb_ep;
|
2018-02-06 23:52:48 +00:00
|
|
|
uint32_t _0xC;
|
2020-06-01 09:19:40 +00:00
|
|
|
uint32_t bl_size;
|
|
|
|
uint32_t bl_ep;
|
|
|
|
uint32_t sm_size;
|
|
|
|
uint32_t sm_ep;
|
2018-02-06 23:52:48 +00:00
|
|
|
unsigned char data[];
|
|
|
|
} pk11_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
FILE *file;
|
|
|
|
hactool_ctx_t *tool_ctx;
|
2020-06-01 09:19:40 +00:00
|
|
|
int is_modern;
|
|
|
|
int is_mariko;
|
2020-06-01 22:31:32 +00:00
|
|
|
int is_decrypted;
|
2018-02-06 23:52:48 +00:00
|
|
|
unsigned int key_rev;
|
2020-06-01 09:19:40 +00:00
|
|
|
pk11_mariko_oem_header_t mariko_oem_header;
|
|
|
|
pk11_metadata_t metadata;
|
2018-02-06 23:52:48 +00:00
|
|
|
pk11_stage1_t stage1;
|
2020-06-01 09:19:40 +00:00
|
|
|
uint32_t pk11_size;
|
|
|
|
uint8_t *mariko_bl;
|
2018-02-06 23:52:48 +00:00
|
|
|
pk11_t *pk11;
|
2020-06-01 09:19:40 +00:00
|
|
|
unsigned char pk11_mac[0x10];
|
2018-02-06 23:52:48 +00:00
|
|
|
} pk11_ctx_t;
|
|
|
|
|
2020-06-01 09:19:40 +00:00
|
|
|
typedef enum {
|
|
|
|
PK11_SECTION_BL,
|
|
|
|
PK11_SECTION_SM,
|
|
|
|
PK11_SECTION_WB,
|
|
|
|
} pk11_section_id_t;
|
|
|
|
|
|
|
|
static inline int pk11_get_section_idx(pk11_ctx_t *ctx, pk11_section_id_t section_id) {
|
|
|
|
if (ctx->metadata.version >= 0x07) {
|
|
|
|
switch (section_id) {
|
|
|
|
case PK11_SECTION_BL: return 0;
|
|
|
|
case PK11_SECTION_SM: return 1;
|
|
|
|
case PK11_SECTION_WB: return 2;
|
|
|
|
}
|
|
|
|
} else if (ctx->metadata.version >= 0x02) {
|
|
|
|
switch (section_id) {
|
|
|
|
case PK11_SECTION_BL: return 1;
|
|
|
|
case PK11_SECTION_SM: return 2;
|
|
|
|
case PK11_SECTION_WB: return 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (section_id) {
|
|
|
|
case PK11_SECTION_BL: return 1;
|
|
|
|
case PK11_SECTION_SM: return 0;
|
|
|
|
case PK11_SECTION_WB: return 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline pk11_section_id_t pk11_get_section_id(pk11_ctx_t *ctx, int id) {
|
|
|
|
if (pk11_get_section_idx(ctx, PK11_SECTION_BL) == id) {
|
|
|
|
return PK11_SECTION_BL;
|
|
|
|
} else if (pk11_get_section_idx(ctx, PK11_SECTION_SM) == id) {
|
|
|
|
return PK11_SECTION_SM;
|
|
|
|
} else {
|
|
|
|
return PK11_SECTION_WB;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint32_t pk11_get_section_size(pk11_ctx_t *ctx, pk11_section_id_t section_id) {
|
|
|
|
switch (section_id) {
|
|
|
|
case PK11_SECTION_BL: return ctx->pk11->bl_size;
|
|
|
|
case PK11_SECTION_SM: return ctx->pk11->sm_size;
|
|
|
|
case PK11_SECTION_WB: return ctx->pk11->wb_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint32_t pk11_get_section_ofs(pk11_ctx_t *ctx, pk11_section_id_t section_id) {
|
|
|
|
switch (pk11_get_section_idx(ctx, section_id)) {
|
|
|
|
case 0:
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
case 1:
|
|
|
|
return pk11_get_section_size(ctx, pk11_get_section_id(ctx, 0));
|
|
|
|
case 2:
|
|
|
|
return pk11_get_section_size(ctx, pk11_get_section_id(ctx, 0)) + pk11_get_section_size(ctx, pk11_get_section_id(ctx, 1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned char *pk11_get_section(pk11_ctx_t *ctx, pk11_section_id_t section_id) {
|
|
|
|
return &ctx->pk11->data[pk11_get_section_ofs(ctx, section_id)];
|
|
|
|
}
|
2018-02-06 23:52:48 +00:00
|
|
|
|
|
|
|
static inline unsigned char *pk11_get_warmboot_bin(pk11_ctx_t *ctx) {
|
2020-06-01 09:19:40 +00:00
|
|
|
return pk11_get_section(ctx, PK11_SECTION_WB);
|
2018-02-06 23:52:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned char *pk11_get_secmon(pk11_ctx_t *ctx) {
|
2020-06-01 09:19:40 +00:00
|
|
|
return pk11_get_section(ctx, PK11_SECTION_SM);
|
2018-02-06 23:52:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned char *pk11_get_nx_bootloader(pk11_ctx_t *ctx) {
|
2020-06-01 09:19:40 +00:00
|
|
|
return pk11_get_section(ctx, PK11_SECTION_BL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int pk11_get_warmboot_bin_size(pk11_ctx_t *ctx) {
|
|
|
|
return pk11_get_section_size(ctx, PK11_SECTION_WB);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int pk11_get_secmon_size(pk11_ctx_t *ctx) {
|
|
|
|
return pk11_get_section_size(ctx, PK11_SECTION_SM);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int pk11_get_nx_bootloader_size(pk11_ctx_t *ctx) {
|
|
|
|
return pk11_get_section_size(ctx, PK11_SECTION_BL);
|
2018-02-06 23:52:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pk11_process(pk11_ctx_t *ctx);
|
|
|
|
void pk11_print(pk11_ctx_t *ctx);
|
|
|
|
void pk11_save(pk11_ctx_t *ctx);
|
|
|
|
|
2018-02-07 06:06:19 +00:00
|
|
|
|
|
|
|
/* Package2 */
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
typedef struct {
|
|
|
|
unsigned char signature[0x100];
|
|
|
|
union {
|
|
|
|
unsigned char ctr[0x10];
|
|
|
|
uint32_t ctr_dwords[0x4];
|
|
|
|
};
|
|
|
|
unsigned char section_ctrs[4][0x10];
|
|
|
|
uint32_t magic;
|
|
|
|
uint32_t base_offset;
|
|
|
|
uint32_t _0x58;
|
|
|
|
uint8_t version_max; /* Must be > TZ value. */
|
|
|
|
uint8_t version_min; /* Must be < TZ value. */
|
|
|
|
uint16_t _0x5E;
|
|
|
|
uint32_t section_sizes[4];
|
|
|
|
uint32_t section_offsets[4];
|
|
|
|
unsigned char section_hashes[4][0x20];
|
|
|
|
} pk21_header_t;
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
2019-04-25 15:07:08 +00:00
|
|
|
typedef struct {
|
|
|
|
uint32_t text_start_offset;
|
|
|
|
uint32_t text_end_offset;
|
|
|
|
uint32_t rodata_start_offset;
|
|
|
|
uint32_t rodata_end_offset;
|
|
|
|
uint32_t data_start_offset;
|
|
|
|
uint32_t data_end_offset;
|
|
|
|
uint32_t bss_start_offset;
|
|
|
|
uint32_t bss_end_offset;
|
|
|
|
uint32_t ini1_start_offset;
|
|
|
|
uint32_t dynamic_offset;
|
|
|
|
uint32_t init_array_start_offset;
|
|
|
|
uint32_t init_array_end_offset;
|
|
|
|
} kernel_map_t;
|
|
|
|
|
2019-04-30 12:30:34 +00:00
|
|
|
typedef struct {
|
|
|
|
FILE *file;
|
|
|
|
hactool_ctx_t *tool_ctx;
|
|
|
|
unsigned int key_rev;
|
|
|
|
uint32_t package_size;
|
|
|
|
validity_t signature_validity;
|
|
|
|
validity_t section_validities[4];
|
|
|
|
unsigned char *sections;
|
|
|
|
pk21_header_t header;
|
|
|
|
ini1_ctx_t ini1_ctx;
|
|
|
|
kernel_map_t *kernel_map;
|
|
|
|
} pk21_ctx_t;
|
|
|
|
|
2018-02-07 06:06:19 +00:00
|
|
|
void pk21_process(pk21_ctx_t *ctx);
|
|
|
|
void pk21_print(pk21_ctx_t *ctx);
|
|
|
|
void pk21_save(pk21_ctx_t *ctx);
|
|
|
|
|
2019-05-05 04:26:34 +00:00
|
|
|
#endif
|