Last active
November 15, 2023 10:01
-
-
Save Kethen/a95a0a825cf9d14e7cd8d30c0ad3e2fc to your computer and use it in GitHub Desktop.
sony psp param.sfo dumper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdint.h> | |
#define CONV_LE(addr, dest) { \ | |
dest = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24; \ | |
} | |
#define CONV_LE16(addr, dest) { \ | |
dest = addr[0] | addr[1] << 8; \ | |
} | |
int main(int argc, char **argv){ | |
if(argc != 2){ | |
printf("this program takes exactly one argument, path to param.sfo\n"); | |
exit(1); | |
} | |
int fd = open(argv[1], O_RDONLY); | |
if(fd <= 0){ | |
printf("cannot open %s for reading\n", argv[1]); | |
} | |
lseek(fd, 0x08, SEEK_SET); | |
unsigned char buf[4]; | |
if(read(fd, &buf, 4) != 4){ | |
close(fd); | |
printf("failed reading key table start from sfo\n"); | |
return -1; | |
} | |
uint32_t key_table_start = 0; | |
CONV_LE(buf, key_table_start); | |
printf("key_table_start is %ld\n", key_table_start); | |
if(read(fd, &buf, 4) != 4){ | |
close(fd); | |
printf("failed reading data table start from sfo\n"); | |
return -1; | |
} | |
uint32_t data_table_start = 0; | |
CONV_LE(buf, data_table_start); | |
printf("data_table_start is %ld\n", data_table_start); | |
if(read(fd, &buf, 4) != 4){ | |
close(fd); | |
printf("failed reading tables entries from sfo\n"); | |
return -1; | |
} | |
uint32_t tables_entries = 0; | |
CONV_LE(buf, tables_entries); | |
printf("tables_entries is %ld\n", tables_entries); | |
int i; | |
for(i = 0;i < tables_entries;i++){ | |
lseek(fd, 0x14 + i * 0x10, SEEK_SET); | |
if(read(fd, &buf, 2) != 2){ | |
close(fd); | |
printf("failed reading key offset from sfo\n"); | |
return -1; | |
} | |
uint32_t key_offset = 0; | |
CONV_LE16(buf, key_offset); | |
if(read(fd, &buf, 2) != 2){ | |
close(fd); | |
printf("failed reading data format from sfo\n"); | |
return -1; | |
} | |
uint32_t data_format = 0; | |
CONV_LE16(buf, data_format); | |
if(read(fd, &buf, 4) != 4){ | |
close(fd); | |
printf("failed reading data len from sfo\n"); | |
return -1; | |
} | |
uint32_t data_len = 0; | |
CONV_LE(buf, data_len); | |
lseek(fd, 4, SEEK_CUR); | |
if(read(fd, &buf, 4) != 4){ | |
close(fd); | |
printf("failed reading data offset from sfo\n"); | |
return -1; | |
} | |
uint32_t data_offset = 0; | |
CONV_LE(buf, data_offset); | |
lseek(fd, key_offset + key_table_start, SEEK_SET); | |
char keybuf[50]; | |
int j; | |
for(j = 0;j < 50;j++){ | |
if(read(fd, &keybuf[j], 1) != 1){ | |
close(fd); | |
printf("failed reading key from sfo\n"); | |
} | |
if(keybuf[j] == 0){ | |
break; | |
} | |
} | |
printf("key is %s\n", keybuf); | |
lseek(fd, data_offset + data_table_start, SEEK_SET); | |
char databuf[data_len]; | |
for(j = 0;j < data_len; j++){ | |
if(read(fd, &databuf[j], 1) != 1){ | |
close(fd); | |
printf("failed reading data from sfo\n"); | |
} | |
} | |
if(data_format == 0x0204){ | |
printf("utf8 data: %s\n", databuf); | |
}else{ | |
printf("hex data: "); | |
int j; | |
for(j = 0;j < data_len; j++){ | |
if(j != 0 && j % 16 == 0){ | |
printf("| "); | |
} | |
printf("0x%02x ", (uint8_t)databuf[j]); | |
} | |
printf("\n"); | |
} | |
} | |
close(fd); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment