forked from wargio/vitatool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreadself.c
314 lines (263 loc) · 11.5 KB
/
readself.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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
// Copyright 2012 Grazioli Giovanni <wargio@libero.it>
// Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include "tools.h"
#include "types.h"
#include "little_endian.h"
#include "readself.h"
static u8 *self = NULL;
const u32 HDR = 0x53434500;
//64bit
void program_hdr(u64 offset){
uint32_t p_type = le32(self+offset); /* type of segment */
offset+=sizeof(uint32_t);
uint32_t p_flags = le32(self+offset); /* segment attributes */
offset+=sizeof(uint32_t);
uint32_t p_offset = le32(self+offset); /* offset in file */
offset+=sizeof(uint32_t);
uint32_t p_vaddr = le32(self+offset); /* virtual address in memory */
offset+=sizeof(uint32_t);
uint32_t p_paddr = le32(self+offset); /* reserved */
offset+=sizeof(uint32_t);
uint32_t p_filesz = le32(self+offset); /* size of segment in file */
offset+=sizeof(uint32_t);
uint32_t p_memsz = le32(self+offset); /* size of segment in memory */
offset+=sizeof(uint32_t);
uint32_t p_align = le32(self+offset); /* alignment of segment */
offset+=sizeof(uint32_t);
const char* p_type_char = prg_type(p_type);
const char* p_flags_char = prg_flags(p_flags);
printf("--- SELF PROGRAM INFO ---\n");
printf("Type 0x%08x [%s]\n",p_type,p_type_char);
printf("Flags 0x%08x [%s]\n",p_flags,p_flags_char);
printf("Offset 0x%08x\n",p_offset);
printf("Virtual Address 0x%08x\n",p_vaddr);
printf("Reserved Adderess 0x%08x\n",p_paddr);
printf("Real Size 0x%08x (%u Bytes)\n",p_filesz,p_filesz);
printf("Size in Memory 0x%08x (%u Bytes)\n",p_memsz,p_memsz);
printf("Alignment 0x%08x (%u)\n",p_align,p_align);
}
void section_hdr(u64 offset){
uint32_t sh_name = le32(self+offset); /* section name */
offset+=sizeof(uint32_t);
uint32_t sh_type = le32(self+offset); /* section type */
offset+=sizeof(uint32_t);
uint32_t sh_flags = le32(self+offset); /* section attributes */
offset+=sizeof(uint32_t);
uint32_t sh_addr = le32(self+offset); /* virtual address in memory */
offset+=sizeof(uint32_t);
uint32_t sh_offset = le32(self+offset); /* offset in file */
offset+=sizeof(uint32_t);
uint32_t sh_size = le32(self+offset); /* size of section */
offset+=sizeof(uint32_t);
uint32_t sh_link = le32(self+offset); /* link to other section */
offset+=sizeof(uint32_t);
uint32_t sh_info = le32(self+offset); /* miscellaneous information */
offset+=sizeof(uint32_t);
uint32_t sh_addralign = le32(self+offset); /* address alignment boundary */
offset+=sizeof(uint32_t);
uint32_t sh_entsize = le32(self+offset); /* size of entries, if section has table */
offset+=sizeof(uint32_t);
printf("--- SELF PROGRAM INFO ---\n");
printf("Name 0x%08x\n",sh_name);
printf("Type 0x%08x\n",sh_type);
printf("Flags 0x%08x\n",sh_flags);
printf("Virtual Address 0x%08x\n",sh_addr);
printf("Offset 0x%08x (%u Bytes)\n",sh_offset,sh_offset);
printf("Size 0x%08x\n",sh_size);
printf("Link to other section 0x%08x\n",sh_link);
printf("Info 0x%08x\n",sh_info);
printf("Address Alignment 0x%08x\n",sh_addralign);
printf("Size Entries 0x%08x (%u Bytes)\n",sh_entsize,sh_entsize);
}
void elf(u64 offset){
uint8_t e_ident[16];
int i=0;
for(i=0;i<0x10;i++)
e_ident[i] = be8(self+offset+i);
uint16_t e_type = le16(self+offset+0x10); /* object file type */
offset+=0x10+sizeof(uint16_t);
uint16_t e_machine = le16(self+offset); /* machine type */
offset+=sizeof(uint16_t);
uint32_t e_version = le32(self+offset); /* object file version */
offset+=sizeof(uint32_t);
uint32_t e_entry = le32(self+offset); /* entry point address */
offset+=sizeof(uint32_t);
uint32_t e_phoff = le32(self+offset); /* program header offset */
offset+=sizeof(uint32_t);
uint32_t e_shoff = le32(self+offset); /* section header offset */
offset+=sizeof(uint32_t);
uint16_t e_flags = le16(self+offset); /* processor-specific flags */
offset+=sizeof(uint16_t);
uint32_t e_ehsize = le16(self+offset); /* ELF header size */
offset+=sizeof(uint16_t);
uint16_t e_phentsize = le16(self+offset); /* size of program header entry */
offset+=sizeof(uint16_t);
uint16_t e_phnum = le16(self+offset); /* number of program header entries */
offset+=sizeof(uint16_t);
uint16_t e_shentsize = le16(self+offset); /* size of section header entry */
offset+=sizeof(uint16_t);
uint16_t e_shnum = le16(self+offset); /* number of section header entries */
offset+=sizeof(uint16_t);
uint16_t e_shstrndx = le16(self+offset); /* section name string table index */
offset+=sizeof(uint16_t);
printf("--- ELF INFO ---\n");
printf("File Class 0x%02x [%s]\n",e_ident[4],(e_ident[4]==1) ? "ELFCLASS64" : "ELFCLASS32");
printf("File Data 0x%02x [%s]\n",e_ident[5],(e_ident[5]==1) ? "ELFDATA2MSB][BIG ENDIAN" : "ELFDATA2LSB][LITTLE ENDIAN");
printf("File Version 0x%02x\n",e_ident[6]);
printf("Type 0x%04x [%s]\n",e_type,(e_type==2) ? "EXEC" : "PRX");
printf("Machine Type 0x%04x\n",e_machine);
printf("Version 0x%08x\n",e_version);
printf("Entry Point Address 0x%08x\n",e_entry);
printf("Program Header Offset 0x%08x\n",e_phoff);
printf("Section Header Offset 0x%08x\n",e_shoff);
printf("Flag 0x%04x\n",e_flags);
printf("ELF Header Size 0x%08x (%u Bytes)\n",e_ehsize,e_ehsize);
printf("Size Progr Hdr Entry 0x%04x (%u Bytes)\n",e_phentsize,e_phentsize);
printf("Number Hdr Entries 0x%04x (%u)\n",e_phnum,e_phnum);
printf("Size Sect Hdr Entry 0x%04x (%u Bytes)\n",e_shentsize,e_shentsize);
printf("Number Hdr Entries 0x%04x (%u)\n",e_shnum,e_shnum);
printf("Section String Table 0x%04x\n",e_shstrndx);
}
void app_info(u64 offset){
u64 authid = le64(self+offset); /* auth id */
offset += sizeof(u64);
u32 vendor_id = le32(self+offset); /* vendor id */
offset += sizeof(u32);
u32 self_type = le32(self+offset); /* app type */
offset += sizeof(u32);
u64 version = le64(self+offset); /* app version */
offset += sizeof(u64);
u64 padding = le64(self+offset); /* UNKNOWN */
offset += sizeof(u64);
printf("--- APP INFO ---\n");
printf("Authority ID 0x%016lx\n",authid);
printf("Vendor ID 0x%08x\n",vendor_id);
printf("SELF Type 0x%08x\n",self_type);
printf("Version 0x%016lx\n",version);
printf("Padding 0x%016lx\n",padding);
}
void sce_version(u64 offset){
uint32_t unknown1 = le32(self+offset);
offset+=sizeof(uint32_t);
uint32_t unknown2 = le32(self+offset);
offset+=sizeof(uint32_t);
uint32_t unknown3 = le32(self+offset);
offset+=sizeof(uint32_t);
uint32_t unknown4 = le32(self+offset);
offset+=sizeof(uint32_t);
printf("--- SELF SCE VERSION ---\n");
printf("Unknown_1 0x%08x\n",unknown1);
printf("Unknown_2 0x%08x\n",unknown2);
printf("Unknown_3 0x%08x\n",unknown3);
printf("Unknown_4 0x%08x\n",unknown4);
}
void control_information(u64 offset){
uint32_t type = le32(self+offset); // 4== ; 6==;7==
offset+=sizeof(uint32_t);
uint32_t size = le32(self+offset);
offset+=sizeof(uint32_t);
uint64_t unknown = le64(self+offset); // 0;1
offset+=sizeof(uint64_t);
printf("--- CONTROL INFORMATION ---\n");
printf("Type 0x%08x\n",type);
printf("Size 0x%08x\n",size);
printf("Unknown 0x%016lx\n",unknown);
}
void readself(){
printf("\nReading...\n");
u32 offset=0;
u32 magic = be32(self); /* 53434500 = SCE\0 */
offset += sizeof(u32);
u32 version = le32(self+offset); /* header version 3*/
offset += sizeof(u32);
u16 sdk_type = le16(self+offset); /* SDK type */
offset += sizeof(u16);
u16 header_type = le16(self+offset); /* 1 self, 2 unknown, 3 pkg */
offset += sizeof(u16);
u32 metadata_offset = le32(self+offset); /* metadata offset */
offset += sizeof(u32);
u64 header_len = le64(self+offset); /* self header length */
offset += sizeof(u64);
u64 elf_filesize = le64(self+offset); /* ELF file length */
offset += sizeof(u64);
u64 self_filesize = le64(self+offset); /* SELF file length */
offset += sizeof(u64);
u64 unknown1 = le64(self+offset); /* UNKNOWN */
offset += sizeof(u64);
u64 self_offset = le64(self+offset); /* Self Offset */
offset += sizeof(u64);
u64 appinfo_offset = le64(self+offset); /* app info offset */
offset += sizeof(u64);
u64 elf_offset = le64(self+offset); /* ELF #1 offset */
offset += sizeof(u64);
u64 phdr_offset = le64(self+offset); /* program header offset */
offset += sizeof(u64);
u64 shdr_offset = le64(self+offset); /* section header offset */
offset += sizeof(u64);
u64 section_info_offset = le64(self+offset); /* section info offset */
offset += sizeof(u64);
u64 sceversion_offset = le64(self+offset); /* version offset */
offset += sizeof(u64);
u64 controlinfo_offset = le64(self+offset); /* control info offset */
offset += sizeof(u64);
u64 controlinfo_size = le64(self+offset); /* control info size */
offset += sizeof(u64);
if(magic!=HDR)
fail("\nERROR! Not a PlayStation Vita Self File (Magic: %08x)",magic);
if(header_type!=1){
char* HType;
if(header_type==2)
HType = "rvk";
else if(header_type==3)
HType = "pkg";
else if(header_type==4)
HType = "spp";
else
HType = "Unknown";
fail("\nERROR! Not a PlayStation Vita Self File (Type : %08x)\n"
" [%s]",header_type,HType);
}
printf("Magic 0x%08x\n",magic);
printf("Version 0x%08x\n",version);
printf("SDK Type 0x%08x\n",sdk_type);
printf("Header Type 0x%08x\n",header_type);
printf("Metadata offset 0x%08x\n",metadata_offset);
printf("Header Length 0x%016lx (%lu Bytes)\n",header_len,header_len);
printf("Elf Size 0x%016lx (%lu Bytes)\n",elf_filesize,elf_filesize);
printf("Self Size 0x%016lx (%lu Bytes)\n",self_filesize,self_filesize);
printf("Unknown_1 0x%016lx\n",unknown1);
printf("Self Offset 0x%016lx\n",self_offset);
printf("Application Info Offset 0x%016lx\n",appinfo_offset);
printf("Elf Offset 0x%016lx\n",elf_offset);
printf("Program hdr Offset 0x%016lx\n",phdr_offset);
printf("Section hdr Offset 0x%016lx\n",shdr_offset);
printf("Section Info Offset 0x%016lx\n",section_info_offset);
printf("Version Offset 0x%016lx\n",sceversion_offset);
printf("Control Info Offset 0x%016lx\n",controlinfo_offset);
printf("Control Info Size 0x%016lx (%lu Bytes)\n",controlinfo_size,controlinfo_size);
app_info(appinfo_offset);
elf(elf_offset);
program_hdr(phdr_offset);
section_hdr(shdr_offset);
sce_version(sceversion_offset);
control_information(controlinfo_offset);
printf("\nDone\n");
}
int main(int argc, char *argv[]){
if (argc == 2) {
self = mmap_file(argv[1]);
printf( "readself - v0.1 By deroad\n\n");
readself();
}else {
fail("usage: %s file.self"
,argv[0]);
}
return 0;
}