From 3d7ebe61e6d832b2b83242949b190d4fb9ca84a1 Mon Sep 17 00:00:00 2001 From: cuevavirus <53134627+cuevavirus@users.noreply.github.com> Date: Fri, 25 Sep 2020 13:50:22 -0400 Subject: [PATCH] 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. --- archive.c | 18 +++++++++--------- elf.c | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/archive.c b/archive.c index af17d24..61ec575 100644 --- a/archive.c +++ b/archive.c @@ -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); diff --git a/elf.c b/elf.c index 2d6ee67..3b85506 100644 --- a/elf.c +++ b/elf.c @@ -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);