diff --git a/Il2CppInspector.Common/FileFormatReaders/FSELFReader.cs b/Il2CppInspector.Common/FileFormatReaders/FSELFReader.cs new file mode 100644 index 0000000..96a972a --- /dev/null +++ b/Il2CppInspector.Common/FileFormatReaders/FSELFReader.cs @@ -0,0 +1,84 @@ +/* + Copyright 2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com + + All rights reserved. +*/ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; + +namespace Il2CppInspector +{ + // Sony PlayStation 4 fake signed ELF reader + // Not compatible with PlayStation 3, PSP or Vita + // References: + // http://hitmen.c02.at/files/yapspd/psp_doc/chap26.html + // https://www.psdevwiki.com/ps3/SELF_-_SPRX#File_Format + // https://www.psdevwiki.com/ps4/SELF_File_Format + // https://www.psxhax.com/threads/ps4-self-spkg-file-format-documentation-detailed-for-scene-devs.6636/ + // https://wiki.henkaku.xyz/vita/images/a/a2/Vita_SDK_specifications.pdf + internal class FSELFReader : FileFormatReader + { + public FSELFReader(Stream stream) : base(stream) { } + + public override string Format => "FSELF"; + + public override string Arch => "x64"; + + public override int Bits => 64; + + protected override bool Init() { + var fselfHeader = ReadObject(); + + // Check for magic bytes + if ((FSELFConsts) fselfHeader.Magic != FSELFConsts.Magic) + return false; + + if ((FSELFConsts) fselfHeader.Unk4 != FSELFConsts.Unk4) + return false; + + // Read segments + var segments = ReadArray(fselfHeader.NumberOfSegments); + + // Read ELF header + // PS4 files as follows: + // m_arch = 0x2 (64-bit) + // m_endian = 0x1 (little endian) + // m_version = 0x1 (ELF version 1) + // m_osabi = 0x9 (FreeBSD) + // e_type = special type, see psdevwiki documentation; probably 0xFE10 or 0xFE18 + // e_machine = 0x3E (x86-64) + var startOfElf = Position; + var elfHeader = ReadObject>(); + + // There are no sections, but read all the program headers + var program_header_table = ReadArray(startOfElf + (long) elfHeader.e_phoff, elfHeader.e_phnum); + + // Read the special section + var sceSpecial = ReadObject(); + + // TODO: Implement the rest of FSELF + // TODO: Set GlobalOffset + + throw new NotImplementedException("Il2CppInspector does not have PRX support yet"); + + return true; + } + + public override Dictionary GetSymbolTable() { + throw new NotImplementedException(); + } + + public override uint[] GetFunctionTable() { + throw new NotImplementedException(); + } + + public override uint MapVATR(ulong uiAddr) { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Il2CppInspector.Common/FileFormatReaders/FormatLayouts/FSELF.cs b/Il2CppInspector.Common/FileFormatReaders/FormatLayouts/FSELF.cs new file mode 100644 index 0000000..13c2fb1 --- /dev/null +++ b/Il2CppInspector.Common/FileFormatReaders/FormatLayouts/FSELF.cs @@ -0,0 +1,83 @@ +/* + Copyright 2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com + + All rights reserved. +*/ + +using System; +using NoisyCowStudios.Bin2Object; + +namespace Il2CppInspector +{ + internal enum FSELFConsts : uint + { + Magic = 0x1D3D154F, + Unk4 = 0x12010100 + } + + [Flags] + internal enum FSELFSegmentFlags + { + Ordered = 0x1, + Encrypted = 0x2, + Signed = 0x4, + Deflated = 0x8, + Blocked = 0x800 + } + + // SCE-specific definitions for e_type + internal enum FSELFTypes : ushort + { + ET_SCE_EXEC = 0xFE00, + ET_SCE_RELEXEC = 0xFE04, + ET_SCE_STUBLIB = 0xFE0C, + ET_SCE_DYNEXEC = 0xFE10, // SCE EXEC_ASLR (PS4 Executable with ASLR) + ET_SCE_DYNAMIC = 0xFE18, + ET_SCE_IOPRELEXEC = 0xFF80, + ET_SCE_IOPRELEXEC2 = 0xFF81, + ET_SCE_EERELEXEC = 0xFF90, + ET_SCE_EERELEXEC2 = 0xFF91, + ET_SCE_PSPRELEXEC = 0xFFA0, + ET_SCE_PPURELEXEC = 0xFFA4, + ET_SCE_ARMRELEXEC = 0xFFA5, + ET_SCE_PSPOVERLAY = 0xFFA8 + } + +#pragma warning disable CS0649 + internal class FSELFHeader + { + public uint Magic; + public uint Unk4; + public byte ContentType; + public byte ProductType; + public ushort Padding1; + public ushort HeaderSize; + public ushort MetadataSize; + public uint SELFSize; + public uint Padding2; + public ushort NumberOfSegments; + public ushort Unk2; + public uint Padding3; + } + + internal class FSELFSegment + { + public ulong Flags; + public ulong FileOffset; + public ulong EncryptedCompressedSize; + public ulong MemorySize; + } + + internal class FSELFSCE + { + public ulong AuthID; + public ulong ProductType; + public ulong Version_1; + public ulong Version_2; + [ArrayLength(FixedSize = 0x20)] + public byte[] ContentID; // Only if NPDRM + [ArrayLength(FixedSize = 0x20)] + public byte[] SHA256Sum; + } +#pragma warning restore CS0649 +}