Skip to content

Instantly share code, notes, and snippets.

@yifanlu
Last active May 21, 2017 19:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yifanlu/2995526667a2456ffabc0e7814c892fa to your computer and use it in GitHub Desktop.
Save yifanlu/2995526667a2456ffabc0e7814c892fa to your computer and use it in GitHub Desktop.
Extract psp2swu.self from PUP
#include <kernel/iofilemgr.h>
#include <stdint.h>
int extract(const char *pup, const char *psp2swu) {
int inf, outf;
if ((inf = sceIoOpen(pup, SCE_O_RDONLY, 0)) < 0) {
return -1;
}
if ((outf = sceIoOpen(psp2swu, SCE_O_CREAT | SCE_O_WRONLY | SCE_O_TRUNC, 6)) < 0) {
return -1;
}
int ret = -1;
int count;
if (sceIoLseek(inf, 0x18, SCE_SEEK_SET) < 0) {
goto end;
}
if (sceIoRead(inf, &count, 4) < 4) {
goto end;
}
if (sceIoLseek(inf, 0x80, SCE_SEEK_SET) < 0) {
goto end;
}
struct {
uint64_t id;
uint64_t off;
uint64_t len;
uint64_t field_18;
} __attribute__((packed)) file_entry;
for (int i = 0; i < count; i++) {
if (sceIoRead(inf, &file_entry, sizeof(file_entry)) < sizeof(file_entry)) {
goto end;
}
if (file_entry.id == 0x200) {
break;
}
}
if (file_entry.id == 0x200) {
char buffer[1024];
int rd;
if (sceIoLseek(inf, file_entry.off, SCE_SEEK_SET) < 0) {
goto end;
}
while (file_entry.len && (rd = sceIoRead(inf, buffer, sizeof(buffer))) > 0) {
if (rd > file_entry.len) {
rd = file_entry.len;
}
sceIoWrite(outf, buffer, rd);
file_entry.len -= rd;
}
if (file_entry.len == 0) {
ret = 0;
}
}
end:
sceIoClose(inf);
sceIoClose(outf);
return ret;
}
int main(int argc, const char *argv[]){
extract(argv[1], argv[2]);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment