mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-05 14:37:08 +00:00
elf: handle decompress flag for 32 bit elfs
This commit is contained in:
parent
b3a933ba84
commit
095d02e41b
3 changed files with 83 additions and 108 deletions
|
|
@ -1274,115 +1274,13 @@ fs::file SELFDecrypter::MakeElf(bool isElf32)
|
|||
// Create a new ELF file.
|
||||
fs::file e = fs::make_stream<std::vector<u8>>();
|
||||
|
||||
// Set initial offset.
|
||||
u32 data_buf_offset = 0;
|
||||
|
||||
if (isElf32)
|
||||
{
|
||||
// Write ELF header.
|
||||
WriteEhdr(e, elf32_hdr);
|
||||
|
||||
// Write program headers.
|
||||
for (u32 i = 0; i < elf32_hdr.e_phnum; ++i)
|
||||
{
|
||||
WritePhdr(e, phdr32_arr[i]);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < meta_hdr.section_count; i++)
|
||||
{
|
||||
// PHDR type.
|
||||
if (meta_shdr[i].type == 2)
|
||||
{
|
||||
// Seek to the program header data offset and write the data.
|
||||
e.seek(phdr32_arr[meta_shdr[i].program_idx].p_offset);
|
||||
e.write(data_buf.get() + data_buf_offset, meta_shdr[i].data_size);
|
||||
|
||||
// Advance the data buffer offset by data size.
|
||||
data_buf_offset += meta_shdr[i].data_size;
|
||||
}
|
||||
}
|
||||
|
||||
// Write section headers.
|
||||
if (self_hdr.se_shdroff != 0)
|
||||
{
|
||||
e.seek(elf32_hdr.e_shoff);
|
||||
|
||||
for (u32 i = 0; i < elf32_hdr.e_shnum; ++i)
|
||||
{
|
||||
WriteShdr(e, shdr32_arr[i]);
|
||||
}
|
||||
}
|
||||
WriteElf(e, elf32_hdr, shdr32_arr, phdr32_arr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write ELF header.
|
||||
WriteEhdr(e, elf64_hdr);
|
||||
|
||||
// Write program headers.
|
||||
for (u32 i = 0; i < elf64_hdr.e_phnum; ++i)
|
||||
{
|
||||
WritePhdr(e, phdr64_arr[i]);
|
||||
}
|
||||
|
||||
// Write data.
|
||||
for (unsigned int i = 0; i < meta_hdr.section_count; i++)
|
||||
{
|
||||
// PHDR type.
|
||||
if (meta_shdr[i].type == 2)
|
||||
{
|
||||
// Decompress if necessary.
|
||||
if (meta_shdr[i].compressed == 2)
|
||||
{
|
||||
// Store the length in writeable memory space.
|
||||
std::unique_ptr<uLongf> decomp_buf_length(new uLongf);
|
||||
memcpy(decomp_buf_length.get(), &phdr64_arr[meta_shdr[i].program_idx].p_filesz, sizeof(uLongf));
|
||||
|
||||
/// Create a pointer to a buffer for decompression.
|
||||
std::unique_ptr<u8[]> decomp_buf(new u8[phdr64_arr[meta_shdr[i].program_idx].p_filesz]);
|
||||
|
||||
// Create a buffer separate from data_buf to uncompress.
|
||||
std::unique_ptr<u8[]> zlib_buf(new u8[data_buf_length]);
|
||||
memcpy(zlib_buf.get(), data_buf.get(), data_buf_length);
|
||||
|
||||
// Use zlib uncompress on the new buffer.
|
||||
// decomp_buf_length changes inside the call to uncompress, so it must be a pointer to correct type (in writeable mem space).
|
||||
int rv = uncompress(decomp_buf.get(), decomp_buf_length.get(), zlib_buf.get() + data_buf_offset, data_buf_length);
|
||||
|
||||
// Check for errors (TODO: Probably safe to remove this once these changes have passed testing.)
|
||||
switch (rv)
|
||||
{
|
||||
case Z_MEM_ERROR: LOG_ERROR(LOADER, "MakeELF encountered a Z_MEM_ERROR!"); break;
|
||||
case Z_BUF_ERROR: LOG_ERROR(LOADER, "MakeELF encountered a Z_BUF_ERROR!"); break;
|
||||
case Z_DATA_ERROR: LOG_ERROR(LOADER, "MakeELF encountered a Z_DATA_ERROR!"); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Seek to the program header data offset and write the data.
|
||||
e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset);
|
||||
e.write(decomp_buf.get(), phdr64_arr[meta_shdr[i].program_idx].p_filesz);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Seek to the program header data offset and write the data.
|
||||
e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset);
|
||||
e.write(data_buf.get() + data_buf_offset, meta_shdr[i].data_size);
|
||||
}
|
||||
|
||||
// Advance the data buffer offset by data size.
|
||||
data_buf_offset += meta_shdr[i].data_size;
|
||||
}
|
||||
}
|
||||
|
||||
// Write section headers.
|
||||
if (self_hdr.se_shdroff != 0)
|
||||
{
|
||||
e.seek(elf64_hdr.e_shoff);
|
||||
|
||||
for (u32 i = 0; i < elf64_hdr.e_shnum; ++i)
|
||||
{
|
||||
WriteShdr(e, shdr64_arr[i]);
|
||||
}
|
||||
}
|
||||
WriteElf(e, elf64_hdr, shdr64_arr, phdr64_arr);
|
||||
}
|
||||
|
||||
return e;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue