forked from omgneeq/ps3utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pdb_gen.c
225 lines (190 loc) · 6.06 KB
/
pdb_gen.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/*
* pdb_gen.h -- PS3 .pdb file format generator
*
* Copyright (C) Youness Alaoui (KaKaRoTo)
*
* This software is distributed under the terms of the GNU General Public
* License ("GPL") version 3, as published by the Free Software Foundation.
*
*/
#include <stdio.h>
#include <stdint.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#ifdef WIN32
#include <winsock.h>
#define MKDIR(x,y) mkdir(x)
#else
#include <arpa/inet.h>
#define MKDIR(x,y) mkdir(x,y)
#endif
#define PDB_HEADER 0x00000000
#define UNKNOWN_HEADER1 0x00000064
#define UNKNOWN_HEADER2 0x00000065
#define UNKNOWN_HEADER3 0x00000066
#define UNKNOWN_HEADER4 0x0000006B
#define UNKNOWN_HEADER5 0x00000068
#define UNKNOWN_HEADER6 0x0000006C
#define HEADER5_MAGIC_VALUE 0x80023E13
#define CURRENT_LENGTH 0x000000D0
#define TOTAL_LENGTH 0x000000CE
#define PKG_DATE 0x000000CC
#define IMAGE_PATH 0x0000006A
#define TITLE 0x00000069
#define DOWNLOAD_URL 0x000000CA
#define FILENAME 0x000000CB
#define CONTENT_ID 0x000000D9
#define UNKNOWN1 0x000000DA
#define UNKNOWN2 0x000000CD
#define LOG_URL 0x000000EB
#define UNKNOWN3 0x000000EC
typedef struct {
uint32_t magic;
uint32_t type;
uint32_t pkg_info_offset;
uint32_t unknown;
uint32_t header_size;
uint32_t item_count;
uint64_t pkg_size;
uint64_t data_offset;
uint64_t data_size;
char content_id[30];
uint8_t QA_digest[10];
uint8_t unknown_digest[10];
} PkgHeader;
static void
write_kllv (FILE *f, uint32_t key, uint32_t len, uint8_t *value)
{
uint32_t key_be = htonl (key);
uint32_t len_be = htonl (len);
fwrite (&key_be, sizeof(uint32_t), 1, f);
fwrite (&len_be, sizeof(uint32_t), 1, f);
fwrite (&len_be, sizeof(uint32_t), 1, f);
fwrite (value, 1, len, f);
}
static void
write_pdb (FILE *f, char *out_path, char *pkg_path, char *title,
PkgHeader *pkg_header, uint32_t header5) {
uint32_t pdb_header = htonl (PDB_HEADER);
uint32_t header1 = htonl (0);
uint32_t header2 = htonl (0);
uint8_t header3 = 0;
uint32_t header4 = htonl (3);
uint32_t header6 = htonl (0);
uint64_t pkg_size = pkg_header->pkg_size; /* already in BE */
char pkg_date[] = "Thu, 02 Sep 2010 17:28:10 GMT";
char icon_file[1024];
char content_title[1024];
char download_url[1024];
uint8_t unknown1 = 1;
uint8_t unknown2 = 0;
char log_url[] = "http://google.com";
uint8_t unknown3 = 0;
int i;
fwrite (&pdb_header, sizeof(pdb_header), 1, f);
i = 0;
memset (download_url, 0, sizeof(download_url));
strcpy (download_url, "http://zeus.dl.playstation.net/cdn/");
while (pkg_header->content_id[i] != '-')
download_url[strlen (download_url)] = pkg_header->content_id[i++];
download_url[strlen (download_url)] = '/';
i++;
while (pkg_header->content_id[i] != '-')
download_url[strlen (download_url)] = pkg_header->content_id[i++];
download_url[strlen (download_url)] = '/';
strcat (download_url, pkg_path);
strcat (download_url, "?product=0084&country=us");
i++;
if (title == NULL)
strcpy (content_title, pkg_header->content_id + i);
else
strcpy (content_title, title);
sprintf (icon_file, "/dev_hdd0/vsh/task/%s/ICON_FILE", out_path);
write_kllv (f, UNKNOWN_HEADER1, sizeof(uint32_t), (uint8_t *) &header1);
write_kllv (f, UNKNOWN_HEADER2, sizeof(uint32_t), (uint8_t *) &header2);
write_kllv (f, UNKNOWN_HEADER3, sizeof(uint8_t), &header3);
write_kllv (f, UNKNOWN_HEADER4, sizeof(uint32_t), (uint8_t *) &header4);
write_kllv (f, UNKNOWN_HEADER5, sizeof(uint32_t), (uint8_t *) &header5);
write_kllv (f, UNKNOWN_HEADER6, sizeof(uint32_t), (uint8_t *) &header6);
write_kllv (f, CURRENT_LENGTH, sizeof(uint64_t), (uint8_t *) &pkg_size);
write_kllv (f, TOTAL_LENGTH, sizeof(uint64_t), (uint8_t *) &pkg_size);
write_kllv (f, PKG_DATE, strlen (pkg_date) + 1, (uint8_t *) pkg_date);
write_kllv (f, IMAGE_PATH, strlen (icon_file) + 1, (uint8_t *) icon_file);
write_kllv (f, TITLE, strlen (content_title) + 1, (uint8_t *) content_title);
write_kllv (f, DOWNLOAD_URL, strlen (download_url) + 1, (uint8_t *) download_url);
write_kllv (f, FILENAME, strlen (pkg_path) + 1, (uint8_t *) pkg_path);
write_kllv (f, CONTENT_ID, strlen (pkg_header->content_id) + 1,
(uint8_t *) pkg_header->content_id);
write_kllv (f, UNKNOWN1, sizeof(uint8_t), (uint8_t *) &unknown1);
write_kllv (f, UNKNOWN2, sizeof(uint8_t), (uint8_t *) &unknown2);
write_kllv (f, LOG_URL, strlen (log_url) + 1, (uint8_t *) log_url);
write_kllv (f, UNKNOWN3, sizeof(uint8_t), (uint8_t *) &unknown3);
}
int main (int argc, char *argv[])
{
FILE *pkg = NULL;
FILE *out1 = NULL;
FILE *out2 = NULL;
PkgHeader pkg_header;
char path[9];
int ret = -1;
int i;
if (argc < 2 || argc > 3) {
printf ("Usage: %s file.pkg ?title?", argv[0]);
return -1;
}
pkg = fopen (argv[1], "rb");
if (pkg == NULL) {
perror ("Failed to open .pkg file : ");
return -2;
}
if (fread (&pkg_header, sizeof(pkg_header), 1, pkg) < 1) {
perror ("Couldn't read pkg data : ");
return -3;
}
fclose (pkg);
for (i = 2; i < 20 && ret == -1; i++) {
sprintf (path, "%.8X", i);
ret = MKDIR (path, 0777);
if (ret != 0 && errno != EEXIST) {
perror ("Error creating directory : ");
return -4;
}
}
if (ret == -1) {
perror ("Couldn't create directory in 20 attempts : ");
return -5;
}
if (chdir (path) != 0) {
perror ("Couldn't change directory : ");
return -6;
}
out1 = fopen ("f0.pdb", "wb");
if (out1 == NULL) {
perror ("Couldn't create f0.pdb : ");
return -7;
}
fclose (out1);
out1 = fopen ("d0.pdb", "wb");
if (out1 == NULL) {
perror ("Couldn't create d0.pdb : ");
return -8;
}
out2 = fopen ("d1.pdb", "wb");
if (out2 == NULL) {
perror ("Couldn't create d1.pdb : ");
fclose (out1);
return -9;
}
write_pdb (out1, path, argv[1], argc >= 3 ? argv[2]: NULL,
&pkg_header, htonl (HEADER5_MAGIC_VALUE));
write_pdb (out2, path, argv[1], argc >= 3 ? argv[2]: NULL,
&pkg_header, htonl (0));
fclose (out1);
fclose (out2);
printf ("Created pkg directory %s\n", path);
return 0;
}