Skip to content

Commit b3ce86e

Browse files
committed
unpack PSP pkg files to CSO
1 parent 2731502 commit b3ce86e

9 files changed

+312
-25
lines changed

pkg2zip.c

+12-3
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ int main(int argc, char* argv[])
275275
printf("pkg2zip v1.8\n");
276276

277277
int zipped = 1;
278+
int cso = 5;
278279
const char* pkg_arg = NULL;
279280
const char* zrif_arg = NULL;
280281
for (int i = 1; i < argc; i++)
@@ -283,6 +284,14 @@ int main(int argc, char* argv[])
283284
{
284285
zipped = 0;
285286
}
287+
else if (strncmp(argv[i], "-c", 2) == 0)
288+
{
289+
if (argv[i][2] != 0)
290+
{
291+
cso = atoi(argv[i] + 2);
292+
cso = cso > 9 ? 9 : cso < 0 ? 0 : cso;
293+
}
294+
}
286295
else
287296
{
288297
if (pkg_arg != NULL)
@@ -300,7 +309,7 @@ int main(int argc, char* argv[])
300309
if (pkg_arg == NULL)
301310
{
302311
fprintf(stderr, "ERROR: no pkg file specified\n");
303-
fatal("Usage: %s [-x] file.pkg [zRIF]\n", argv[0]);
312+
fatal("Usage: %s [-x] [-c[N]] file.pkg [zRIF]\n", argv[0]);
304313
}
305314

306315
printf("[*] loading...\n");
@@ -706,8 +715,8 @@ int main(int argc, char* argv[])
706715
{
707716
if (strcmp("USRDIR/CONTENT/EBOOT.PBP", name) == 0)
708717
{
709-
snprintf(path, sizeof(path), "pspemu/ISO/%s [%.9s].iso", title, id);
710-
unpack_psp_eboot(path, item_key, iv, pkg, enc_offset, data_offset, data_size);
718+
snprintf(path, sizeof(path), "pspemu/ISO/%s [%.9s].%s", title, id, cso ? "cso" : "iso");
719+
unpack_psp_eboot(path, item_key, iv, pkg, enc_offset, data_offset, data_size, cso);
711720
continue;
712721
}
713722
else if (strcmp("USRDIR/CONTENT/PSP-KEY.EDAT", name) == 0)

pkg2zip_crc32.c

+67
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,70 @@ uint32_t crc32_done(crc32_ctx* ctx)
258258

259259
return ~ctx->crc[0];
260260
}
261+
262+
static uint32_t crc32_gfmulv(const uint32_t* m, uint32_t v)
263+
{
264+
uint32_t r = 0;
265+
while (v)
266+
{
267+
if (v & 1)
268+
{
269+
r ^= *m;
270+
}
271+
v >>= 1;
272+
m++;
273+
}
274+
return r;
275+
}
276+
277+
static void crc32_gfsq(const uint32_t* m, uint32_t* r)
278+
{
279+
for (size_t i = 0; i < 32; i++)
280+
{
281+
r[i] = crc32_gfmulv(m, m[i]);
282+
}
283+
}
284+
285+
uint32_t crc32_combine(uint32_t a, uint32_t b, uint32_t blen)
286+
{
287+
uint32_t m1[32];
288+
uint32_t m2[32];
289+
290+
m1[0] = 0xedb88320;
291+
for (uint32_t i = 1; i < 32; i++)
292+
{
293+
m1[i] = 1 << (i - 1);
294+
}
295+
296+
crc32_gfsq(m1, m2);
297+
crc32_gfsq(m2, m1);
298+
299+
for (;;)
300+
{
301+
crc32_gfsq(m1, m2);
302+
if (blen & 1)
303+
{
304+
a = crc32_gfmulv(m2, a);
305+
}
306+
blen >>= 1;
307+
308+
if (blen == 0)
309+
{
310+
break;
311+
}
312+
313+
crc32_gfsq(m2, m1);
314+
if (blen & 1)
315+
{
316+
a = crc32_gfmulv(m1, a);
317+
}
318+
blen >>= 1;
319+
320+
if (blen == 0)
321+
{
322+
break;
323+
}
324+
}
325+
326+
return a ^ b;
327+
}

pkg2zip_crc32.h

+5
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ typedef struct {
99
void crc32_init(crc32_ctx* ctx);
1010
void crc32_update(crc32_ctx* ctx, const void* buffer, size_t size);
1111
uint32_t crc32_done(crc32_ctx* ctx);
12+
13+
// returns crc32(x||y)
14+
// where a=crc32(x) and b=crc32(y)
15+
// crc32(x||y) = crc32(x||z) ^ crc32(y), where z=00...00 (same length as y)
16+
uint32_t crc32_combine(uint32_t a, uint32_t b, uint32_t blen);

pkg2zip_out.c

+45-2
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,17 @@ void out_add_folder(const char* path)
3636
}
3737
}
3838

39-
void out_begin_file(const char* name, int compress)
39+
uint64_t out_begin_file(const char* name, int compress)
4040
{
4141
if (out_zipped)
4242
{
43-
zip_begin_file(&out_zip, name, compress);
43+
return zip_begin_file(&out_zip, name, compress);
4444
}
4545
else
4646
{
4747
out_file = sys_create(name);
4848
out_file_offset = 0;
49+
return 0;
4950
}
5051
}
5152

@@ -73,3 +74,45 @@ void out_write(const void* buffer, uint32_t size)
7374
out_file_offset += size;
7475
}
7576
}
77+
78+
void out_write_at(uint64_t offset, const void* buffer, uint32_t size)
79+
{
80+
if (out_zipped)
81+
{
82+
zip_write_file_at(&out_zip, offset, buffer, size);
83+
}
84+
else
85+
{
86+
sys_write(out_file, offset, buffer, size);
87+
}
88+
}
89+
90+
void out_set_offset(uint64_t offset)
91+
{
92+
if (out_zipped)
93+
{
94+
zip_set_offset(&out_zip, offset);
95+
}
96+
else
97+
{
98+
out_file_offset = offset;
99+
100+
}
101+
}
102+
103+
uint32_t out_zip_get_crc32(void)
104+
{
105+
if (out_zipped)
106+
{
107+
return zip_get_crc32(&out_zip);
108+
}
109+
return 0;
110+
}
111+
112+
void out_zip_set_crc32(uint32_t crc)
113+
{
114+
if (out_zipped)
115+
{
116+
zip_set_crc32(&out_zip, crc);
117+
}
118+
}

pkg2zip_out.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
void out_begin(const char* name, int zipped);
66
void out_end(void);
77
void out_add_folder(const char* path);
8-
void out_begin_file(const char* name, int compress);
8+
uint64_t out_begin_file(const char* name, int compress);
99
void out_end_file(void);
1010
void out_write(const void* buffer, uint32_t size);
11+
12+
// hacky solution to be able to write cso header after the data is written
13+
void out_write_at(uint64_t offset, const void* buffer, uint32_t size);
14+
void out_set_offset(uint64_t offset);
15+
uint32_t out_zip_get_crc32(void);
16+
void out_zip_set_crc32(uint32_t crc);

0 commit comments

Comments
 (0)