Only use Ehdr and Phdr from SELF header (#581)

segment_info in the SELF header contains offsets to segments. It is a
coincidence of Vitasdk that the first segment also contains the ELF
header and program headers. The second ELF header and program headers
may precede the first segment or may not be present at all.
This commit is contained in:
cuevavirus 2020-09-25 13:50:22 -04:00 committed by GitHub
parent 45069ba9da
commit 3d7ebe61e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 14 deletions

View File

@ -31,7 +31,7 @@ struct archive *archive_fd = NULL;
static int need_password = 0;
static char password[128];
int checkForUnsafeImports(void *buffer);
int checkForUnsafeImports(const Elf32_Ehdr *ehdr, const Elf32_Phdr *phdr, void *buffer);
char *uncompressBuffer(const Elf32_Ehdr *ehdr, const Elf32_Phdr *phdr, const segment_info *segment,
const char *buffer);
@ -448,7 +448,7 @@ int archiveCheckFilesForUnsafeFself() {
uint64_t phdr_offset = *(uint64_t *)(sce_header + 0x44);
uint64_t section_info_offset = *(uint64_t *)(sce_header + 0x54);
// jump to elf1
// jump to ehdr
// Until here we have read 0x88 bytes
int i;
for (i = 0; i < elf1_offset - 0x88; i += sizeof(uint32_t)) {
@ -461,24 +461,24 @@ int archiveCheckFilesForUnsafeFself() {
if (buffer) {
archive_read_data(archive, buffer, stat->st_size);
Elf32_Ehdr *elf1 = (Elf32_Ehdr*)buffer;
Elf32_Ehdr *ehdr = (Elf32_Ehdr*)buffer;
Elf32_Phdr *phdr = (Elf32_Phdr*)(buffer + phdr_offset - elf1_offset);
segment_info *info = (segment_info*)(buffer + section_info_offset - elf1_offset);
// segment is elf2 section
// segment is a pointer to the first segment
char *segment = buffer + info->offset - elf1_offset;
// zlib compress magic
char *uncompressed_buffer = NULL;
if (segment[0] == 0x78) {
// uncompressedBuffer will return elf2 section
uncompressed_buffer = uncompressBuffer(elf1, phdr, info, segment);
// uncompressedBuffer will return uncompressed segments
uncompressed_buffer = uncompressBuffer(ehdr, phdr, info, segment);
if (uncompressed_buffer) {
segment = uncompressed_buffer;
}
}
int unsafe = checkForUnsafeImports(segment);
int unsafe = checkForUnsafeImports(ehdr, phdr, segment);
if (uncompressed_buffer)
free(uncompressed_buffer);

10
elf.c
View File

@ -94,10 +94,7 @@ void convertToImportsTable3xx(SceImportsTable2xx *import_2xx, SceImportsTable3xx
}
}
int checkForUnsafeImports(void *buffer) {
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)buffer;
Elf32_Phdr *phdr = (Elf32_Phdr *)((uint32_t)buffer + ehdr->e_phoff);
int checkForUnsafeImports(const Elf32_Ehdr *ehdr, const Elf32_Phdr *phdr, void *buffer) {
if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
@ -108,7 +105,10 @@ int checkForUnsafeImports(void *buffer) {
uint32_t segment = ehdr->e_entry >> 30;
uint32_t offset = ehdr->e_entry & 0x3FFFFFFF;
uint32_t text_addr = (uint32_t)buffer + phdr[segment].p_offset;
uint32_t text_addr = (uint32_t)buffer;
for (int i = 0; i < segment; i++) {
text_addr += phdr[segment].p_filesz;
}
SceModuleInfo *mod_info = (SceModuleInfo *)(text_addr + offset);