Skip to content

Instantly share code, notes, and snippets.

@SocraticBliss
Last active March 27, 2022 02:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save SocraticBliss/5edd9a589819f6ce76a041a5210ea60c to your computer and use it in GitHub Desktop.
Save SocraticBliss/5edd9a589819f6ce76a041a5210ea60c to your computer and use it in GitHub Desktop.
PS4 Signed ELF Template for 010 Editor
//------------------------------------------------
//--- 010 Editor v9.0 Binary Template
//
// File: PS4_SELF.bt
// Authors: SocraticBliss
// Version: 1.0.0
// Purpose: 1) Decode the Signed ELF format for the PS4 (64 bit)
// 2) Decode the ELF program and section headers
//
// Category: Game
// File Mask: *
// ID Bytes: 4F 15 3D 1D
// History:
// 1.0 SocraticBliss: Initial release.
//------------------------------------------------
local int warnings = 0;
local string temp_warning;
// A hack to get warning messages to both "Warn" (show in status) and output to the "output"
void PrintWarning(string message) {
Warning(temp_warning);
// Ensure new-line, "Warning" statuses should not have them
SPrintf(temp_warning, "%s\n", message);
Printf(temp_warning);
// Hack to trigger a more generic "look at warnings in output"
warnings++;
}
// ******************************* Signed ELF Identification **************************************
// Signed ELF Version
typedef enum <uchar> {
SELF_VERSION_NONE = 0x0,
SELF_VERSION_CURRENT = 0x1,
SELF_VERSION_NUM = 0x2
} sei_version_e <comment="Version">;
// Signed ELF Mode
typedef enum <uchar> {
SELF_MODE_NONE = 0x0,
SELF_MODE_CURRENT = 0x1,
SELF_MODE_NUM = 0x2
} sei_mode_e <comment="Mode">;
// Signed ELF Endian
typedef enum <uchar> {
SELF_DATA_NONE = 0x0,
SELF_DATA_2LSB = 0x1,
SELF_DATA_2MSB = 0x2,
SELF_DATA_NUM = 0x3
} sei_endian_e <comment="Endian">;
// Structure of the Signed ELF Identification
typedef struct {
char sei_magic[4] <format=hex,comment="Magic">;
if (Strcmp(sei_magic, "\x4F\x15\x3D\x1D")) {
PrintWarning("Invalid SELF file");
return -1;
}
sei_version_e sei_version <comment="Version">;
sei_mode_e sei_mode <comment="Mode">;
sei_endian_e sei_endian <comment="Endian">;
uchar sei_flag <format=hex,comment="Attributes">;
} se_ident_e <comment="Identification">;
// ***************************** Signed ELF Extended Format ***************************************
// Structure of the Signed ELF Extended Format
typedef struct {
uint32 ex_key_type <format=hex, comment="Key Type">;
uint16 ex_header_size <format=hex,comment="Header Size">;
uint16 ex_meta_size <comment="(Bytes) Meta Size">;
uint64 ex_file_size <comment="(Bytes) File Size">;
uint16 ex_entry_count <comment="Entry Count">;
uint16 ex_flag <format=hex,comment="Attributes">;
uchar ex_padding[4] <comment="Padding">;
} se_extfmt_e <comment="Extended Format">;
// ************************************* Signed ELF Entries ***************************************
typedef struct {
// Signed ELF Properties
local int16 sep_order = (se_properties >> 0) & 0x1;
local int16 sep_encrypted = (se_properties >> 1) & 0x1;
local int16 sep_signed = (se_properties >> 2) & 0x1;
local int16 sep_compressed = (se_properties >> 3) & 0x1;
local int16 sep_window_bits = (se_properties >> 8) & 0x7;
local int16 sep_has_blocks = (se_properties >> 11) & 0x1;
if (sep_has_blocks > 0) {
local int16 sep_block_size = 1 << (12 + (se_properties >> 12) & 0xF);
} else {
local int16 sep_block_size = 0x1000;
}
local int16 sep_has_digests = (se_properties >> 16) & 0x1;
local int16 sep_has_extents = (se_properties >> 17) & 0x1;
local int16 sep_has_metas = (se_properties >> 20) & 0x1;
local int16 sep_segment_index = (se_properties >> 20) & 0xFFFF;
} se_properties_e;
// Structure of the Signed ELF Entries
typedef struct {
uint64 se_properties <format=hex,comment="Properties">;
se_properties_e expanded_properties;
uint64 se_file_offset <format=hex,comment="File Offset">;
uint64 se_file_size <comment="(Bytes) File Size">;
uint64 se_memory_size <comment="(Bytes) Memory Size">;
} se_entries_e;
// **************************************** ELF Header ********************************************
// ELF Class
typedef enum <uchar> {
ELF_CLASS_NONE = 0x0,
ELF_CLASS_64 = 0x2,
ELF_CLASS_NUM = 0x3
} ei_class_e <comment="Class">;
// ELF Endian
typedef enum <uchar> {
ELF_DATA_NONE = 0x0,
ELF_DATA_2LSB = 0x1,
ELF_DATA_2MSB = 0x2,
ELF_DATA_NUM = 0x3
} ei_data_e <comment="Endian">;
// ELF Version
typedef enum <uchar> {
ELF_VERSION_NONE = 0x0,
ELF_VERSION_CURRENT = 0x1,
ELF_VERSION_NUM = 0x2
} ei_version_e <comment="Version">;
// ELF OS/ABI
typedef enum <uchar> {
ELF_OSABI_NONE = 0x0, /* No extensions or unspecified */
ELF_OSABI_HPUX = 0x1, /* Hewlett-Packard HP-UX */
ELF_OSABI_NETBSD = 0x2, /* NetBSD */
ELF_OSABI_LINUX = 0x3, /* Linux */
ELF_OSABI_SOLARIS = 0x6, /* Sun Solaris */
ELF_OSABI_AIX = 0x7, /* AIX */
ELF_OSABI_IRIX = 0x8, /* IRIX */
ELF_OSABI_FREEBSD = 0x9, /* FreeBSD (PS4) */
ELF_OSABI_TRU64 = 0xA, /* Compaq TRU64 UNIX */
ELF_OSABI_MODESTO = 0xB, /* Novell Modesto */
ELF_OSABI_OPENBSD = 0xC, /* Open BSD */
ELF_OSABI_OPENVMS = 0xD, /* Open VMS */
ELF_OSABI_NSK = 0xE, /* Hewlett-Packard Non-Stop Kernel */
ELF_OSABI_AROS = 0xF, /* Amiga Research OS */
ELF_OSABI_ARM_AEABI = 0x40, /* ARM EABI */
ELF_OSABI_ARM = 0x61, /* ARM */
ELF_OSABI_STANDALONE = 0xFF /* Standalone (embedded applications) */
} ei_osabi_e <comment="OS/ABI">;
// ELF Type
typedef enum <uint16> {
ET_NONE = 0x0,
ET_REL = 0x1,
ET_EXEC = 0x2,
ET_DYN = 0x3,
ET_CORE = 0x4,
ET_SCE_EXEC = 0xfe00,
ET_SCE_STUBLIB = 0xfe0c,
ET_SCE_DYNEXEC = 0xfe10,
ET_SCE_DYNAMIC = 0xfe18
} e_type_e <comment="File Type">;
// ELF Machine
typedef enum <uint16> {
EM_NONE = 0, /* No machine */
EM_M32 = 1, /* AT&T WE 32100 */
EM_SPARC = 2, /* SPARC */
EM_386 = 3, /* Intel 80386 */
EM_68K = 4, /* Motorola 68000 */
EM_88K = 5, /* Motorola 88000 */
EM_860 = 7, /* Intel 80860 */
EM_MIPS = 8, /* MIPS I Architecture */
EM_S370 = 9, /* IBM System/370 Processor */
EM_MIPS_RS3_LE = 10, /* MIPS RS3000 Little-endian */
EM_PARISC = 15, /* Hewlett-Packard PA-RISC */
EM_VPP500 = 17, /* Fujitsu VPP500 */
EM_SPARC32PLUS = 18, /* Enhanced instruction set SPARC */
EM_960 = 19, /* Intel 80960 */
EM_PPC = 20, /* PowerPC */
EM_PPC64 = 21, /* 64-bit PowerPC */
EM_S390 = 22, /* IBM System/390 Processor */
EM_V800 = 36, /* NEC V800 */
EM_FR20 = 37, /* Fujitsu FR20 */
EM_RH32 = 38, /* TRW RH-32 */
EM_RCE = 39, /* Motorola RCE */
EM_ARM = 40, /* Advanced RISC Machines ARM */
EM_ALPHA = 41, /* Digital Alpha */
EM_SH = 42, /* Hitachi SH */
EM_SPARCV9 = 43, /* SPARC Version 9 */
EM_TRICORE = 44, /* Siemens TriCore embedded processor */
EM_ARC = 45, /* Argonaut RISC Core, Argonaut Technologies Inc. */
EM_H8_300 = 46, /* Hitachi H8/300 */
EM_H8_300H = 47, /* Hitachi H8/300H */
EM_H8S = 48, /* Hitachi H8S */
EM_H8_500 = 49, /* Hitachi H8/500 */
EM_IA_64 = 50, /* Intel IA-64 processor architecture */
EM_MIPS_X = 51, /* Stanford MIPS-X */
EM_COLDFIRE = 52, /* Motorola ColdFire */
EM_68HC12 = 53, /* Motorola M68HC12 */
EM_MMA = 54, /* Fujitsu MMA Multimedia Accelerator */
EM_PCP = 55, /* Siemens PCP */
EM_NCPU = 56, /* Sony nCPU embedded RISC processor */
EM_NDR1 = 57, /* Denso NDR1 microprocessor */
EM_STARCORE = 58, /* Motorola Star*Core processor */
EM_ME16 = 59, /* Toyota ME16 processor */
EM_ST100 = 60, /* STMicroelectronics ST100 processor */
EM_TINYJ = 61, /* Advanced Logic Corp. TinyJ embedded processor family */
EM_X86_64 = 62, /* AMD x86-64 architecture (PS4) */
EM_PDSP = 63, /* Sony DSP Processor */
EM_PDP10 = 64, /* Digital Equipment Corp. PDP-10 */
EM_PDP11 = 65, /* Digital Equipment Corp. PDP-11 */
EM_FX66 = 66, /* Siemens FX66 microcontroller */
EM_ST9PLUS = 67, /* STMicroelectronics ST9+ 8/16 bit microcontroller */
EM_ST7 = 68, /* STMicroelectronics ST7 8-bit microcontroller */
EM_68HC16 = 69, /* Motorola MC68HC16 Microcontroller */
EM_68HC11 = 70, /* Motorola MC68HC11 Microcontroller */
EM_68HC08 = 71, /* Motorola MC68HC08 Microcontroller */
EM_68HC05 = 72, /* Motorola MC68HC05 Microcontroller */
EM_SVX = 73, /* Silicon Graphics SVx */
EM_ST19 = 75, /* Digital VAX */
EM_CRIS = 76, /* Axis Communications 32-bit embedded processor */
EM_JAVELIN = 77, /* Infineon Technologies 32-bit embedded processor */
EM_FIREPATH = 78, /* Element 14 64-bit DSP Processor */
EM_ZSP = 79, /* LSI Logic 16-bit DSP Processor */
EM_MMIX = 80, /* Donald Knuth's educational 64-bit processor */
EM_HUANY = 81, /* Harvard University machine-independent object files */
EM_PRISM = 82, /* SiTera Prism */
EM_AVR = 83, /* Atmel AVR 8-bit microcontroller */
EM_FR30 = 84, /* Fujitsu FR30 */
EM_D10V = 85, /* Mitsubishi D10V */
EM_D30V = 86, /* Mitsubishi D30V */
EM_V850 = 87, /* NEC v850 */
EM_M32R = 88, /* Mitsubishi M32R */
EM_MN10300 = 89, /* Matsushita MN10300 */
EM_MN10200 = 90, /* Matsushita MN10200 */
EM_PJ = 91, /* PicoJava */
EM_OPENRISC = 92, /* OpenRISC 32-bit embedded processor */
EM_ARC_A5 = 93, /* ARC Cores Tangent-A5 */
EM_XTENSA = 94, /* Tensilica Xtensa Architecture */
EM_VIDEOCORE = 95, /* Alphamosaic VideoCore processor */
EM_TMM_GPP = 96, /* Thompson Multimedia General Purpose Processor */
EM_NS32K = 97, /* National Semiconductor 32000 series */
EM_TPC = 98, /* Tenor Network TPC processor */
EM_SNP1K = 99, /* Trebia SNP 1000 processor */
EM_ST200 = 100, /* STMicroelectronics (www.st.com) ST200 microcontroller */
EM_IP2K = 101, /* Ubicom IP2xxx microcontroller family */
EM_MAX = 102, /* MAX Processor */
EM_CR = 103, /* National Semiconductor CompactRISC microprocessor */
EM_F2MC16 = 104, /* Fujitsu F2MC16 */
EM_MSP430 = 105, /* Texas Instruments embedded microcontroller msp430 */
EM_BLACKFIN = 106, /* Analog Devices Blackfin (DSP) processor */
EM_SE_C33 = 107, /* S1C33 Family of Seiko Epson processors */
EM_SEP = 108, /* Sharp embedded microprocessor */
EM_ARCA = 109, /* Arca RISC Microprocessor */
EM_UNICORE = 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC */
} e_machine_e <comment="Machine Type">;
// ELF Entry Version
typedef enum <uint32> {
EV_NONE = 0x0,
EV_CURRENT = 0x1
} e_version_e <comment="File Version">;
// Structure of the ELF Identification
typedef struct {
char ei_magic[4] <format=hex,comment="Magic">;
if (Strcmp(ei_magic, "\x7FELF")) {
PrintWarning("Invalid ELF file");
return -1;
}
ei_class_e ei_class;
ei_data_e ei_data;
if (ei_data == ELF_DATA_2LSB) {
LittleEndian();
} else {
BigEndian();
}
ei_version_e ei_version;
ei_osabi_e ei_osabi;
uchar ei_abiversion <comment="ABI Version">;
uchar ei_pad[6] <comment="Padding">;
uchar ei_nident_size;
} e_ident_e;
// ********************************** ELF Program Headers *****************************************
// Program Header Type
typedef enum <uint32> {
PT_NULL = 0x0,
PT_LOAD = 0x1,
PT_DYNAMIC = 0x2,
PT_INERP = 0x3,
PT_NOTE = 0x4,
PT_SHLIB = 0x5,
PT_PHDR = 0x6,
PT_TLS = 0x7,
PT_NUM = 0x8,
PT_SCE_RELA = 0x60000000,
PT_SCE_DYNLIBDATA = 0x61000000,
PT_SCE_PROCPARAM = 0x61000001,
PT_SCE_MODULE_PARAM = 0x61000002,
PT_SCE_RELRO = 0x61000010,
PT_GNU_EH_FRAME = 0x6474e550,
PT_GNU_STACK = 0x6474e551,
PT_GNU_RELRO = 0x6474e552,
PT_SCE_COMMENT = 0x6fffff00,
PT_SCE_LIBVERSION = 0x6fffff01,
PT_LOSUNW = 0x6ffffffa,
PT_SUNWBSS = 0x6ffffffa,
PT_SUNWSTACK = 0x6ffffffb,
PT_HISUNW = 0x6fffffff,
PT_HIOS = 0x6fffffff,
PT_LOPROC = 0x70000000,
PT_HIPROC = 0x7fffffff
} ep_type_e <comment="Program Type">;
// Program Header Attributes
typedef enum <uint32> {
PF_NONE = 0x0,
PF_EXEC = 0x1,
PF_WRITE = 0x2,
PF_WRITE_EXEC = 0x3,
PF_READ = 0x4,
PF_READ_EXEC = 0x5,
PF_READ_WRITE = 0x6,
PF_READ_WRITE_EXEC = 0x7
} ep_flags_e <comment="Program Attributes">;
// Structure of the Program Header Table
typedef struct {
local quad off = FTell();
ep_type_e p_type;
ep_flags_e p_flags;
uint64 p_offset <format=hex,comment="File Offset">;
uint64 p_virtual_address <format=hex,comment="Virtual Address">;
uint64 p_physical_address <format=hex,comment="Physical Address">;
uint64 p_file_size <comment="(Bytes) File Size">;
uint64 p_memory_size <comment="(Bytes) Memory Size">;
uint64 p_alignment <comment="Alignment">;
if (p_file_size > 0 && p_file_size < (uint64) FileSize() &&
p_offset > 0 && p_offset + p_file_size < (uint64) FileSize()) {
FSeek(p_offset);
char p_data[p_file_size] <comment="Data">;
}
FSeek(off + file.elf_header.e_phentsize);
} program_table_entries <read=ProgramInfo,optimize=false>;
string ProgramType( ep_type_e type ) {
switch(type) {
case PT_NULL:
return "Null";
case PT_LOAD:
return "Loadable";
case PT_DYNAMIC:
return "Dynamic";
case PT_INERP:
return "Interpreter Path";
case PT_NOTE:
return "Note";
case PT_SHLIB:
return "Section Header Library";
case PT_PHDR:
return "Program Header";
case PT_TLS:
return "Thread-Local Storage";
case PT_NUM:
return "Defined Sections Number";
case PT_SCE_RELA:
return "SCE Relative";
case PT_SCE_DYNLIBDATA:
return "SCE Dynamic Library Data";
case PT_SCE_PROCPARAM:
return "SCE Processor Parameters";
case PT_SCE_MODULE_PARAM:
return "SCE Module Parameters";
case PT_SCE_RELRO:
return "SCE Read-Only After Relocation";
case PT_GNU_EH_FRAME:
return "GNU Entry Header Frame";
case PT_GNU_STACK:
return "GNU Stack (executability)";
case PT_GNU_RELRO:
return "GNU Read-Only After Relocation";
case PT_SCE_COMMENT:
return "SCE Comment";
case PT_SCE_LIBVERSION:
return "SCE Library Version";
default:
return "Unknown Section";
}
}
string ProgramFlags(ep_flags_e flags) {
local string rv = "(";
rv += (flags & PF_READ) ? "R" : "_";
rv += (flags & PF_WRITE) ? "W" : "_";
rv += (flags & PF_EXEC) ? "X" : "_";
rv += ")";
return rv;
}
string ProgramInfo(program_table_entries &ent) {
return ProgramFlags(ent.p_flags) + " " + ProgramType(ent.p_type);
}
// ************************************* Section Header Table *************************************
// Section Header Type
typedef enum <uint32> {
SHT_NULL = 0x0, /* Inactive section header */
SHT_PROGBITS = 0x1, /* Information defined by the program */
SHT_SYMTAB = 0x2, /* Symbol table - not DLL */
SHT_STRTAB = 0x3, /* String table */
SHT_RELA = 0x4, /* Explicit addend relocations, Elf64_Rela */
SHT_HASH = 0x5, /* Symbol hash table */
SHT_DYNAMIC = 0x6, /* Information for dynamic linking */
SHT_NOTE = 0x7, /* A Note section */
SHT_NOBITS = 0x8, /* Like SHT_PROGBITS with no data */
SHT_REL = 0x9, /* Implicit addend relocations, Elf64_Rel */
SHT_SHLIB = 0xA, /* Currently unspecified semantics */
SHT_DYNSYM = 0xD, /* Symbol table for a DLL */
SHT_INIT_ARRAY = 0xE, /* Array of constructors */
SHT_FINI_ARRAY = 0xF, /* Array of de-constructors */
SHT_PREINIT_ARRAY = 0x10, /* Array of pre-constructors */
SHT_GROUP = 0x11, /* Section group */
SHT_SYMTAB_SHNDX = 0x12, /* Extended section indices */
SHT_NUM = 0x13, /* Number of defined types */
SHT_LOOS = 0x60000000, /* Lowest OS-specific section type */
SHT_SCE_NID = 0x61000001,
SHT_GNU_INCREMENTAL_INPUTS = 0x6fff4700,
SHT_GNU_ATTRIBUTES = 0x6ffffff5, /* Object attributes */
SHT_GNU_HASH = 0x6ffffff6, /* GNU-style hash table */
SHT_GNU_LIBLIST = 0x6ffffff7, /* Pre-link library list */
SHT_CHECKSUM = 0x6ffffff8, /* Checksum for DSO content */
SHT_LOSUNW = 0x6ffffffa, /* Sun-specific low bound */
SHT_SUNW_MOVE = 0x6ffffffa,
SHT_SUNW_COMDAT = 0x6ffffffb,
SHT_SUNW_SYMINFO = 0x6ffffffc,
SHT_GNU_VERDEF = 0x6ffffffd, /* Version definition section */
SHT_GNU_VERNEED = 0x6ffffffe, /* Version needs section */
SHT_GNY_VERSYM = 0x6fffffff, /* Version symbol table */
SHT_HISUNW = 0x6fffffff, /* Sun-specific high bound */
SHT_HIOS = 0x6fffffff, /* Highest OS-specific section type */
SHT_LOPROC = 0x70000000, /* Start of processor-specific section type */
SHT_HIPROC = 0x7fffffff, /* End of processor-specific section type */
SHT_LOUSER = 0x80000000, /* Start of application-specific */
SHT_HIUSER = 0x8fffffff /* End of application-specific */
} es_type_e <comment="Section Type">;
// Section Header Attributes
typedef enum <uint64> {
SF64_NONE = 0x0,
SF64_EXEC = 0x1,
SF64_ALLOC = 0x2,
SF64_ALLOC_EXEC = 0x3,
SF64_WRITE = 0x4,
SF64_WRITE_EXEC = 0x5,
SF64_WRITE_ALLOC = 0x6,
SF64_WRITE_ALLOC_EXEC = 0x7
} es_flags_e <comment="Section Attributes">;
// Structure of the Section Header Table
typedef struct {
uint32 s_name <comment="Name">;
es_type_e s_type;
es_flags_e s_flags;
uint64 s_addr <comment="Virtual Address">;
uint64 s_offset <format=hex,comment="File Offset">;
uint64 s_size <comment="(Bytes) Section Size ">;
uint32 s_link <comment="Section Link">;
uint32 s_info <comment="Miscellaneous Information">;
uint64 s_addralign <comment="Address Alignment Boundary ">;
uint64 s_enttrysize <comment="(Bytes) Entry Size">;
if (s_type != SHT_NOBITS && s_type != SHT_NULL && s_size > 0 && s_offset < FileSize()
&& s_size <= (FileSize() - s_offset)) {
FSeek(s_offset);
char data[s_size];
}
//FSeek(off + file.elf_header.e_shentsize);
} section_table_entries <optimize=false>;
// ******************************** Signed ELF Extended Information *******************************
// Signed ELF Types
typedef enum <uint64> {
PT_FAKE = 0x1,
PT_NPDRM_EXEC = 0x4,
PT_NPDRM_DYNLIB = 0x5,
PT_SYSTEM_EXEC = 0x8,
PT_SYSTEM_DYNLIB = 0x9,
PT_HOST_KERNEL = 0xC,
PT_SECURE_MODULE = 0xE,
PT_SECURE_KERNEL = 0xF
} se_type_e <comment="Signed ELF Type">;
// **************************************** Signed ELF File ***************************************
// Structure of the Signed ELF File
local int sec_tbl_elem[255];
struct {
local int i;
for (i=0; i<255; i++) {
sec_tbl_elem[i] = -1;
}
// Signed ELF Header
struct {
se_ident_e identification;
se_extfmt_e ext_format;
} self_header <comment="The signed ELF header tells us where everything is located">;
// Signed ELF Entries
if (file.self_header.ext_format.ex_entry_count > 0) {
struct {
se_entries_e entry[file.self_header.ext_format.ex_entry_count] <optimize=false>;
} self_entries <comment="Signed ELF Entries">;
}
// ELF Header
struct {
e_ident_e e_ident;
e_type_e e_type;
e_machine_e e_machine;
e_version_e e_version;
uint64 e_entry <format=hex,comment="Entry Point Virtual Address">;
uint64 e_phoff <format=hex,comment="Program Header File Offset">;
uint64 e_shoff <format=hex,comment="Section Header File Offset">;
uint32 e_flags <format=hex,comment="Processor-Specific Flags">;
uint16 e_ehsize <comment="(Bytes) ELF Header Size">;
uint16 e_phentsize <comment="(Bytes) Program Header Entry Size">;
uint16 e_phnum <comment="Program Header Entry Count">;
uint16 e_shentsize <comment="(Bytes) Section Header Entry Size">;
uint16 e_shnum <comment="Section Header Entry Count">;
uint16 e_shtrndx <comment="Section Header String Index">;
} elf_header <comment="The main ELF header tells us where everything is located">;
// ELF Program Headers
if (file.elf_header.e_phnum > 0) {
struct {
program_table_entries entry[file.elf_header.e_phnum];
} elf_program_headers <comment="Describes the executable sections of the program code">;
}
// ELF Section Headers
if (file.elf_header.e_shnum > 0) {
struct {
section_table_entries entry[file.elf_header.e_shnum];
} elf_section_headers <comment="Describes the executable sections of the program code">;
}
// Signed Elf Extended Information
struct {
uint64 se_authid <format=hex,comment="Authentication ID">;
se_type_e se_type;
uint64 se_appver <format=hex,comment="Application Version">;
uint64 se_firmver <format=hex,comment="Firmware Version">;
uchar se_digest[32] <format=hex,comment="Signed ELF Digest">;
} self_ext_info <comment="Signed ELF Extended Information">;
} file;
// *************************************** Warnings ***********************************************
// It's not really useful to see just the last warning,
// so inform us how many warnings we should see in output.
if (warnings > 1) {
Warning("%d warnings have occured and logged to the output box!", warnings);
}
// This will make the template show "Template executed successfully."
if (warnings != 0) {
SPrintf(temp_warning, "%d warnings found, template may not have run successfully!", warnings);
return temp_warning;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment