SELF: More boilerplate code
This commit is contained in:
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
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<FSELFReader>
|
|
||||||
{
|
|
||||||
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<FSELFHeader>();
|
|
||||||
|
|
||||||
// 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<FSELFSegment>(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<elf_header<ulong>>();
|
|
||||||
|
|
||||||
// There are no sections, but read all the program headers
|
|
||||||
var program_header_table = ReadArray<elf_64_phdr>(startOfElf + (long) elfHeader.e_phoff, elfHeader.e_phnum);
|
|
||||||
|
|
||||||
// Read the special section
|
|
||||||
var sceSpecial = ReadObject<FSELFSCE>();
|
|
||||||
|
|
||||||
// TODO: Implement the rest of FSELF
|
|
||||||
// TODO: Set GlobalOffset
|
|
||||||
|
|
||||||
throw new NotImplementedException("Il2CppInspector does not have PRX support yet");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Dictionary<string, ulong> GetSymbolTable() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override uint[] GetFunctionTable() {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override uint MapVATR(ulong uiAddr) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,6 +26,9 @@ namespace Il2CppInspector
|
|||||||
ELFCLASS32 = 1,
|
ELFCLASS32 = 1,
|
||||||
ELFCLASS64 = 2,
|
ELFCLASS64 = 2,
|
||||||
|
|
||||||
|
// elf_header.e_Type
|
||||||
|
ET_EXEC = 2,
|
||||||
|
|
||||||
// PHTs
|
// PHTs
|
||||||
PT_DYNAMIC = 2,
|
PT_DYNAMIC = 2,
|
||||||
DT_PLTGOT = 3,
|
DT_PLTGOT = 3,
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
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
|
|
||||||
}
|
|
||||||
117
Il2CppInspector.Common/FileFormatReaders/FormatLayouts/SElf.cs
Normal file
117
Il2CppInspector.Common/FileFormatReaders/FormatLayouts/SElf.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using NoisyCowStudios.Bin2Object;
|
||||||
|
|
||||||
|
namespace Il2CppInspector
|
||||||
|
{
|
||||||
|
internal enum SElfConsts : uint
|
||||||
|
{
|
||||||
|
Magic = 0x1D3D154F
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
internal enum SElfEntryFlags : ulong
|
||||||
|
{
|
||||||
|
Ordered = 0x1,
|
||||||
|
Encrypted = 0x2,
|
||||||
|
Signed = 0x4,
|
||||||
|
Deflated = 0x8,
|
||||||
|
WindowMask = 0x700,
|
||||||
|
Blocks = 0x800,
|
||||||
|
BlockSizeMask = 0xF000,
|
||||||
|
Digests = 0x10000,
|
||||||
|
Extents = 0x20000,
|
||||||
|
SegmentIndexMask = 0x_000F_FFF0_0000
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCE-specific definitions for e_type
|
||||||
|
internal enum SElfETypes : 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCE-specific definitions for program header type
|
||||||
|
internal enum SElfPTypes : uint
|
||||||
|
{
|
||||||
|
PT_SCE_RELA = 0x60000000,
|
||||||
|
PT_SCE_DYNLIBDATA = 0x61000000,
|
||||||
|
PT_SCE_PROCPARAM = 0x61000001,
|
||||||
|
PT_SCE_MODULE_PARAM = 0x61000002,
|
||||||
|
PT_SCE_RELRO = 0x61000010,
|
||||||
|
PT_SCE_COMMENT = 0x6FFFFF00,
|
||||||
|
PT_SCE_VERSION = 0x6FFFFF01
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extended info types
|
||||||
|
internal enum SElfExInfoTypes
|
||||||
|
{
|
||||||
|
PTYPE_FAKE = 0x1,
|
||||||
|
PTYPE_NPDRM_EXEC = 0x4,
|
||||||
|
PTYPE_NPDRM_DYNLIB = 0x5,
|
||||||
|
PTYPE_SYSTEM_EXEC = 0x8,
|
||||||
|
PTYPE_SYSTEM_DYNLIB = 0x9,
|
||||||
|
PTYPE_HOST_KERNEL = 0xC,
|
||||||
|
PTYPE_SECURE_MODULE = 0xE,
|
||||||
|
PTYPE_SECURE_KERNEL = 0xF
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
internal class SElfHeader
|
||||||
|
{
|
||||||
|
public uint Magic;
|
||||||
|
public byte Version;
|
||||||
|
public byte Mode;
|
||||||
|
public byte Endian;
|
||||||
|
public byte Attributes;
|
||||||
|
public uint KeyType;
|
||||||
|
public ushort HeaderSize;
|
||||||
|
public ushort MetadataSize;
|
||||||
|
public ulong FileSize;
|
||||||
|
public ushort NumberOfEntries;
|
||||||
|
public ushort Flags;
|
||||||
|
public uint Padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class SElfEntry
|
||||||
|
{
|
||||||
|
public ulong Flags;
|
||||||
|
public ulong FileOffset;
|
||||||
|
public ulong EncryptedCompressedSize;
|
||||||
|
public ulong MemorySize;
|
||||||
|
|
||||||
|
public bool IsEncrypted => (Flags & (ulong) SElfEntryFlags.Encrypted) != 0;
|
||||||
|
public bool IsDeflated => (Flags & (ulong) SElfEntryFlags.Deflated) != 0;
|
||||||
|
public bool HasBlocks => (Flags & (ulong) SElfEntryFlags.Blocks) != 0;
|
||||||
|
public ushort SegmentIndex => (ushort) ((Flags & (ulong) SElfEntryFlags.SegmentIndexMask) >> 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class SElfSCEData
|
||||||
|
{
|
||||||
|
public ulong ProductAuthID;
|
||||||
|
public ulong ProductType;
|
||||||
|
public ulong AppVersion;
|
||||||
|
public ulong FirmwareVersion;
|
||||||
|
[ArrayLength(FixedSize = 0x20)]
|
||||||
|
public byte[] ContentID; // Only if NPDRM
|
||||||
|
[ArrayLength(FixedSize = 0x20)]
|
||||||
|
public byte[] SHA256Digest;
|
||||||
|
}
|
||||||
|
#pragma warning restore CS0649
|
||||||
|
}
|
||||||
108
Il2CppInspector.Common/FileFormatReaders/SElfReader.cs
Normal file
108
Il2CppInspector.Common/FileFormatReaders/SElfReader.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
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;
|
||||||
|
using NoisyCowStudios.Bin2Object;
|
||||||
|
|
||||||
|
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
|
||||||
|
// https://www.psxhax.com/threads/make-fself-gui-for-flat_zs-make_fself-py-script-by-cfwprophet.3494/
|
||||||
|
internal class SElfReader : FileFormatReader<SElfReader>
|
||||||
|
{
|
||||||
|
public SElfReader(Stream stream) : base(stream) { }
|
||||||
|
|
||||||
|
public override string Format => sceData.ProductType == (ulong) SElfExInfoTypes.PTYPE_FAKE? "FSELF" : "SELF";
|
||||||
|
|
||||||
|
public override string Arch => "x64";
|
||||||
|
|
||||||
|
public override int Bits => 64;
|
||||||
|
|
||||||
|
private SElfHeader selfHeader;
|
||||||
|
private SElfEntry[] entries;
|
||||||
|
private SElfSCEData sceData;
|
||||||
|
private elf_header<ulong> elfHeader;
|
||||||
|
private elf_64_phdr[] pht;
|
||||||
|
private elf_64_phdr getProgramHeader(Elf programIndex) => pht.FirstOrDefault(x => x.p_type == (uint) programIndex);
|
||||||
|
|
||||||
|
protected override bool Init() {
|
||||||
|
selfHeader = ReadObject<SElfHeader>();
|
||||||
|
|
||||||
|
// Check for magic bytes
|
||||||
|
if ((SElfConsts) selfHeader.Magic != SElfConsts.Magic)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (selfHeader.Endian != 0x1)
|
||||||
|
Endianness = Endianness.Big;
|
||||||
|
|
||||||
|
// Read entries
|
||||||
|
entries = ReadArray<SElfEntry>(selfHeader.NumberOfEntries);
|
||||||
|
|
||||||
|
// We can't deal with encrypted or compressed segments right now
|
||||||
|
if (entries.Any(e => e.HasBlocks && e.IsEncrypted))
|
||||||
|
throw new NotImplementedException("This file contains encrypted segments not currently supported by Il2CppInspector.");
|
||||||
|
|
||||||
|
if (entries.Any(e => e.HasBlocks && e.IsDeflated))
|
||||||
|
throw new NotImplementedException("This file contains compressed segments not currently supported by Il2CppInspector.");
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
elfHeader = ReadObject<elf_header<ulong>>();
|
||||||
|
|
||||||
|
// Must be one of these supported binary types
|
||||||
|
if (elfHeader.e_type != (ushort) Elf.ET_EXEC
|
||||||
|
&& elfHeader.e_type != (ushort) SElfETypes.ET_SCE_EXEC
|
||||||
|
&& elfHeader.e_type != (ushort) SElfETypes.ET_SCE_DYNEXEC
|
||||||
|
&& elfHeader.e_type != (ushort) SElfETypes.ET_SCE_DYNAMIC)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// There are no sections, but read all the program headers
|
||||||
|
// Each segment of type PT_LOAD, PT_SCE_RELRO, PT_SCE_DYNLIBDATA and PT_SCE_COMMENT
|
||||||
|
// generates two SELF entries above - one pointing to the ELF segment and one pointing to a digest.
|
||||||
|
// Only p_vaddr is used for memory mapping; all other fields are ignored.
|
||||||
|
// offset, memsz and filesz are taken from the SELF entries.
|
||||||
|
// The digests are all-zero in FSELF files.
|
||||||
|
// All other ELF segments are ignored completely.
|
||||||
|
pht = ReadArray<elf_64_phdr>(startOfElf + (long) elfHeader.e_phoff, elfHeader.e_phnum);
|
||||||
|
|
||||||
|
// Read extended info
|
||||||
|
sceData = ReadObject<SElfSCEData>(startOfElf + (long) elfHeader.e_phoff + elfHeader.e_phentsize * elfHeader.e_phnum);
|
||||||
|
|
||||||
|
// TODO: Implement the rest of FSELF
|
||||||
|
// TODO: Set GlobalOffset
|
||||||
|
|
||||||
|
throw new NotImplementedException("Il2CppInspector does not have PRX support yet");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only the DT_INIT function equivalent
|
||||||
|
public override uint[] GetFunctionTable() => new [] { MapVATR(elfHeader.e_entry) };
|
||||||
|
|
||||||
|
public override uint MapVATR(ulong uiAddr) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user