Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bootloader/hos/pkg2.h
3693 views
1
/*
2
* Copyright (c) 2018 naehrwert
3
* Copyright (c) 2018-2026 CTCaer
4
*
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms and conditions of the GNU General Public License,
7
* version 2, as published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
* more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
#ifndef _PKG2_H_
19
#define _PKG2_H_
20
21
#include <bdk.h>
22
23
#define PKG2_LOAD_ADDR 0xA9800000
24
25
#define PKG2_MAGIC 0x31324B50
26
#define PKG2_SEC_BASE 0x80000000
27
#define PKG2_SEC_KERNEL 0
28
#define PKG2_SEC_INI1 1
29
#define PKG2_SEC_UNUSED 2
30
31
#define INI1_MAGIC 0x31494E49
32
33
//! TODO: Update on kernel change if needed.
34
// Offset of OP + 12 is the INI1 offset. On v2 with dynamic crt0 it's + 16.
35
#define PKG2_NEWKERN_GET_INI1_HEURISTIC 0xD2800015 // MOV X21, #0.
36
#define PKG2_NEWKERN_START 0x800
37
38
#define ATM_MESOSPHERE 0x3053534D
39
40
extern u32 pkg2_newkern_ini1_info;
41
extern u32 pkg2_newkern_ini1_start;
42
extern u32 pkg2_newkern_ini1_end;
43
44
typedef struct _kernel_patch_t
45
{
46
u32 id;
47
u32 off;
48
u32 val;
49
const u32 *ptr;
50
} kernel_patch_t;
51
52
#define KERNEL_PATCHSET_DEF(name, ...) \
53
static const kernel_patch_t name[] = { \
54
__VA_ARGS__, \
55
{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, (u32 *)0xFFFFFFFF} \
56
}
57
58
enum
59
{
60
// Always applied.
61
SVC_GENERIC = 0,
62
// Generic instruction patches.
63
SVC_VERIFY_DS = 0x10,
64
DEBUG_MODE_EN = 0x11,
65
ATM_GEN_PATCH = 0x12,
66
ATM_SYSM_INCR = ATM_GEN_PATCH,
67
// >4 bytes patches. Value is a pointer of a u32 array.
68
ATM_ARR_PATCH = 0x13,
69
};
70
71
typedef struct _pkg2_hdr_t
72
{
73
/* 0x000 */ u8 ctr[0x10];
74
/* 0x010 */ u8 sec_ctr[4][SE_AES_IV_SIZE];
75
/* 0x050 */ u32 magic;
76
/* 0x054 */ u32 base;
77
/* 0x058 */ u32 pad0;
78
/* 0x05C */ u8 pkg2_ver;
79
/* 0x05D */ u8 bl_ver;
80
/* 0x05E */ u16 pad1;
81
/* 0x060 */ u32 sec_size[4];
82
/* 0x070 */ u32 sec_off[4];
83
/* 0x080 */ u8 sec_sha256[4][SE_SHA_256_SIZE];
84
/* 0x100 */ u8 data[];
85
} pkg2_hdr_t;
86
87
typedef struct _pkg2_ini1_t
88
{
89
u32 magic;
90
u32 size;
91
u32 num_procs;
92
u32 pad;
93
} pkg2_ini1_t;
94
95
enum kip_offset_section
96
{
97
KIP_TEXT = 0,
98
KIP_RODATA = 1,
99
KIP_DATA = 2,
100
KIP_BSS = 3,
101
KIP_UNKSEC1 = 4,
102
KIP_UNKSEC2 = 5
103
};
104
105
#define KIP1_NUM_SECTIONS 6
106
107
typedef struct _pkg2_kip1_sec_t
108
{
109
u32 offset;
110
u32 size_decomp;
111
u32 size_comp;
112
u32 attrib;
113
} pkg2_kip1_sec_t;
114
115
typedef struct _pkg2_kip1_t
116
{
117
/* 0x000 */ u32 magic;
118
/* 0x004 */ char name[12];
119
/* 0x010 */ u64 tid;
120
/* 0x018 */ u32 proc_cat;
121
/* 0x01C */ u8 main_thrd_prio;
122
/* 0x01D */ u8 def_cpu_core;
123
/* 0x01E */ u8 res;
124
/* 0x01F */ u8 flags;
125
/* 0x020 */ pkg2_kip1_sec_t sections[KIP1_NUM_SECTIONS];
126
/* 0x080 */ u32 caps[0x20];
127
/* 0x100 */ u8 data[];
128
} pkg2_kip1_t;
129
130
typedef struct _pkg2_kip1_info_t
131
{
132
pkg2_kip1_t *kip1;
133
u32 size;
134
link_t link;
135
} pkg2_kip1_info_t;
136
137
typedef struct _pkg2_kernel_id_t
138
{
139
u8 hash[8];
140
const kernel_patch_t *kernel_patchset;
141
} pkg2_kernel_id_t;
142
143
#define KIP1_PATCH_SRC_NO_CHECK (char *)(-1)
144
145
typedef struct _kip1_patch_t
146
{
147
u32 offset; // section+offset of patch to apply.
148
u32 length; // In bytes, 0 means last patch.
149
char *src_data; // That must match.
150
char *dst_data; // That it gets replaced by.
151
} kip1_patch_t;
152
153
typedef struct _kip1_patchset_t
154
{
155
char *name; // NULL means end.
156
const kip1_patch_t *patches; // NULL means not necessary.
157
} kip1_patchset_t;
158
159
typedef struct _kip1_id_t
160
{
161
const char *name;
162
u8 hash[8];
163
const kip1_patchset_t *patchset;
164
} kip1_id_t;
165
166
/*
167
* NX NC - Package2 BOOT Configuration
168
*
169
* This is taken from the first 1KB of a Package2 partition.
170
* On retail, it's not zeroes, but on devkits it has actual data.
171
* The signed part is reserved for special in-house devkits.
172
*/
173
#define NX_BC1_ADDR 0x4003D000
174
#define NX_BC6_ADDR 0x4003F800
175
176
#define NX_BC_DBG_FLAG00_DEV_MODE BIT(1)
177
#define NX_BC_DBG_FLAG00_SERROR BIT(2)
178
#define NX_BC_DBG_FLAG00_ALL_FLAGS 0xFF
179
180
#define NX_BC_HW_FLAG01_ALL_FLAGS 0xFF
181
#define NX_BC_HW_FLAG03_MEM_MODE 0xFF
182
#define NX_BC_HW_FLAG04_CNTCV_SET BIT(0)
183
184
#define NX_BC_PKG2_FLAG_DECRYPTED BIT(0)
185
#define NX_BC_PKG2_FLAG_UNSIGNED BIT(1)
186
187
#define NX_BC_NCA_FLAG_UNSIGNED BIT(0)
188
189
typedef struct _nx_bc_t {
190
/* Unsigned section */
191
u32 version;
192
u32 rsvd0[3];
193
u8 dbg_flags[0x10]; // Normally all are set to 0xFF if devkit.
194
u8 hw_flags[0x10];
195
u64 cntcv_value;
196
u8 padding0[0x1C8];
197
198
u8 rsa_pss_signature[0x100];
199
200
/* Signed section */
201
u32 version_signed;
202
u32 rsvd1;
203
u8 pkg2_flags;
204
u8 padding1[7];
205
u32 ecid[4];
206
u8 nca_flags[0x10];
207
u8 unk_flags[0x10];
208
u8 padding2[0xC0];
209
} nx_bc_t;
210
211
int pkg2_parse_kips(link_t *info, pkg2_hdr_t *pkg2, bool *new_pkg2);
212
bool pkg2_has_kip(link_t *info, u64 tid);
213
void pkg2_replace_kip(link_t *info, u64 tid, pkg2_kip1_t *kip1);
214
void pkg2_add_kip(link_t *info, pkg2_kip1_t *kip1);
215
void pkg2_merge_kip(link_t *info, pkg2_kip1_t *kip1);
216
void pkg2_get_ids(kip1_id_t **ids, u32 *entries);
217
const char *pkg2_patch_kips(link_t *info, char *patch_names);
218
219
const pkg2_kernel_id_t *pkg2_identify(const u8 *hash);
220
pkg2_hdr_t *pkg2_decrypt(void *data, u8 mkey, bool is_exo);
221
void pkg2_build_encrypt(void *dst, void *hos_ctxt, link_t *kips_info, bool is_exo);
222
223
#endif
224
225