Compare commits

...

10 Commits

Author SHA1 Message Date
Ani 4bfe3668f0 Merge branch 'master' into master 2018-02-09 12:34:50 +00:00
Francisco José García García 74a175401a Merge branch 'master' into master 2018-01-26 11:26:38 +01:00
Francisco José García García 609c25f3e4 Merge branch 'master' into master 2018-01-18 11:33:22 +01:00
Francisco José García García dc1cb2a7bc Merge branch 'master' into master 2018-01-16 08:37:31 +01:00
Francisco José García García 3cbb0262c9 Style nits 2018-01-14 18:17:46 +01:00
Francisco José García García a1688e342c Style nits 2018-01-14 17:45:52 +01:00
Francisco José García García dbd7c70ffd Merge branch 'master' into master 2018-01-11 11:45:26 +01:00
ggf906 97c6d8407a Fix elf64 unself and style nits 2018-01-05 12:25:58 +01:00
ggf906 e66005149a Fix for Official SDK and short relocs 2018-01-05 12:25:57 +01:00
ggf906 b12a2f7ea5 PSP2: Fix vitasdk homebrew loading 2018-01-05 12:25:56 +01:00
4 changed files with 1260 additions and 638 deletions
+351 -36
View File
@@ -148,20 +148,40 @@ void WriteEhdr(const fs::file& f, Elf32_Ehdr& ehdr)
Write8(f, ehdr.e_data);
Write8(f, ehdr.e_curver);
Write8(f, ehdr.e_os_abi);
Write64(f, ehdr.e_abi_ver);
Write16(f, ehdr.e_type);
Write16(f, ehdr.e_machine);
Write32(f, ehdr.e_version);
Write32(f, ehdr.e_entry);
Write32(f, ehdr.e_phoff);
Write32(f, ehdr.e_shoff);
Write32(f, ehdr.e_flags);
Write16(f, ehdr.e_ehsize);
Write16(f, ehdr.e_phentsize);
Write16(f, ehdr.e_phnum);
Write16(f, ehdr.e_shentsize);
Write16(f, ehdr.e_shnum);
Write16(f, ehdr.e_shstrndx);
if (ehdr.e_data == 1)
{
Write64LE(f, ehdr.e_abi_ver);
Write16LE(f, ehdr.e_type);
Write16LE(f, ehdr.e_machine);
Write32LE(f, ehdr.e_version);
Write32LE(f, ehdr.e_entry);
Write32LE(f, ehdr.e_phoff);
Write32LE(f, ehdr.e_shoff);
Write32LE(f, ehdr.e_flags);
Write16LE(f, ehdr.e_ehsize);
Write16LE(f, ehdr.e_phentsize);
Write16LE(f, ehdr.e_phnum);
Write16LE(f, ehdr.e_shentsize);
Write16LE(f, ehdr.e_shnum);
Write16LE(f, ehdr.e_shstrndx);
}
else
{
Write64(f, ehdr.e_abi_ver);
Write16(f, ehdr.e_type);
Write16(f, ehdr.e_machine);
Write32(f, ehdr.e_version);
Write32(f, ehdr.e_entry);
Write32(f, ehdr.e_phoff);
Write32(f, ehdr.e_shoff);
Write32(f, ehdr.e_flags);
Write16(f, ehdr.e_ehsize);
Write16(f, ehdr.e_phentsize);
Write16(f, ehdr.e_phnum);
Write16(f, ehdr.e_shentsize);
Write16(f, ehdr.e_shnum);
Write16(f, ehdr.e_shstrndx);
}
}
void WritePhdr(const fs::file& f, Elf32_Phdr& phdr)
@@ -190,6 +210,32 @@ void WriteShdr(const fs::file& f, Elf32_Shdr& shdr)
Write32(f, shdr.sh_entsize);
}
void WritePhdrLE(const fs::file& f, Elf32_Phdr& phdr)
{
Write32LE(f, phdr.p_type);
Write32LE(f, phdr.p_offset);
Write32LE(f, phdr.p_vaddr);
Write32LE(f, phdr.p_paddr);
Write32LE(f, phdr.p_filesz);
Write32LE(f, phdr.p_memsz);
Write32LE(f, phdr.p_flags);
Write32LE(f, phdr.p_align);
}
void WriteShdrLE(const fs::file& f, Elf32_Shdr& shdr)
{
Write32LE(f, shdr.sh_name);
Write32LE(f, shdr.sh_type);
Write32LE(f, shdr.sh_flags);
Write32LE(f, shdr.sh_addr);
Write32LE(f, shdr.sh_offset);
Write32LE(f, shdr.sh_size);
Write32LE(f, shdr.sh_link);
Write32LE(f, shdr.sh_info);
Write32LE(f, shdr.sh_addralign);
Write32LE(f, shdr.sh_entsize);
}
void AppInfo::Load(const fs::file& f)
{
@@ -200,6 +246,15 @@ void AppInfo::Load(const fs::file& f)
padding = Read64(f);
}
void AppInfo::LoadLE(const fs::file& f)
{
authid = Read64LE(f);
vendor_id = Read32LE(f);
self_type = Read32LE(f);
version = Read64(f);
padding = Read64(f);
}
void AppInfo::Show()
{
LOG_NOTICE(LOADER, "AuthID: 0x%llx", authid);
@@ -218,6 +273,16 @@ void SectionInfo::Load(const fs::file& f)
encrypted = Read32(f);
}
void SectionInfo::LoadLE(const fs::file& f)
{
offset = Read64LE(f);
size = Read64LE(f);
compressed = Read32LE(f);
unknown1 = Read32LE(f);
unknown2 = Read32LE(f);
encrypted = Read32LE(f);
}
void SectionInfo::Show()
{
LOG_NOTICE(LOADER, "Offset: 0x%llx", offset);
@@ -236,6 +301,14 @@ void SCEVersionInfo::Load(const fs::file& f)
unknown = Read32(f);
}
void SCEVersionInfo::LoadLE(const fs::file& f)
{
subheader_type = Read32LE(f);
present = Read32LE(f);
size = Read32LE(f);
unknown = Read32LE(f);
}
void SCEVersionInfo::Show()
{
LOG_NOTICE(LOADER, "Sub-header type: 0x%08x", subheader_type);
@@ -290,6 +363,65 @@ void ControlInfo::Load(const fs::file& f)
}
}
void ControlInfo::LoadLE(const fs::file& f)
{
type = Read32LE(f);
size = Read32LE(f);
next = Read64LE(f);
if (type == 1)
{
control_flags.ctrl_flag1 = Read32LE(f);
control_flags.unknown1 = Read32LE(f);
control_flags.unknown2 = Read32LE(f);
control_flags.unknown3 = Read32LE(f);
control_flags.unknown4 = Read32LE(f);
control_flags.unknown5 = Read32LE(f);
control_flags.unknown6 = Read32LE(f);
control_flags.unknown7 = Read32LE(f);
}
else if (type == 2)
{
if (size == 0x30)
{
f.read(file_digest_30.digest, 20);
file_digest_30.unknown = Read64LE(f);
}
else if (size == 0x40)
{
f.read(file_digest_40.digest1, 20);
f.read(file_digest_40.digest2, 20);
file_digest_40.unknown = Read64LE(f);
}
}
else if (type == 3)
{
npdrm.magic = Read32LE(f);
npdrm.unknown1 = Read32LE(f);
npdrm.license = Read32LE(f);
npdrm.type = Read32LE(f);
f.read(npdrm.content_id, 48);
f.read(npdrm.digest, 16);
f.read(npdrm.invdigest, 16);
f.read(npdrm.xordigest, 16);
npdrm.unknown2 = Read64LE(f);
npdrm.unknown3 = Read64LE(f);
}
else if (type == 5)
{
f.read(type5.unk, 0x100);
}
else if (type == 6)
{
type6.unknown1 = Read32LE(f);
f.read(type6.unk, 0xFC);
}
else if (type == 7)
{
f.read(type7.unk, 0x40);
}
}
void ControlInfo::Show()
{
LOG_NOTICE(LOADER, "Type: 0x%08x", type);
@@ -634,6 +766,19 @@ void SceHeader::Load(const fs::file& f)
se_esize = Read64(f);
}
void SceHeader::LoadLE(const fs::file& f)
{
se_magic = Read32(f);
se_hver = Read32LE(f);
se_flags = Read16LE(f);
se_type = Read16LE(f);
se_meta = Read32LE(f);
se_hsize = Read64LE(f);
se_esize = Read64LE(f);
Read64LE(f);
Read64LE(f);
}
void SelfHeader::Load(const fs::file& f)
{
se_htype = Read64(f);
@@ -648,6 +793,11 @@ void SelfHeader::Load(const fs::file& f)
pad = Read64(f);
}
void SelfHeader::LoadLE(const fs::file& f)
{
f.read(this, sizeof(*this));
}
SCEDecrypter::SCEDecrypter(const fs::file& s)
: sce_f(s)
, data_buf_length(0)
@@ -885,11 +1035,22 @@ SELFDecrypter::SELFDecrypter(const fs::file& s)
{
}
static bool isVita(const SceHeader hdr)
{
return (hdr.se_hver == 3);
}
bool SELFDecrypter::LoadHeaders(bool isElf32)
{
// Read SCE header.
self_f.seek(0);
sce_hdr.Load(self_f);
sce_hdr.LoadLE(self_f);
if (!isVita(sce_hdr))
{
self_f.seek(0);
sce_hdr.Load(self_f);
}
// Check SCE magic.
if (!sce_hdr.CheckMagic())
@@ -899,11 +1060,26 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
}
// Read SELF header.
self_hdr.Load(self_f);
if (!isVita(sce_hdr))
{
self_hdr.Load(self_f);
}
else
{
self_hdr.LoadLE(self_f);
}
// Read the APP INFO.
self_f.seek(self_hdr.se_appinfooff);
app_info.Load(self_f);
if (!isVita(sce_hdr))
{
app_info.Load(self_f);
}
else
{
app_info.LoadLE(self_f);
}
// Read ELF header.
self_f.seek(self_hdr.se_elfoff);
@@ -926,7 +1102,14 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
for(u32 i = 0; i < elf32_hdr.e_phnum; ++i)
{
phdr32_arr.emplace_back();
phdr32_arr.back().Load(self_f);
if (!isVita(sce_hdr))
{
phdr32_arr.back().Load(self_f);
}
else
{
phdr32_arr.back().LoadLE(self_f);
}
}
}
else
@@ -956,12 +1139,26 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
for(u32 i = 0; i < ((isElf32) ? elf32_hdr.e_phnum : elf64_hdr.e_phnum); ++i)
{
secinfo_arr.emplace_back();
secinfo_arr.back().Load(self_f);
if (!isVita(sce_hdr))
{
secinfo_arr.back().Load(self_f);
}
else
{
secinfo_arr.back().LoadLE(self_f);
}
}
// Read SCE version info.
self_f.seek(self_hdr.se_sceveroff);
scev_info.Load(self_f);
if (!isVita(sce_hdr))
{
scev_info.Load(self_f);
}
else
{
scev_info.LoadLE(self_f);
}
// Read control info.
ctrlinfo_arr.clear();
@@ -972,7 +1169,14 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
{
ctrlinfo_arr.emplace_back();
ControlInfo &cinfo = ctrlinfo_arr.back();
cinfo.Load(self_f);
if (!isVita(sce_hdr))
{
cinfo.Load(self_f);
}
else
{
cinfo.LoadLE(self_f);
}
i += cinfo.size;
}
@@ -992,7 +1196,14 @@ bool SELFDecrypter::LoadHeaders(bool isElf32)
for(u32 i = 0; i < elf32_hdr.e_shnum; ++i)
{
shdr32_arr.emplace_back();
shdr32_arr.back().Load(self_f);
if (!isVita(sce_hdr))
{
shdr32_arr.back().Load(self_f);
}
else
{
shdr32_arr.back().LoadLE(self_f);
}
}
}
else
@@ -1157,6 +1368,8 @@ bool SELFDecrypter::LoadMetadata(u8* klic_key)
memcpy(metadata_iv, keyset.riv, 0x10);
// Check DEBUG flag.
if (sce_hdr.se_flags == 0x00c0)
return true;
if ((sce_hdr.se_flags & 0x8000) != 0x8000)
{
// Decrypt the NPDRM layer.
@@ -1219,6 +1432,14 @@ bool SELFDecrypter::DecryptData()
}
}
if (meta_hdr.section_count == 0)
{
for (unsigned int i = 0; i < secinfo_arr.size(); i++)
{
data_buf_length += secinfo_arr[i].size;
}
}
// Allocate a buffer to store decrypted data.
data_buf = std::make_unique<u8[]>(data_buf_length);
@@ -1266,6 +1487,16 @@ bool SELFDecrypter::DecryptData()
}
}
if (meta_hdr.section_count == 0)
{
for (unsigned int i = 0; i < secinfo_arr.size(); i++)
{
self_f.seek(secinfo_arr[i].offset);
self_f.read(data_buf.get() + data_buf_offset, secinfo_arr[i].size);
data_buf_offset += secinfo_arr[i].size;
}
}
return true;
}
@@ -1285,20 +1516,75 @@ fs::file SELFDecrypter::MakeElf(bool isElf32)
// Write program headers.
for (u32 i = 0; i < elf32_hdr.e_phnum; ++i)
{
WritePhdr(e, phdr32_arr[i]);
if (elf32_hdr.e_data == 1)
{
WritePhdrLE(e, phdr32_arr[i]);
}
else
{
WritePhdr(e, phdr32_arr[i]);
}
}
for (unsigned int i = 0; i < meta_hdr.section_count; i++)
if (meta_hdr.section_count != 0)
{
// PHDR type.
if (meta_shdr[i].type == 2)
for (unsigned int i = 0; i < meta_hdr.section_count; i++)
{
// 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);
// 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;
}
}
}
else
{
for (unsigned int i = 0; i < phdr32_arr.size(); i++)
{
// Decompress if necessary.
if (secinfo_arr[i].compressed == 2)
{
// Store the length in writeable memory space.
std::unique_ptr<uLongf> decomp_buf_length(new uLongf);
memcpy(decomp_buf_length.get(), &phdr32_arr[i].p_filesz, sizeof(uLongf));
/// Create a pointer to a buffer for decompression.
std::unique_ptr<u8[]> decomp_buf(new u8[phdr32_arr[i].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(phdr32_arr[i].p_offset);
e.write(decomp_buf.get(), phdr32_arr[i].p_filesz);
}
else
{
// Seek to the program header data offset and write the data.
e.seek(phdr32_arr[i].p_offset);
e.write(data_buf.get() + data_buf_offset, secinfo_arr[i].size);
}
// Advance the data buffer offset by data size.
data_buf_offset += meta_shdr[i].data_size;
data_buf_offset += secinfo_arr[i].size;
}
}
@@ -1309,7 +1595,14 @@ fs::file SELFDecrypter::MakeElf(bool isElf32)
for (u32 i = 0; i < elf32_hdr.e_shnum; ++i)
{
WriteShdr(e, shdr32_arr[i]);
if (elf32_hdr.e_data == 1)
{
WriteShdrLE(e, shdr32_arr[i]);
}
else
{
WriteShdr(e, shdr32_arr[i]);
}
}
}
}
@@ -1424,8 +1717,20 @@ static bool IsSelfElf32(const fs::file& f)
SceHeader hdr;
SelfHeader sh;
hdr.Load(f);
sh.Load(f);
hdr.LoadLE(f);
if (!isVita(hdr))
{
f.seek(0);
hdr.Load(f);
sh.Load(f);
}
else
{
sh.LoadLE(f);
}
// Locate the class byte and check it.
u8 elf_class[0x8];
@@ -1451,13 +1756,23 @@ static bool CheckDebugSelf(fs::file& s)
// Check for DEBUG version.
if (key_version == 0x80 || key_version == 0xc0)
{
LOG_WARNING(LOADER, "Debug SELF detected! Removing fake header...");
s.seek(0x04);
const u16 version = s.read<le_t<u16>>();
if (version == 3)
{
return false;
}
LOG_WARNING(LOADER, "Debug SELF detected! Removing fake header...");
// Get the real elf offset.
s.seek(0x10);
const u64 realoffset = key_version == 0x80 ? +s.read<be_t<u64>>() : +s.read<le_t<u64>>();
// Start at the real elf offset.
s.seek(key_version == 0x80 ? +s.read<be_t<u64>>() : +s.read<le_t<u64>>());
s.seek(realoffset);
// Write the real ELF file back.
fs::file e = fs::make_stream<std::vector<u8>>();
@@ -1560,4 +1875,4 @@ std::array<u8, 0x10> get_default_self_klic()
std::array<u8, 0x10> key;
std::copy(std::begin(NP_KLIC_FREE), std::end(NP_KLIC_FREE), std::begin(key));
return key;
}
}
+29
View File
@@ -11,6 +11,7 @@ struct AppInfo
u64 padding;
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show();
};
@@ -24,6 +25,7 @@ struct SectionInfo
u32 encrypted;
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show();
};
@@ -35,6 +37,7 @@ struct SCEVersionInfo
u32 unknown;
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show();
};
@@ -92,9 +95,33 @@ struct ControlInfo
u64 unknown3;
} npdrm;
// type 5 0x110 bytes
struct
{
u32 pad;
u8 unk[0x100];
} type5;
// type 6 0x110 bytes
struct
{
u32 pad;
u32 unknown1;
u8 unk[0xFC];
} type6;
// type 7 0x50 bytes
struct
{
u32 pad;
u8 unk[0x40];
} type7;
};
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show();
};
@@ -317,6 +344,7 @@ struct SceHeader
u64 se_esize;
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show(){}
bool CheckMagic() const { return se_magic == 0x53434500; }
};
@@ -335,6 +363,7 @@ struct SelfHeader
u64 pad;
void Load(const fs::file& f);
void LoadLE(const fs::file& f);
void Show(){}
};
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -728,7 +728,7 @@ void Emulator::Load(bool add_only)
vm::ps3::init();
spu_load_exec(spu_exec);
}
else if (arm_exec.open(elf_file) == elf_error::ok)
else if (arm_exec.open(elf_file, 0, + elf_opt::no_sections) == elf_error::ok)
{
// ARMv7 executable
g_system = system_type::psv;