ソースを参照

Merge branch 'elf-info' of https://github.com/n1073645/CyberChef

n1474335 3 年 前
コミット
23b168515c

+ 2 - 1
src/core/config/Categories.json

@@ -413,7 +413,8 @@
             "Extract RGBA",
             "View Bit Plane",
             "Randomize Colour Palette",
-            "Extract LSB"
+            "Extract LSB",
+            "ELF Info"
         ]
     },
     {

+ 4 - 2
src/core/lib/Stream.mjs

@@ -48,12 +48,14 @@ export default class Stream {
      * Interpret the following bytes as a string, stopping at the next null byte or
      * the supplied limit.
      *
-     * @param {number} numBytes
+     * @param {number} [numBytes=-1]
      * @returns {string}
      */
-    readString(numBytes) {
+    readString(numBytes=-1) {
         if (this.position > this.length) return undefined;
 
+        if (numBytes === -1) numBytes = this.length - this.position;
+
         let result = "";
         for (let i = this.position; i < this.position + numBytes; i++) {
             const currentByte = this.bytes[i];

+ 913 - 0
src/core/operations/ELFInfo.mjs

@@ -0,0 +1,913 @@
+/**
+ * @author n1073645 [n1073645@gmail.com]
+ * @copyright Crown Copyright 2022
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation.mjs";
+import Stream from "../lib/Stream.mjs";
+import Utils from "../Utils.mjs";
+import OperationError from "../errors/OperationError.mjs";
+
+/**
+ * ELF Info operation
+ */
+class ELFInfo extends Operation {
+
+    /**
+     * ELFInfo constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "ELF Info";
+        this.module = "Default";
+        this.description = "Implements readelf-like functionality. This operation will extract the ELF Header, Program Headers, Section Headers and Symbol Table for an ELF file.";
+        this.infoURL = "https://www.wikipedia.org/wiki/Executable_and_Linkable_Format";
+        this.inputType = "ArrayBuffer";
+        this.outputType = "string";
+        this.args = [];
+    }
+
+    /**
+     * @param {ArrayBuffer} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        let phoff = 0;
+        let phEntries = 0;
+        let shoff = 0;
+        let shEntries = 0;
+        let shentSize = 0;
+        let entry = 0;
+        let format = 0;
+        let endianness = "";
+        let shstrtab = 0;
+
+        let namesOffset = 0;
+
+        let symtabOffset = 0;
+        let symtabSize = 0;
+        let symtabEntSize = 0;
+
+        let strtabOffset = 0;
+        const align = 30;
+
+        /**
+         * This function reads characters until it hits a null terminator.
+         *
+         * @param {stream} stream
+         * @param {integer} namesOffset
+         * @param {integer} nameOffset
+         * @returns {string}
+         */
+        function readString(stream, namesOffset, nameOffset) {
+            const preMove = stream.position;
+            stream.moveTo(namesOffset + nameOffset);
+
+            const nameResult = stream.readString();
+            stream.moveTo(preMove);
+            return nameResult;
+        }
+
+        /**
+         * This function parses and extracts relevant information from the ELF Header.
+         *
+         * @param {stream} stream
+         * @returns {string}
+         */
+        function elfHeader(stream) {
+            /**
+             * The ELF Header is comprised of the following structures depending on the binary's format.
+             *
+             * e_ident     - The Magic Number 0x7F,0x45,0x4c,0x46
+             *             - Byte set to 1 or 2 to signify 32-bit or 64-bit format, respectively.
+             *             - Byte set to 1 or 2 to signify little of big endianness, respectively.
+             *             - Byte set to 1 for the version of ELF.
+             *             - Byte identifying the target OS ABI.
+             *             - Byte further identifying the OS ABI Version.
+             *             - 7 Padding Bytes.
+             * e_type      - 2 bytes identifying the object file type.
+             * e_machine   - 2 bytes identifying the instruction set architecture.
+             * e_version   - Byte set to 1 for the version of ELF.
+             *
+             * 32-bit:
+             *      e_entry     - 4 Bytes specifying the entry point.
+             *      e_phoff     - 4 Bytes specifying the offset of the Program Header Table.
+             *      e_shoff     - 4 Bytes specifying the offset of the Section Header Table.
+             *
+             * 64-bit:
+             *      e_entry     - 8 Bytes specifying the entry point.
+             *      e_phoff     - 8 Bytes specifying the offset of the Program Header Table.
+             *      e_shoff     - 8 Bytes specifying the offset of the Section Header Table.
+             *
+             * e_flags     - 4 Bytes specifying processor specific flags.
+             * e_ehsize    - 2 Bytes specifying the size of the ELF Header.
+             * e_phentsize - 2 Bytes specifying the size of a Program Header Table Entry.
+             * e_phnum     - 2 Bytes specifying the number of entries in the Program Header Table.
+             * e_shentsize - 2 Bytes specifying the size of a Section Header Table Entry.
+             * e_shnum     - 2 Bytes specifying the number of entries in the Section Header Table.
+             * e_shstrndx  - 2 Bytes specifying the index of the section containing the section names in the Section Header Table.
+             */
+            const ehResult = [];
+
+            const magic = stream.getBytes(4);
+            if (magic.join("") !== [0x7f, 0x45, 0x4c, 0x46].join(""))
+                throw new OperationError("Invalid ELF");
+
+            ehResult.push("Magic:".padEnd(align) + `${Utils.byteArrayToChars(magic)}`);
+
+            format = stream.readInt(1);
+            ehResult.push("Format:".padEnd(align) + `${format === 1 ? "32-bit" : "64-bit"}`);
+
+            endianness = stream.readInt(1) === 1 ? "le" : "be";
+            ehResult.push("Endianness:".padEnd(align) + `${endianness === "le" ? "Little" : "Big"}`);
+
+            ehResult.push("Version:".padEnd(align) + `${stream.readInt(1).toString()}`);
+
+            let ABI = "";
+            switch (stream.readInt(1)) {
+                case 0x00:
+                    ABI = "System V";
+                    break;
+                case 0x01:
+                    ABI = "HP-UX";
+                    break;
+                case 0x02:
+                    ABI = "NetBSD";
+                    break;
+                case 0x03:
+                    ABI = "Linux";
+                    break;
+                case 0x04:
+                    ABI = "GNU Hurd";
+                    break;
+                case 0x06:
+                    ABI = "Solaris";
+                    break;
+                case 0x07:
+                    ABI = "AIX";
+                    break;
+                case 0x08:
+                    ABI = "IRIX";
+                    break;
+                case 0x09:
+                    ABI = "FreeBSD";
+                    break;
+                case 0x0A:
+                    ABI = "Tru64";
+                    break;
+                case 0x0B:
+                    ABI = "Novell Modesto";
+                    break;
+                case 0x0C:
+                    ABI = "OpenBSD";
+                    break;
+                case 0x0D:
+                    ABI = "OpenVMS";
+                    break;
+                case 0x0E:
+                    ABI = "NonStop Kernel";
+                    break;
+                case 0x0F:
+                    ABI = "AROS";
+                    break;
+                case 0x10:
+                    ABI = "Fenix OS";
+                    break;
+                case 0x11:
+                    ABI = "CloudABI";
+                    break;
+                case 0x12:
+                    ABI = "Stratus Technologies OpenVOS";
+                    break;
+                default:
+                    break;
+            }
+            ehResult.push("ABI:".padEnd(align) + ABI);
+
+            // Linux Kernel does not use ABI Version.
+            const abiVersion = stream.readInt(1).toString();
+            if (ABI !== "Linux")
+                ehResult.push("ABI Version:".padEnd(align) + abiVersion);
+
+            stream.moveForwardsBy(7);
+
+            let eType = "";
+            switch (stream.readInt(2, endianness)) {
+                case 0x0000:
+                    eType = "Unknown";
+                    break;
+                case 0x0001:
+                    eType = "Relocatable File";
+                    break;
+                case 0x0002:
+                    eType = "Executable File";
+                    break;
+                case 0x0003:
+                    eType = "Shared Object";
+                    break;
+                case 0x0004:
+                    eType = "Core File";
+                    break;
+                case 0xFE00:
+                    eType = "LOOS";
+                    break;
+                case 0xFEFF:
+                    eType = "HIOS";
+                    break;
+                case 0xFF00:
+                    eType = "LOPROC";
+                    break;
+                case 0xFFFF:
+                    eType = "HIPROC";
+                    break;
+                default:
+                    break;
+            }
+            ehResult.push("Type:".padEnd(align) + eType);
+
+            let ISA = "";
+            switch (stream.readInt(2, endianness)) {
+                case 0x0000:
+                    ISA = "No specific instruction set";
+                    break;
+                case 0x0001:
+                    ISA = "AT&T WE 32100";
+                    break;
+                case 0x0002:
+                    ISA = "SPARC";
+                    break;
+                case 0x0003:
+                    ISA = "x86";
+                    break;
+                case 0x0004:
+                    ISA = "Motorola 68000 (M68k)";
+                    break;
+                case 0x0005:
+                    ISA = "Motorola 88000 (M88k)";
+                    break;
+                case 0x0006:
+                    ISA = "Intel MCU";
+                    break;
+                case 0x0007:
+                    ISA = "Intel 80860";
+                    break;
+                case 0x0008:
+                    ISA = "MIPS";
+                    break;
+                case 0x0009:
+                    ISA = "IBM System/370";
+                    break;
+                case 0x000A:
+                    ISA = "MIPS RS3000 Little-endian";
+                    break;
+                case 0x000B:
+                case 0x000C:
+                case 0x000D:
+                case 0x000E:
+                case 0x0018:
+                case 0x0019:
+                case 0x001A:
+                case 0x001B:
+                case 0x001C:
+                case 0x001D:
+                case 0x001E:
+                case 0x001F:
+                case 0x0020:
+                case 0x0021:
+                case 0x0022:
+                case 0x0023:
+                    ISA = "Reserved for future use";
+                    break;
+                case 0x000F:
+                    ISA = "Hewlett-Packard PA-RISC";
+                    break;
+                case 0x0011:
+                    ISA = "Fujitsu VPP500";
+                    break;
+                case 0x0012:
+                    ISA = "Enhanced instruction set SPARC";
+                    break;
+                case 0x0013:
+                    ISA = "Intel 80960";
+                    break;
+                case 0x0014:
+                    ISA = "PowerPC";
+                    break;
+                case 0x0015:
+                    ISA = "PowerPC (64-bit)";
+                    break;
+                case 0x0016:
+                    ISA = "S390, including S390";
+                    break;
+                case 0x0017:
+                    ISA = "IBM SPU/SPC";
+                    break;
+                case 0x0024:
+                    ISA = "NEC V800";
+                    break;
+                case 0x0025:
+                    ISA = "Fujitsu FR20";
+                    break;
+                case 0x0026:
+                    ISA = "TRW RH-32";
+                    break;
+                case 0x0027:
+                    ISA = "Motorola RCE";
+                    break;
+                case 0x0028:
+                    ISA = "ARM (up to ARMv7/Aarch32)";
+                    break;
+                case 0x0029:
+                    ISA = "Digital Alpha";
+                    break;
+                case 0x002A:
+                    ISA = "SuperH";
+                    break;
+                case 0x002B:
+                    ISA = "SPARC Version 9";
+                    break;
+                case 0x002C:
+                    ISA = "Siemens TriCore embedded processor";
+                    break;
+                case 0x002D:
+                    ISA = "Argonaut RISC Core";
+                    break;
+                case 0x002E:
+                    ISA = "Hitachi H8/300";
+                    break;
+                case 0x002F:
+                    ISA = "Hitachi H8/300H";
+                    break;
+                case 0x0030:
+                    ISA = "Hitachi H8S";
+                    break;
+                case 0x0031:
+                    ISA = "Hitachi H8/500";
+                    break;
+                case 0x0032:
+                    ISA = "IA-64";
+                    break;
+                case 0x0033:
+                    ISA = "Standford MIPS-X";
+                    break;
+                case 0x0034:
+                    ISA = "Motorola ColdFire";
+                    break;
+                case 0x0035:
+                    ISA = "Motorola M68HC12";
+                    break;
+                case 0x0036:
+                    ISA = "Fujitsu MMA Multimedia Accelerator";
+                    break;
+                case 0x0037:
+                    ISA = "Siemens PCP";
+                    break;
+                case 0x0038:
+                    ISA = "Sony nCPU embedded RISC processor";
+                    break;
+                case 0x0039:
+                    ISA = "Denso NDR1 microprocessor";
+                    break;
+                case 0x003A:
+                    ISA = "Motorola Star*Core processor";
+                    break;
+                case 0x003B:
+                    ISA = "Toyota ME16 processor";
+                    break;
+                case 0x003C:
+                    ISA = "STMicroelectronics ST100 processor";
+                    break;
+                case 0x003D:
+                    ISA = "Advanced Logic Corp. TinyJ embedded processor family";
+                    break;
+                case 0x003E:
+                    ISA = "AMD x86-64";
+                    break;
+                case 0x003F:
+                    ISA = "Sony DSP Processor";
+                    break;
+                case 0x0040:
+                    ISA = "Digital Equipment Corp. PDP-10";
+                    break;
+                case 0x0041:
+                    ISA = "Digital Equipment Corp. PDP-11";
+                    break;
+                case 0x0042:
+                    ISA = "Siemens FX66 microcontroller";
+                    break;
+                case 0x0043:
+                    ISA = "STMicroelectronics ST9+ 8/16 bit microcontroller";
+                    break;
+                case 0x0044:
+                    ISA = "STMicroelectronics ST7 8-bit microcontroller";
+                    break;
+                case 0x0045:
+                    ISA = "Motorola MC68HC16 Microcontroller";
+                    break;
+                case 0x0046:
+                    ISA = "Motorola MC68HC11 Microcontroller";
+                    break;
+                case 0x0047:
+                    ISA = "Motorola MC68HC08 Microcontroller";
+                    break;
+                case 0x0048:
+                    ISA = "Motorola MC68HC05 Microcontroller";
+                    break;
+                case 0x0049:
+                    ISA = "Silicon Graphics SVx";
+                    break;
+                case 0x004A:
+                    ISA = "STMicroelectronics ST19 8-bit microcontroller";
+                    break;
+                case 0x004B:
+                    ISA = "Digital VAX";
+                    break;
+                case 0x004C:
+                    ISA = "Axis Communications 32-bit embedded processor";
+                    break;
+                case 0x004D:
+                    ISA = "Infineon Technologies 32-bit embedded processor";
+                    break;
+                case 0x004E:
+                    ISA = "Element 14 64-bit DSP Processor";
+                    break;
+                case 0x004F:
+                    ISA = "LSI Logic 16-bit DSP Processor";
+                    break;
+                case 0x0050:
+                    ISA = "Donald Knuth's educational 64-bit processor";
+                    break;
+                case 0x0051:
+                    ISA = "Harvard University machine-independent object files";
+                    break;
+                case 0x0052:
+                    ISA = "SiTera Prism";
+                    break;
+                case 0x0053:
+                    ISA = "Atmel AVR 8-bit microcontroller";
+                    break;
+                case 0x0054:
+                    ISA = "Fujitsu FR30";
+                    break;
+                case 0x0055:
+                    ISA = "Mitsubishi D10V";
+                    break;
+                case 0x0056:
+                    ISA = "Mitsubishi D30V";
+                    break;
+                case 0x0057:
+                    ISA = "NEC v850";
+                    break;
+                case 0x0058:
+                    ISA = "Mitsubishi M32R";
+                    break;
+                case 0x0059:
+                    ISA = "Matsushita MN10300";
+                    break;
+                case 0x005A:
+                    ISA = "Matsushita MN10200";
+                    break;
+                case 0x005B:
+                    ISA = "picoJava";
+                    break;
+                case 0x005C:
+                    ISA = "OpenRISC 32-bit embedded processor";
+                    break;
+                case 0x005D:
+                    ISA = "ARC Cores Tangent-A5";
+                    break;
+                case 0x005E:
+                    ISA = "Tensilica Xtensa Architecture";
+                    break;
+                case 0x005F:
+                    ISA = "Alphamosaic VideoCore processor";
+                    break;
+                case 0x0060:
+                    ISA = "Thompson Multimedia General Purpose Processor";
+                    break;
+                case 0x0061:
+                    ISA = "National Semiconductor 32000 series";
+                    break;
+                case 0x0062:
+                    ISA = "Tenor Network TPC processor";
+                    break;
+                case 0x0063:
+                    ISA = "Trebia SNP 1000 processor";
+                    break;
+                case 0x0064:
+                    ISA = "STMicroelectronics (www.st.com) ST200 microcontroller";
+                    break;
+                case 0x008C:
+                    ISA = "TMS320C6000 Family";
+                    break;
+                case 0x00AF:
+                    ISA = "MCST Elbrus e2k";
+                    break;
+                case 0x00B7:
+                    ISA = "ARM 64-bits (ARMv8/Aarch64)";
+                    break;
+                case 0x00F3:
+                    ISA = "RISC-V";
+                    break;
+                case 0x00F7:
+                    ISA = "Berkeley Packet Filter";
+                    break;
+                case 0x0101:
+                    ISA = "WDC 65C816";
+                    break;
+                default:
+                    ISA = "Unimplemented";
+                    break;
+            }
+            ehResult.push("Instruction Set Architecture:".padEnd(align) + ISA);
+
+            ehResult.push("ELF Version:".padEnd(align) + `${stream.readInt(4, endianness)}`);
+
+            const readSize = format === 1 ? 4 : 8;
+            entry = stream.readInt(readSize, endianness);
+            phoff = stream.readInt(readSize, endianness);
+            shoff = stream.readInt(readSize, endianness);
+            ehResult.push("Entry Point:".padEnd(align) + `0x${Utils.hex(entry)}`);
+            ehResult.push("Entry PHOFF:".padEnd(align) + `0x${Utils.hex(phoff)}`);
+            ehResult.push("Entry SHOFF:".padEnd(align) + `0x${Utils.hex(shoff)}`);
+
+            const flags = stream.readInt(4, endianness);
+            ehResult.push("Flags:".padEnd(align) + `${Utils.bin(flags)}`);
+
+            ehResult.push("ELF Header Size:".padEnd(align) + `${stream.readInt(2, endianness)} bytes`);
+            ehResult.push("Program Header Size:".padEnd(align) + `${stream.readInt(2, endianness)} bytes`);
+            phEntries = stream.readInt(2, endianness);
+            ehResult.push("Program Header Entries:".padEnd(align) + phEntries);
+            shentSize = stream.readInt(2, endianness);
+            ehResult.push("Section Header Size:".padEnd(align) + shentSize + " bytes");
+            shEntries = stream.readInt(2, endianness);
+            ehResult.push("Section Header Entries:".padEnd(align) + shEntries);
+            shstrtab = stream.readInt(2, endianness);
+            ehResult.push("Section Header Names:".padEnd(align) + shstrtab);
+
+            return ehResult.join("\n");
+        }
+
+        /**
+         * This function parses and extracts relevant information from a Program Header.
+         *
+         * @param {stream} stream
+         * @returns {string}
+         */
+        function programHeader(stream) {
+            /**
+             * A Program Header is comprised of the following structures depending on the binary's format.
+             *
+             * p_type       - 4 Bytes identifying the type of the segment.
+             *
+             * 32-bit:
+             *      p_offset    - 4 Bytes specifying the offset of the segment.
+             *      p_vaddr     - 4 Bytes specifying the virtual address of the segment in memory.
+             *      p_paddr     - 4 Bytes specifying the physical address of the segment in memory.
+             *      p_filesz    - 4 Bytes specifying the size in bytes of the segment in the file image.
+             *      p_memsz     - 4 Bytes specifying the size in bytes of the segment in memory.
+             *      p_flags     - 4 Bytes identifying the segment dependent flags.
+             *      p_align     - 4 Bytes set to 0 or 1 for alignment or no alignment, respectively.
+             *
+             * 64-bit:
+             *      p_flags     - 4 Bytes identifying segment dependent flags.
+             *      p_offset    - 8 Bytes specifying the offset of the segment.
+             *      p_vaddr     - 8 Bytes specifying the virtual address of the segment in memory.
+             *      p_paddr     - 8 Bytes specifying the physical address of the segment in memory.
+             *      p_filesz    - 8 Bytes specifying the size in bytes of the segment in the file image.
+             *      p_memsz     - 8 Bytes specifying the size in bytes of the segment in memory.
+             *      p_align     - 8 Bytes set to 0 or 1 for alignment or no alignment, respectively.
+             */
+
+            /**
+             * This function decodes the flags bitmask for the Program Header.
+             *
+             * @param {integer} flags
+             * @returns {string}
+             */
+            function readFlags(flags) {
+                const result = [];
+                if (flags & 0x1)
+                    result.push("Execute");
+                if (flags & 0x2)
+                    result.push("Write");
+                if (flags & 0x4)
+                    result.push("Read");
+                if (flags &  0xf0000000)
+                    result.push("Unspecified");
+                return result.join(",");
+            }
+
+            const phResult = [];
+
+            let pType = "";
+            const programHeaderType = stream.readInt(4, endianness);
+            switch (true) {
+                case (programHeaderType === 0x00000000):
+                    pType = "Unused";
+                    break;
+                case (programHeaderType === 0x00000001):
+                    pType = "Loadable Segment";
+                    break;
+                case (programHeaderType === 0x00000002):
+                    pType = "Dynamic linking information";
+                    break;
+                case (programHeaderType === 0x00000003):
+                    pType = "Interpreter Information";
+                    break;
+                case (programHeaderType === 0x00000004):
+                    pType = "Auxiliary Information";
+                    break;
+                case (programHeaderType === 0x00000005):
+                    pType = "Reserved";
+                    break;
+                case (programHeaderType === 0x00000006):
+                    pType = "Program Header Table";
+                    break;
+                case (programHeaderType === 0x00000007):
+                    pType = "Thread-Local Storage Template";
+                    break;
+                case (programHeaderType >= 0x60000000 && programHeaderType <= 0x6FFFFFFF):
+                    pType = "Reserved Inclusive Range. OS Specific";
+                    break;
+                case (programHeaderType >= 0x70000000 && programHeaderType <= 0x7FFFFFFF):
+                    pType = "Reserved Inclusive Range. Processor Specific";
+                    break;
+                default:
+                    break;
+
+            }
+            phResult.push("Program Header Type:".padEnd(align) + pType);
+
+            if (format === 2)
+                phResult.push("Flags:".padEnd(align) + readFlags(stream.readInt(4, endianness)));
+
+            const readSize = format === 1? 4 : 8;
+            phResult.push("Offset Of Segment:".padEnd(align) + `${stream.readInt(readSize, endianness)}`);
+            phResult.push("Virtual Address of Segment:".padEnd(align) + `${stream.readInt(readSize, endianness)}`);
+            phResult.push("Physical Address of Segment:".padEnd(align) + `${stream.readInt(readSize, endianness)}`);
+            phResult.push("Size of Segment:".padEnd(align) + `${stream.readInt(readSize, endianness)} bytes`);
+            phResult.push("Size of Segment in Memory:".padEnd(align) + `${stream.readInt(readSize, endianness)} bytes`);
+
+            if (format === 1)
+                phResult.push("Flags:".padEnd(align) + readFlags(stream.readInt(4, endianness)));
+
+            stream.moveForwardsBy(readSize);
+
+            return phResult.join("\n");
+        }
+
+        /**
+         * This function parses and extracts relevant information from a Section Header.
+         *
+         * @param {stream} stream
+         * @returns {string}
+         */
+        function sectionHeader(stream) {
+            /**
+             * A Section Header is comprised of the following structures depending on the binary's format.
+             *
+             * sh_name      - 4 Bytes identifying the offset into the .shstrtab for the name of this section.
+             * sh_type      - 4 Bytes identifying the type of this header.
+             *
+             * 32-bit:
+             *      sh_flags        - 4 Bytes identifying section specific flags.
+             *      sh_addr         - 4 Bytes identifying the virtual address of the section in memory.
+             *      sh_offset       - 4 Bytes identifying the offset of the section in the file.
+             *      sh_size         - 4 Bytes specifying the size in bytes of the section in the file image.
+             *      sh_link         - 4 Bytes identifying the index of an associated section.
+             *      sh_info         - 4 Bytes specifying extra information about the section.
+             *      sh_addralign    - 4 Bytes containing the alignment for the section.
+             *      sh_entsize      - 4 Bytes specifying the size, in bytes, of each entry in the section.
+             *
+             * 64-bit:
+             *      sh_flags        - 8 Bytes identifying section specific flags.
+             *      sh_addr         - 8 Bytes identifying the virtual address of the section in memory.
+             *      sh_offset       - 8 Bytes identifying the offset of the section in the file.
+             *      sh_size         - 8 Bytes specifying the size in bytes of the section in the file image.
+             *      sh_link         - 4 Bytes identifying the index of an associated section.
+             *      sh_info         - 4 Bytes specifying extra information about the section.
+             *      sh_addralign    - 8 Bytes containing the alignment for the section.
+             *      sh_entsize      - 8 Bytes specifying the size, in bytes, of each entry in the section.
+             */
+            const shResult = [];
+
+            const nameOffset = stream.readInt(4, endianness);
+            let type = "";
+            const shType = stream.readInt(4, endianness);
+            switch (true) {
+                case (shType === 0x00000001):
+                    type = "Program Data";
+                    break;
+                case (shType === 0x00000002):
+                    type = "Symbol Table";
+                    break;
+                case (shType === 0x00000003):
+                    type = "String Table";
+                    break;
+                case (shType === 0x00000004):
+                    type = "Relocation Entries with Addens";
+                    break;
+                case (shType === 0x00000005):
+                    type = "Symbol Hash Table";
+                    break;
+                case (shType === 0x00000006):
+                    type = "Dynamic Linking Information";
+                    break;
+                case (shType === 0x00000007):
+                    type = "Notes";
+                    break;
+                case (shType === 0x00000008):
+                    type = "Program Space with No Data";
+                    break;
+                case (shType === 0x00000009):
+                    type = "Relocation Entries with no Addens";
+                    break;
+                case (shType === 0x0000000A):
+                    type = "Reserved";
+                    break;
+                case (shType === 0x0000000B):
+                    type = "Dynamic Linker Symbol Table";
+                    break;
+                case (shType === 0x0000000E):
+                    type = "Array of Constructors";
+                    break;
+                case (shType === 0x0000000F):
+                    type = "Array of Destructors";
+                    break;
+                case (shType === 0x00000010):
+                    type = "Array of pre-constructors";
+                    break;
+                case (shType === 0x00000011):
+                    type = "Section group";
+                    break;
+                case (shType === 0x00000012):
+                    type = "Extended section indices";
+                    break;
+                case (shType === 0x00000013):
+                    type = "Number of defined types";
+                    break;
+                case (shType >= 0x60000000 && shType <= 0x6fffffff):
+                    type = "OS-specific";
+                    break;
+                case (shType >= 0x70000000 && shType <= 0x7fffffff):
+                    type = "Processor-specific";
+                    break;
+                case (shType >= 0x80000000 && shType <= 0x8fffffff):
+                    type = "Application-specific";
+                    break;
+                default:
+                    type = "Unused";
+                    break;
+            }
+
+            shResult.push("Type:".padEnd(align) + type);
+
+            let nameResult = "";
+            if (type !== "Unused") {
+                nameResult = readString(stream, namesOffset, nameOffset);
+                shResult.push("Section Name: ".padEnd(align) + nameResult);
+            }
+
+            const readSize = (format === 1) ? 4 : 8;
+
+            const flags = stream.readInt(readSize, endianness);
+            const shFlags = [];
+            const bitMasks = [
+                [0x00000001, "Writable"],
+                [0x00000002, "Alloc"],
+                [0x00000004, "Executable"],
+                [0x00000010, "Merge"],
+                [0x00000020, "Strings"],
+                [0x00000040, "SHT Info Link"],
+                [0x00000080, "Link Order"],
+                [0x00000100, "OS Specific Handling"],
+                [0x00000200, "Group"],
+                [0x00000400, "Thread Local Data"],
+                [0x0FF00000, "OS-Specific"],
+                [0xF0000000, "Processor Specific"],
+                [0x04000000, "Special Ordering (Solaris)"],
+                [0x08000000, "Excluded (Solaris)"]
+            ];
+            bitMasks.forEach(elem => {
+                if (flags & elem[0])
+                    shFlags.push(elem[1]);
+            });
+            shResult.push("Flags:".padEnd(align) + shFlags);
+
+            const vaddr = stream.readInt(readSize, endianness);
+            shResult.push("Section Vaddr in memory:".padEnd(align) + vaddr);
+
+            const shoffset = stream.readInt(readSize, endianness);
+            shResult.push("Offset of the section:".padEnd(align) + shoffset);
+
+            const secSize = stream.readInt(readSize, endianness);
+            shResult.push("Section Size:".padEnd(align) + secSize);
+
+            const associatedSection = stream.readInt(4, endianness);
+            shResult.push("Associated Section:".padEnd(align) + associatedSection);
+
+            const extraInfo = stream.readInt(4, endianness);
+            shResult.push("Section Extra Information:".padEnd(align) + extraInfo);
+
+            // Jump over alignment field.
+            stream.moveForwardsBy(readSize);
+            const entSize = stream.readInt(readSize, endianness);
+            switch (nameResult) {
+                case ".strtab":
+                    strtabOffset = shoffset;
+                    break;
+                case ".symtab":
+                    symtabOffset = shoffset;
+                    symtabSize = secSize;
+                    symtabEntSize = entSize;
+                    break;
+                default:
+                    break;
+            }
+            return shResult.join("\n");
+        }
+
+        /**
+         * This function returns the offset of the Section Header Names Section.
+         *
+         * @param {stream} stream
+         */
+        function getNamesOffset(stream) {
+            const preMove = stream.position;
+            stream.moveTo(shoff + (shentSize * shstrtab));
+            if (format === 1) {
+                stream.moveForwardsBy(0x10);
+                namesOffset = stream.readInt(4, endianness);
+            } else {
+                stream.moveForwardsBy(0x18);
+                namesOffset = stream.readInt(8, endianness);
+            }
+            stream.position = preMove;
+        }
+
+        /**
+         * This function returns a symbol's name from the string table.
+         *
+         * @param {stream} stream
+         * @returns {string}
+         */
+        function getSymbols(stream) {
+            /**
+             * The Symbol Table is comprised of Symbol Table Entries whose structure depends on the binary's format.
+             *
+             * 32-bit:
+             *      st_name         - 4 Bytes specifying an index in the files symbol string table.
+             *      st_value        - 4 Bytes identifying the value associated with the symbol.
+             *      st_size         - 4 Bytes specifying the size associated with the symbol (this is not the size of the symbol).
+             *      st_info         - A byte specifying the type and binding of the symbol.
+             *      st_other        - A byte specifying the symbol's visibility.
+             *      st_shndx        - 2 Bytes identifying the section that this symbol is related to.
+             *
+             * 64-bit:
+             *      st_name         - 4 Bytes specifying an index in the files symbol string table.
+             *      st_info         - A byte specifying the type and binding of the symbol.
+             *      st_other        - A byte specifying the symbol's visibility.
+             *      st_shndx        - 2 Bytes identifying the section that this symbol is related to.
+             *      st_value        - 8 Bytes identifying the value associated with the symbol.
+             *      st_size         - 8 Bytes specifying the size associated with the symbol (this is not the size of the symbol).
+             */
+            const nameOffset = stream.readInt(4, endianness);
+            stream.moveForwardsBy(format === 2 ? 20 : 12);
+            return readString(stream, strtabOffset, nameOffset);
+        }
+
+        input = new Uint8Array(input);
+        const stream = new Stream(input);
+        const result = ["=".repeat(align) + " ELF Header " + "=".repeat(align)];
+        result.push(elfHeader(stream) + "\n");
+
+        getNamesOffset(stream);
+
+        result.push("=".repeat(align) + " Program Header " + "=".repeat(align));
+        stream.moveTo(phoff);
+        for (let i = 0; i < phEntries; i++)
+            result.push(programHeader(stream) + "\n");
+
+        result.push("=".repeat(align) + " Section Header " + "=".repeat(align));
+        stream.moveTo(shoff);
+        for (let i = 0; i < shEntries; i++)
+            result.push(sectionHeader(stream) + "\n");
+
+        result.push("=".repeat(align) + " Symbol Table " + "=".repeat(align));
+
+        stream.moveTo(symtabOffset);
+        let elem = "";
+        for (let i = 0; i < (symtabSize / symtabEntSize); i++)
+            if ((elem = getSymbols(stream)) !== "")
+                result.push("Symbol Name:".padEnd(align) + elem);
+
+        return result.join("\n");
+    }
+
+}
+
+export default ELFInfo;

+ 1 - 0
tests/operations/index.mjs

@@ -113,6 +113,7 @@ import "./tests/JA3SFingerprint.mjs";
 import "./tests/HASSH.mjs";
 import "./tests/GetAllCasings.mjs";
 import "./tests/SIGABA.mjs";
+import "./tests/ELFInfo.mjs";
 
 
 // Cannot test operations that use the File type yet

ファイルの差分が大きいため隠しています
+ 8 - 0
tests/operations/tests/ELFInfo.mjs


+ 375 - 0
tests/samples/Executables.mjs

@@ -0,0 +1,375 @@
+/**
+ * Executables in various formats for use in tests.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2022
+ * @license Apache-2.0
+ */
+
+/**
+ * ---------------ELF Header---------------
+ * 7f454c46         - Magic:            .ELF
+ * 01               - Format:           32 bit
+ * 01               - Endianness:       Little
+ * 01               - ELF Version:      1
+ * 00               - Target ABI:       System V
+ * 00               - ABI Version:      0
+ * 00000000000000   - Padding
+ * 0200             - File Type:        Executable File
+ * 0300             - ISA:              x86
+ * 01000000         - ELF Version:      1
+ * 50210608         - Entry Point:      0x8062150
+ * 34000000         - PH Offset:        0x34
+ * 54000000         - SH Offset:        0x54
+ * 00000000         - Flags:            0
+ * 3400             - ELF Header Size:  0x34
+ * 2000             - PH Header Size:   0x20
+ * 0100             - PH Entries:       1
+ * 2800             - SH Size:          0x28
+ * 0300             - SH Entries:       0x3
+ * 0000             - SH Names Offset:  0x0
+ *
+ * -------------Program Header-------------
+ * 06000000         - PH Type:          Program Header Table
+ * 34000000         - Segment Offset:   0x34
+ * 34800408         - VAddr of segment: 134512692
+ * 34800408         - PAddr of segment: 134512692
+ * 00010000         - Size of segment:  256
+ * 00010000         - Size of segment:  256
+ * 05000000         - Flags:            Execute,Read
+ * 04000000         - Alignment
+ *
+ * --------------SH .shstrtab--------------
+ * 00000000         - SH Name Offset:   0
+ * 03000000         - SH Type:          String Table
+ * 00000000         - Flags:
+ * 00000000         - VAddr of section: 0
+ * cc000000         - Section offset:   204
+ * 1c000000         - Section size:     28
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 00000000         - Alignment
+ * 00000000         - Entry Size:       0
+ *
+ * ---------------SH .symtab---------------
+ * 09000000         - SH Name Offset:   9
+ * 02000000         - SH Type:          Symbol Table
+ * 00000000         - Flags:
+ * 00000000         - VAddr of section: 0
+ * e6000000         - Section offset:   230
+ * 10000000         - Section size:     16
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 00000000         - Alignment
+ * 10000000         - Entry Size:       16
+ *
+ * ---------------SH .strtab---------------
+ * 11000000         - SH Name Offset:   17
+ * 03000000         - SH Type:          String Table
+ * 00000000         - Flags:
+ * 00000000         - VAddr of section: 0
+ * f5000000         - Section offset:   245
+ * 04000000         - Section size:     4
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 00000000         - Alignment
+ * 00000000         - Entry Size:       0
+ *
+ * ---------------.shstrtab---------------
+ * 2e73687374726162002e73796d746162002e73747274616200 - .shstrab\0.symtab\0.strtab\0
+ *
+ * ----------------.symtab----------------
+ * 00000000         - Name Offset:      0
+ * 00000000         - Value:            0
+ * 00000000         - Size:             0
+ * 00               - Info
+ * 00               - other
+ * 0000             - shdx
+ *
+ * ----------------.strtab----------------
+ * 74657374         - test
+ */
+export const ELF32_LE = "7f454c46010101000000000000000000020003000100000050210608340000005400000000000000340020000100280003000000" +
+                        "0600000034000000348004083480040800010000000100000500000004000000" +
+                        "00000000030000000000000000000000cc0000001c00000000000000000000000000000000000000" +
+                        "09000000020000000000000000000000e60000001000000000000000000000000000000010000000" +
+                        "11000000030000000000000000000000f50000000400000000000000000000000000000000000000" +
+                        "2e73687374726162002e73796d746162002e73747274616200" +
+                        "00000000000000000000000000000000" +
+                        "74657374";
+
+/**
+ * ---------------ELF Header---------------
+ * 7f454c46         - Magic:            .ELF
+ * 01               - Format:           32 bit
+ * 02               - Endianness:       Big
+ * 01               - ELF Version:      1
+ * 00               - Target ABI:       System V
+ * 00               - ABI Version:      0
+ * 00000000000000   - Padding
+ * 0002             - File Type:        Executable File
+ * 0003             - ISA:              x86
+ * 00000001         - ELF Version:      1
+ * 08062150         - Entry Point:      0x8062150
+ * 00000034         - PH Offset:        0x34
+ * 00000054         - SH Offset:        0x54
+ * 00000000         - Flags:            0
+ * 0034             - ELF Header Size:  0x34
+ * 0020             - PH Header Size:   0x20
+ * 0001             - PH Entries:       1
+ * 0028             - SH Size:          0x28
+ * 0003             - SH Entries:       0x3
+ * 0000             - SH Names Offset:  0x0
+ *
+ * -------------Program Header-------------
+ * 00000006         - PH Type:          Program Header Table
+ * 00000034         - Segment Offset:   0x34
+ * 08048034         - VAddr of segment: 134512692
+ * 08048034         - PAddr of segment: 134512692
+ * 00000100         - Size of segment:  256
+ * 00000100         - Size of segment:  256
+ * 00000005         - Flags:            Execute,Read
+ * 00000004         - Alignment
+ *
+ * --------------SH .shstrtab--------------
+ * 00000000         - SH Name Offset:   0
+ * 00000003         - SH Type:          String Table
+ * 00000000         - Flags:
+ * 00000000         - VAddr of section: 0
+ * 000000cc         - Section offset:   204
+ * 0000001c         - Section size:     28
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 00000000         - Alignment
+ * 00000000         - Entry Size:       0
+ *
+ * ---------------SH .symtab---------------
+ * 00000009         - SH Name Offset:   9
+ * 00000002         - SH Type:          Symbol Table
+ * 00000000         - Flags:
+ * 00000000         - VAddr of section: 0
+ * 000000e6         - Section offset:   230
+ * 00000010         - Section size:     16
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 00000000         - Alignment
+ * 00000010         - Entry Size:       16
+ *
+ * ---------------SH .strtab---------------
+ * 00000011         - SH Name Offset:   17
+ * 00000003         - SH Type:          String Table
+ * 00000000         - Flags:
+ * 00000000         - VAddr of section: 0
+ * 000000f5         - Section offset:   245
+ * 00000004         - Section size:     4
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 00000000         - Alignment
+ * 00000000         - Entry Size:       0
+ *
+ * ---------------.shstrtab---------------
+ * 2e73687374726162002e73796d746162002e73747274616200 - .shstrab\0.symtab\0.strtab\0
+ *
+ * ----------------.symtab----------------
+ * 00000000         - Name Offset:      0
+ * 00000000         - Value:            0
+ * 00000000         - Size:             0
+ * 00               - Info
+ * 00               - other
+ * 0000             - shdx
+ *
+ * ----------------.strtab----------------
+ * 74657374         - test
+ */
+export const ELF32_BE =     "7f454c46010201000000000000000000000200030000000108062150000000340000005400000000003400200001002800030000" +
+                            "0000000600000034080480340804803400000100000001000000000500000004" +
+                            "00000000000000030000000000000000000000cc0000001c00000000000000000000000000000000" +
+                            "00000009000000020000000000000000000000e60000001000000000000000000000000000000010" +
+                            "00000011000000030000000000000000000000f50000000400000000000000000000000000000000" +
+                            "2e73687374726162002e73796d746162002e73747274616200" +
+                            "00000000000000000000000000000000" +
+                            "74657374";
+
+/**
+ * ---------------ELF Header---------------
+ * 7f454c46         - Magic:            .ELF
+ * 02               - Format:           64 bit
+ * 01               - Endianness:       Little
+ * 01               - ELF Version:      1
+ * 00               - Target ABI:       System V
+ * 00               - ABI Version:      0
+ * 00000000000000   - Padding
+ * 0200             - File Type:        Executable File
+ * 3e00             - ISA:              AMD x86-64
+ * 01000000         - ELF Version:      1
+ * 5021060800000000 - Entry Point:      0x8062150
+ * 4000000000000000 - PH Offset:        0x40
+ * 7800000000000000 - SH Offset:        0x78
+ * 00000000         - Flags:            0
+ * 4000             - ELF Header Size:  0x40
+ * 3800             - PH Header Size:   0x38
+ * 0100             - PH Entries:       1
+ * 4000             - SH Size:          0x40
+ * 0300             - SH Entries:       0x3
+ * 0000             - SH Names Offset:  0x0
+ *
+ * -------------Program Header-------------
+ * 06000000         - PH Type:          Program Header Table
+ * 05000000         - Flags:            Execute,Read
+ * 3400000000000000 - Segment Offset:   0x34
+ * 3480040800000000 - VAddr of segment: 134512692
+ * 3480040800000000 - PAddr of segment: 134512692
+ * 0001000000000000 - Size of segment:  256
+ * 0001000000000000 - Size of segment:  256
+ * 0400000000000000 - Alignment
+ *
+ * --------------SH .shstrtab--------------
+ * 00000000         - SH Name Offset:   0
+ * 03000000         - SH Type:          String Table
+ * 0000000000000000 - Flags:
+ * 0000000000000000 - VAddr of section: 0
+ * 3801000000000000 - Section offset:   312
+ * 1c00000000000000 - Section size:     28
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 0000000000000000 - Alignment
+ * 0000000000000000 - Entry Size:       0
+ *
+ * ---------------SH .symtab---------------
+ * 09000000         - SH Name Offset:   9
+ * 02000000         - SH Type:          Symbol Table
+ * 0000000000000000 - Flags:
+ * 0000000000000000 - VAddr of section: 0
+ * 5001000000000000 - Section offset:   336
+ * 1000000000000000 - Section size:     16
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 0000000000000000 - Alignment
+ * 1800000000000000 - Entry Size:       24
+ *
+ * ---------------SH .strtab---------------
+ * 11000000         - SH Name Offset:   17
+ * 03000000         - SH Type:          String Table
+ * 0000000000000000 - Flags:
+ * 0000000000000000 - VAddr of section: 0
+ * 6901000000000000 - Section offset:   361
+ * 0400000000000000 - Section size:     4
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 0000000000000000 - Alignment
+ * 0000000000000000 - Entry Size:       0
+ *
+ * ---------------.shstrtab---------------
+ * 2e73687374726162002e73796d746162002e73747274616200 - .shstrab\0.symtab\0.strtab\0
+ *
+ * ----------------.symtab----------------
+ * 00000000         - Name Offset:      0
+ * 00               - Info
+ * 00               - other
+ * 0000             - shdx
+ * 0000000000000000 - Value:            0
+ * 0000000000000000 - Size:             0
+ *
+ * ----------------.strtab----------------
+ * 74657374         - test
+ */
+export const ELF64_LE = "7f454c4602010100000000000000000002003e000100000050210608000000004000000000000000780000000000000000000000400038000100400003000000" +
+                        "0600000005000000340000000000000034800408000000003480040800000000000100000000000000010000000000000400000000000000" +
+                        "00000000030000000000000000000000000000000000000038010000000000001c00000000000000000000000000000000000000000000000000000000000000" +
+                        "09000000020000000000000000000000000000000000000050010000000000001000000000000000000000000000000000000000000000001800000000000000" +
+                        "11000000030000000000000000000000000000000000000069010000000000000400000000000000000000000000000000000000000000000000000000000000" +
+                        "2e73687374726162002e73796d746162002e73747274616200" +
+                        "000000000000000000000000000000000000000000000000" +
+                        "74657374";
+
+/**
+ * ---------------ELF Header---------------
+ * 7f454c46         - Magic:            .ELF
+ * 02               - Format:           64 bit
+ * 02               - Endianness:       Big
+ * 01               - ELF Version:      1
+ * 00               - Target ABI:       System V
+ * 00               - ABI Version:      0
+ * 00000000000000   - Padding
+ * 0002             - File Type:        Executable File
+ * 003e             - ISA:              AMD x86-64
+ * 00000001         - ELF Version:      1
+ * 0000000008062150 - Entry Point:      0x8062150
+ * 0000000000000040 - PH Offset:        0x40
+ * 0000000000000078 - SH Offset:        0x78
+ * 00000000         - Flags:            0
+ * 0040             - ELF Header Size:  0x40
+ * 0038             - PH Header Size:   0x38
+ * 0001             - PH Entries:       1
+ * 0040             - SH Size:          0x40
+ * 0003             - SH Entries:       0x3
+ * 0000             - SH Names Offset:  0x0
+ *
+ * -------------Program Header-------------
+ * 00000006         - PH Type:          Program Header Table
+ * 00000005         - Flags:            Execute,Read
+ * 0000000000000034 - Segment Offset:   0x34
+ * 0000000008048034 - VAddr of segment: 134512692
+ * 0000000008048034 - PAddr of segment: 134512692
+ * 0000000000000100 - Size of segment:  256
+ * 0000000000000100 - Size of segment:  256
+ * 0400000000000000 - Alignment
+ *
+ * --------------SH .shstrtab--------------
+ * 00000000         - SH Name Offset:   0
+ * 00000003         - SH Type:          String Table
+ * 0000000000000000 - Flags:
+ * 0000000000000000 - VAddr of section: 0
+ * 0000000000000138 - Section offset:   312
+ * 000000000000001c - Section size:     28
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 0000000000000000 - Alignment
+ * 0000000000000000 - Entry Size:       0
+ *
+ * ---------------SH .symtab---------------
+ * 00000009         - SH Name Offset:   9
+ * 00000002         - SH Type:          Symbol Table
+ * 0000000000000000 - Flags:
+ * 0000000000000000 - VAddr of section: 0
+ * 0000000000000150 - Section offset:   336
+ * 0000000000000010 - Section size:     16
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 0000000000000000 - Alignment
+ * 0000000000000018 - Entry Size:       24
+ *
+ * ---------------SH .strtab---------------
+ * 00000011         - SH Name Offset:   17
+ * 00000003         - SH Type:          String Table
+ * 0000000000000000 - Flags:
+ * 0000000000000000 - VAddr of section: 0
+ * 0000000000000169 - Section offset:   361
+ * 0000000000000004 - Section size:     4
+ * 00000000         - Associated:       0
+ * 00000000         - Extra Info:       0
+ * 0000000000000000 - Alignment
+ * 0000000000000000 - Entry Size:       0
+ *
+ * ---------------.shstrtab---------------
+ * 2e73687374726162002e73796d746162002e73747274616200 - .shstrab\0.symtab\0.strtab\0
+ *
+ * ----------------.symtab----------------
+ * 00000000         - Name Offset:      0
+ * 00               - Info
+ * 00               - other
+ * 0000             - shdx
+ * 0000000000000000 - Value:            0
+ * 0000000000000000 - Size:             0
+ *
+ * ----------------.strtab----------------
+ * 74657374         - test
+ */
+export const ELF64_BE =     "7f454c460202010000000000000000000002003e0000000100000000080621500000000000000040000000000000007800000000004000380001004000030000" +
+                            "0000000600000005000000000000003400000000080480340000000008048034000000000000010000000000000001000400000000000000" +
+                            "0000000000000003000000000000000000000000000000000000000000000138000000000000001c000000000000000000000000000000000000000000000000" +
+                            "00000009000000020000000000000000000000000000000000000000000001500000000000000010000000000000000000000000000000000000000000000018" +
+                            "00000011000000030000000000000000000000000000000000000000000001690000000000000004000000000000000000000000000000000000000000000000" +
+                            "2e73687374726162002e73796d746162002e73747274616200" +
+                            "000000000000000000000000000000000000000000000000" +
+                            "74657374";

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません