diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/delf.py | 2347 | 
1 files changed, 2347 insertions, 0 deletions
| diff --git a/src/delf.py b/src/delf.py new file mode 100755 index 0000000..c988098 --- /dev/null +++ b/src/delf.py @@ -0,0 +1,2347 @@ +#!/usr/bin/env python3 +# *****************************************************************************/ +# yet another elfdump in python +# Copyright (C) 2018 Farzad Sadeghi + +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA  02110-1301, USA.*/ +# *****************************************************************************/ +import argparse +import code +import os +import subprocess +import sys + +from capstone import CS_ARCH_X86, CS_MODE_64, Cs + +# from capstone.x86 import Cs + + +class ELF_TYPE_SIZES: +    ELF32_HALF = 2 +    ELF64_HALF = 2 +    ELF32_WORD = 4 +    ELF32_SWORD = 4 +    ELF64_WORD = 4 +    ELF64_SWORD = 4 +    ELF32_XWORD = 8 +    ELF32_SXWORD = 8 +    ELF64_XWORD = 8 +    ELF64_SXWORD = 8 +    ELF32_ADDR = 4 +    ELF64_ADDR = 8 +    ELF32_OFF = 4 +    ELF64_OFF = 8 +    ELF32_SECTION = 2 +    ELF64_SECTION = 2 + + +def SigHandler_SIGINT(signum, frame): +    print() +    sys.exit(0) + + +class CLIArgParser(object): +    def __init__(self): +        parser = argparse.ArgumentParser() +        parser.add_argument("--dbg", action="store_true", help="debug", default=False) +        parser.add_argument( +            "--obj", +            type=str, +            help="path to the executbale, shared object " +            "or object you want to load in bruiser", +        ) +        parser.add_argument( +            "--header", action="store_true", help="dump headers", default=False +        ) +        parser.add_argument( +            "--symboltable", +            action="store_true", +            help="dump symbol table", +            default=False, +        ) +        parser.add_argument( +            "--phdrs", +            action="store_true", +            help="dump program haeders", +            default=False, +        ) +        parser.add_argument( +            "--shdrs", +            action="store_true", +            help="dump section haeders", +            default=False, +        ) +        parser.add_argument( +            "--symbolindex", +            action="store_true", +            help="dump symbol index", +            default=False, +        ) +        parser.add_argument( +            "--stentries", +            action="store_true", +            help="dump section table entries", +            default=False, +        ) +        parser.add_argument( +            "--objcode", +            action="store_true", +            help="dump objects", +            default=False, +        ) +        parser.add_argument( +            "--test", action="store_true", help="test switch", default=False +        ) +        parser.add_argument( +            "--test2", action="store_true", help="test switch 2", default=False +        ) +        parser.add_argument( +            "--listdso", action="store_true", help="list DSOs", default=False +        ) +        parser.add_argument( +            "--funcs", +            action="store_true", +            help="dump functions", +            default=False, +        ) +        parser.add_argument( +            "--objs", action="store_true", help="dump objects", default=False +        ) +        parser.add_argument( +            "--dynsym", +            action="store_true", +            help="dump dynamic symbol table", +            default=False, +        ) +        parser.add_argument( +            "--dlpath", +            action="store_true", +            help="dump dynamic linker path", +            default=False, +        ) +        parser.add_argument( +            "--phdynent", +            action="store_true", +            help="dump ph PT_DYNAMIC entries", +            default=False, +        ) +        parser.add_argument("--section", type=str, help="dump a section") +        parser.add_argument( +            "--dumpfunc", type=str, help="dump a functions machine code" +        ) +        parser.add_argument( +            "--dumpfuncasm", type=str, help="dump a functions assembly code" +        ) +        parser.add_argument( +            "--textasm", +            action="store_true", +            help="disassemble the text section", +            default=False, +        ) +        parser.add_argument( +            "--dynsecents", +            action="store_true", +            help="dynamic section entries", +            default=False, +        ) +        parser.add_argument( +            "--reladyn", +            action="store_true", +            help=".rela.dyn entries", +            default=False, +        ) +        parser.add_argument( +            "--relaplt", +            action="store_true", +            help=".rela.plt entries", +            default=False, +        ) +        parser.add_argument( +            "--rodata", action="store_true", help="dump .rodata", default=False +        ) +        parser.add_argument( +            "--disass", +            type=str, +            help="disassembls a section by " "name in section headers", +        ) +        parser.add_argument( +            "--disassp", +            type=int, +            help="disassembls a section " "by index in program headers", +        ) +        parser.add_argument( +            "--got", +            action="store_true", +            help="dump .got section", +            default=False, +        ) +        parser.add_argument( +            "--gotplt", +            action="store_true", +            help="dump .got.plt section", +            default=False, +        ) +        self.args = parser.parse_args() +        if self.args.obj is None: +            raise Exception( +                "no object file provided. " "please specify an object with --obj." +            ) + + +def byte2int(value, sign=False): +    return int.from_bytes(value, byteorder="little", signed=sign) + + +def byte2hex(value): +    return hex(int.from_bytes(value, byteorder="little", signed=False)) + + +def LEB128UnsignedDecode(bytelist): +    result = 0 +    shift = 0 +    for byte in bytelist: +        result |= (byte & 0x7F) << shift +        if (byte & 0x80) == 0: +            break +        shift += 7 +    return result + + +def LEB128SignedDecode(bytelist): +    result = 0 +    shift = 0 +    for byte in bytelist: +        result |= (byte & 0x7F) << shift +        last_byte = byte +        shift += 7 +        if (byte & 0x80) == 0: +            break +    if last_byte & 0x40: +        result |= -(1 << shift) +    return result + + +def LEB128UnsignedEncode(int_val): +    if int_val < 0: +        raise Exception("value must not be negative") +    if int_val == 0: +        return bytes([0]) +    byte_array = bytearray() +    while int_val: +        byte = int_val & 0x7F +        byte_array.append(byte | 0x80) +        int_val >>= 7 +    byte_array[-1] ^= 0x80 +    return byte_array + + +def LEB128SignedEncode(int_val): +    byte_array = bytearray() +    while True: +        byte = int_val & 0x7F +        byte_array.append(byte | 0x80) +        int_val >>= 7 +        if (int_val == 0 and byte & 0x40 == 0) or (int_val == -1 and byte & 0x40): +            byte_array[-1] ^= 0x80 +            break +    return byte_array + + +class ELF_REL: +    def __init__(self, r_offset, r_info): +        self.r_offset = r_offset +        self.r_info = r_info + + +class ELF_RELA: +    def __init__(self, r_offset, r_info, r_addend): +        self.r_offset = r_offset +        self.r_info = r_info +        self.r_addend = r_addend + + +def ffs(offset, header_list, numbered, *args): +    # cn = Colors.green +    ch = Colors.cyan +    cd = Colors.blue +    cb = Colors.BOLD +    ci = Colors.red +    ce = Colors.ENDC +    max_column_width = [] +    lines = [] +    numbers_f = [] +    dummy = [] + +    if numbered: +        numbers_f.extend(range(1, len(args[-1]) + 1)) +        max_column_width.append( +            max([len(repr(number)) for number in numbers_f]) if numbers_f else 6 +        ) +        header_list.insert(0, "idx") + +    for arg in args: +        max_column_width.append( +            max([len(repr(argette)) for argette in arg]) if arg else 6 +        ) + +    index = range(0, len(header_list)) +    for header, width, i in zip(header_list, max_column_width, index): +        max_column_width[i] = max(len(header), width) + offset + +    for i in index: +        dummy.append(ch + cb + header_list[i].ljust(max_column_width[i]) + ce) +    lines.append("".join(dummy)) +    dummy.clear() + +    index2 = range(0, len(args[-1])) +    for i in index2: +        if numbered: +            dummy.append(ci + cb + repr(i).ljust(max_column_width[0]) + ce) +            for arg, width in zip(args, max_column_width[1:]): +                dummy.append(cd + repr(arg[i]).ljust(width) + ce) +        else: +            for arg, width in zip(args, max_column_width): +                dummy.append(cd + repr(arg[i]).ljust(width) + ce) +        lines.append("".join(dummy)) +        dummy.clear() +    return lines + + +def get_section_type_string(number): +    if number == 0x0: +        return "NULL" +    if number == 0x1: +        return "PROGBITS" +    if number == 0x2: +        return "SYMTAB" +    if number == 0x3: +        return "STRTAB" +    if number == 0x4: +        return "RELA" +    if number == 0x5: +        return "HASH" +    if number == 0x6: +        return "DYNAMIC" +    if number == 0x7: +        return "NOTE" +    if number == 0x8: +        return "NOBITS" +    if number == 0x9: +        return "REL" +    if number == 0xA: +        return "SHLIB" +    if number == 0xB: +        return "DYNSYM" +    if number == 0xE: +        return "INIT_ARRAY" +    if number == 0xF: +        return "FINI_ARRAY" +    if number == 0x10: +        return "PREINIT" +    if number == 0x11: +        return "GROUP" +    if number == 0x12: +        return "SYMTAB" +    if number == 0x13: +        return "NUM" +    if number == 0x60000000: +        return "LOOS" +    if number == 0x6FFFFFF6: +        return "GNU_HASH" +    if number == 0x6FFFFFFF: +        return "VERSYM" +    if number == 0x6FFFFFFE: +        return "VERNEED" + + +class sh_type_e: +    SHT_NULL = 0x0 +    SHT_PROGBITS = 0x1 +    SHT_SYMTAB = 0x2 +    SHT_STRTAB = 0x3 +    SHT_RELA = 0x4 +    SHT_HASH = 0x5 +    SHT_DYNAMIC = 0x6 +    SHT_NOTE = 0x7 +    SHT_NOBITS = 0x8 +    SHT_REL = 0x9 +    SHT_SHLIB = 0xA +    SHT_DYNSYM = 0xB +    SHT_INIT_ARRAY = 0xE +    SHT_FINI_ARRAY = 0xF +    SHT_PREINIT = 0x10 +    SHT_GROUP = 0x11 +    SHT_SYMTAB_SHNDX = 0x12 +    SHT_NUM = 0x13 +    SHT_LOOS = 0x60000000 +    GNU_HASH = 0x6FFFFFF6 +    VERSYM = 0x6FFFFFFF +    VERNEED = 0x6FFFFFFE + + +class sh_flags_e: +    SHF_WRITE = 0x1 +    SHF_ALLOC = 0x2 +    SHF_EXECINSTR = 0x4 +    SHF_MERGE = 0x10 +    SHF_STRINGS = 0x20 +    SHF_INFO_LINK = 0x40 +    SHF_LINK_ORDER = 0x80 +    SHF_OS_NONCONFORMING = 0x100 +    SHF_GROUP = 0x200 +    SHF_TLS = 0x400 +    SHF_MASKOS = 0x0FF00000 +    SHF_MASKPROC = 0xF0000000 +    SHF_ORDERED = 0x4000000 +    SHF_EXCLUDE = 0x8000000 + + +class p_type_e: +    PT_NULL = 0x0 +    PT_LOAD = 0x1 +    PT_DYNAMIC = 0x2 +    PT_INTERP = 0x3 +    PT_NOTE = 0x4 +    PT_SHLIB = 0x5 +    PT_PHDR = 0x6 +    PT_LOOS = 0x60000000 +    PT_HIOS = 0x6FFFFFFF +    PT_LOPROC = 0x70000000 +    PT_HIPROC = 0x7FFFFFFF +    GNU_EH_FRAME = 0x6474E550 +    GNU_STACK = 0x6474E551 +    GNU_RELRO = 0x6474E552 + + +def get_ph_type(value): +    if value == p_type_e.PT_NULL: +        return "NULL" +    elif value == p_type_e.PT_LOAD: +        return "LOAD" +    elif value == p_type_e.PT_DYNAMIC: +        return "DYNAMIC" +    elif value == p_type_e.PT_INTERP: +        return "INTERP" +    elif value == p_type_e.PT_NOTE: +        return "NOTE" +    elif value == p_type_e.PT_SHLIB: +        return "SHLIB" +    elif value == p_type_e.PT_PHDR: +        return "PHDR" +    elif value == p_type_e.PT_LOOS: +        return "LOOS" +    elif value == p_type_e.PT_HIOS: +        return "HIOS" +    elif value == p_type_e.PT_LOPROC: +        return "LOPROC" +    elif value == p_type_e.PT_HIPROC: +        return "HIPROC" +    elif value == p_type_e.GNU_EH_FRAME: +        return "GNU_EH_FRAME" +    elif value == p_type_e.GNU_STACK: +        return "GNU_STACK" +    elif value == p_type_e.GNU_RELRO: +        return "GNU_RELRO" +    else: +        return None + + +class ph_dynamic_entry: +    def __init__(self, d_tag, d_un): +        self.d_tag = d_tag +        self.d_un = d_un + + +class elf_seg_flags: +    PF_X = 0x1 +    PF_W = 0x2 +    PF_R = 0x4 + + +def get_elf_seg_flag(value): +    ret = [] +    if value & 0x01 == 1: +        ret.append("X") +    if (value & 0x02) >> 1 == 1: +        ret.append("W") +    if (value & 0x04) >> 2 == 1: +        ret.append("R") +    return "".join(ret) + + +class PH_DYN_TAG_TYPE: +    DT_NULL = 0 +    DT_NEEDED = 1 +    DT_PLTRELSZ = 2 +    DT_PLTGOT = 3 +    DT_HASH = 4 +    DT_STRTAB = 5 +    DT_SYMTAB = 6 +    DT_RELA = 7 +    DT_RELASZ = 8 +    DT_RELAENT = 9 +    DT_STRSZ = 10 +    DT_SYMENT = 11 +    DT_INIT = 12 +    DT_FINI = 13 +    DT_SONAME = 14 +    DT_RPATH = 15 +    DT_SYMBOLIC = 16 +    DT_REL = 17 +    DT_RELSZ = 18 +    DT_RELENT = 19 +    DT_PLTREL = 20 +    DT_DEBUG = 21 +    DT_TEXTREL = 22 +    DT_JMPREL = 23 +    DT_LOPROC = 0x70000000 +    DT_HIPROC = 0x7FFFFFFF +    DT_BIND_NOW = 24 +    DT_INIT_ARRAY = 25 +    DT_FINI_ARRAY = 26 +    DT_INIT_ARRAYSZ = 27 +    DT_FINI_ARRAYSZ = 28 +    DT_RUNPATH = 29 +    DT_FLAGS = 30 +    DT_ENCODING = 32 +    DT_PREINIT_ARRAY = 32 +    DT_PREINIT_ARRAYSZ = 33 +    DT_NUM = 34 +    DT_LOOS = 0x6000000D +    DT_HIOS = 0x6FFFF000 +    DT_PROC_NUM = 0x0 +    DT_MIPS_NUM = 0x0 +    DT_VALRNGLO = 0x6FFFFD00 +    DT_GNU_PRELINKED = 0x6FFFFDF5 +    DT_GNU_CONFLICTSZ = 0x6FFFFDF6 +    DT_GNU_LIBLISTSZ = 0x6FFFFDF7 +    DT_CHECKSUM = 0x6FFFFDF8 +    DT_PLTPADSZ = 0x6FFFFDF9 +    DT_MOVEENT = 0x6FFFFDFA +    DT_MOVESZ = 0x6FFFFDFB +    DT_FEATURE_1 = 0x6FFFFDFC +    DT_POSFLAG_1 = 0x6FFFFDFD +    DT_SYMINSZ = 0x6FFFFDFE +    DT_SYMINENT = 0x6FFFFDFF +    DT_VALRNGHI = 0x6FFFFDFF +    DT_VALNUM = 12 +    DT_ADDRRNGLO = 0x6FFFFE00 +    DT_GNU_HASH = 0x6FFFFEF5 +    DT_TLSDESC_PLT = 0x6FFFFEF6 +    DT_TLSDESC_GOT = 0x6FFFFEF7 +    DT_GNU_CONFLICT = 0x6FFFFEF8 +    DT_GNU_LIBLIST = 0x6FFFFEF9 +    DT_CONFIG = 0x6FFFFEFA +    DT_DEPAUDIT = 0x6FFFFEFB +    DT_AUDIT = 0x6FFFFEFC +    DT_PLTPAD = 0x6FFFFEFD +    DT_MOVETAB = 0x6FFFFEFE +    DT_SYMINFO = 0x6FFFFEFF +    DT_ADDRRNGHI = 0x6FFFFEFF +    DT_ADDRNUM = 11 +    DT_VERSYM = 0x6FFFFFF0 +    DT_RELACOUNT = 0x6FFFFFF9 +    DT_RELCOUNT = 0x6FFFFFFA +    DT_FLAGS_1 = 0x6FFFFFFB +    DT_VERDEF = 0x6FFFFFFC +    DT_VERDEFNUM = 0x6FFFFFFD +    DT_VERNEED = 0x6FFFFFFE +    DT_VERNEEDNUM = 0x6FFFFFFF +    DT_VERSIONTAGNUM = 16 +    DT_AUXILIARY = 0x7FFFFFFD +    DT_FILTER = 0x7FFFFFFF +    DT_EXTRANUM = 3 + + +def get_ph_dynamic_ent_tag_type(value): +    if value == PH_DYN_TAG_TYPE.DT_NULL: +        return "DT_NULL" +    elif value == PH_DYN_TAG_TYPE.DT_NEEDED: +        return "DT_NEEDED" +    elif value == PH_DYN_TAG_TYPE.DT_PLTRELSZ: +        return "DT_PLTRELSZ" +    elif value == PH_DYN_TAG_TYPE.DT_PLTGOT: +        return "DT_PLTGOT" +    elif value == PH_DYN_TAG_TYPE.DT_HASH: +        return "DT_HASH" +    elif value == PH_DYN_TAG_TYPE.DT_STRTAB: +        return "DT_STRTAB" +    elif value == PH_DYN_TAG_TYPE.DT_SYMTAB: +        return "DT_SYMTAB" +    elif value == PH_DYN_TAG_TYPE.DT_RELA: +        return "DT_RELA" +    elif value == PH_DYN_TAG_TYPE.DT_RELASZ: +        return "DT_RELASZ" +    elif value == PH_DYN_TAG_TYPE.DT_RELAENT: +        return "DT_RELAENT" +    elif value == PH_DYN_TAG_TYPE.DT_STRSZ: +        return "DT_STRSZ" +    elif value == PH_DYN_TAG_TYPE.DT_SYMENT: +        return "DT_SYMENT" +    elif value == PH_DYN_TAG_TYPE.DT_INIT: +        return "DT_INIT" +    elif value == PH_DYN_TAG_TYPE.DT_FINI: +        return "DT_FINI" +    elif value == PH_DYN_TAG_TYPE.DT_SONAME: +        return "DT_SONAME" +    elif value == PH_DYN_TAG_TYPE.DT_RPATH: +        return "DT_RPATH" +    elif value == PH_DYN_TAG_TYPE.DT_SYMBOLIC: +        return "DT_SYMBOLIC" +    elif value == PH_DYN_TAG_TYPE.DT_REL: +        return "DT_REL" +    elif value == PH_DYN_TAG_TYPE.DT_RELSZ: +        return "DT_RELSZ" +    elif value == PH_DYN_TAG_TYPE.DT_RELENT: +        return "DT_RELENT" +    elif value == PH_DYN_TAG_TYPE.DT_PLTREL: +        return "DT_PLTREL" +    elif value == PH_DYN_TAG_TYPE.DT_DEBUG: +        return "DT_DEBUG" +    elif value == PH_DYN_TAG_TYPE.DT_TEXTREL: +        return "DT_TEXTREL" +    elif value == PH_DYN_TAG_TYPE.DT_JMPREL: +        return "DT_JMPREL" +    elif value == PH_DYN_TAG_TYPE.DT_LOPROC: +        return "DT_LOPROC" +    elif value == PH_DYN_TAG_TYPE.DT_HIPROC: +        return "DT_HIPROC" +    elif value == PH_DYN_TAG_TYPE.DT_BIND_NOW: +        return "DT_BIND_NOW" +    elif value == PH_DYN_TAG_TYPE.DT_INIT_ARRAY: +        return "DT_INIT_ARRAY" +    elif value == PH_DYN_TAG_TYPE.DT_FINI_ARRAY: +        return "DT_FINI_ARRAY" +    elif value == PH_DYN_TAG_TYPE.DT_INIT_ARRAYSZ: +        return "DT_INIT_ARRAYSZ" +    elif value == PH_DYN_TAG_TYPE.DT_FINI_ARRAYSZ: +        return "DT_FINI_ARRAYSZ" +    elif value == PH_DYN_TAG_TYPE.DT_RUNPATH: +        return "DT_RUNPATH" +    elif value == PH_DYN_TAG_TYPE.DT_FLAGS: +        return "DT_FLAGS" +    elif value == PH_DYN_TAG_TYPE.DT_ENCODING: +        return "DT_ENCODING" +    elif value == PH_DYN_TAG_TYPE.DT_PREINIT_ARRAY: +        return "DT_PREINIT_ARRAY" +    elif value == PH_DYN_TAG_TYPE.DT_PREINIT_ARRAYSZ: +        return "DT_PREINIT_ARRAYSZ" +    elif value == PH_DYN_TAG_TYPE.DT_NUM: +        return "DT_NUM" +    elif value == PH_DYN_TAG_TYPE.DT_LOOS: +        return "DT_LOOS" +    elif value == PH_DYN_TAG_TYPE.DT_HIOS: +        return "DT_HIOS" +    # elif value == PH_DYN_TAG_TYPE.DT_PROC_NUM: return "DT_PROC_NUM" +    # elif value == PH_DYN_TAG_TYPE.DT_MIPS_NUM: return "DT_MIPS_NUM" +    elif value == PH_DYN_TAG_TYPE.DT_VALRNGLO: +        return "DT_VALRNGLO" +    elif value == PH_DYN_TAG_TYPE.DT_GNU_PRELINKED: +        return "DT_GNU_PRELINKED" +    elif value == PH_DYN_TAG_TYPE.DT_GNU_CONFLICTSZ: +        return "DT_GNU_CONFLICTSZ" +    elif value == PH_DYN_TAG_TYPE.DT_GNU_LIBLISTSZ: +        return "DT_GNU_LIBLISTSZ" +    elif value == PH_DYN_TAG_TYPE.DT_CHECKSUM: +        return "DT_CHECKSUM" +    elif value == PH_DYN_TAG_TYPE.DT_PLTPADSZ: +        return "DT_PLTPADSZ" +    elif value == PH_DYN_TAG_TYPE.DT_MOVEENT: +        return "DT_MOVEENT" +    elif value == PH_DYN_TAG_TYPE.DT_MOVESZ: +        return "DT_MOVESZ" +    elif value == PH_DYN_TAG_TYPE.DT_FEATURE_1: +        return "DT_FEATURE_1" +    elif value == PH_DYN_TAG_TYPE.DT_POSFLAG_1: +        return "DT_POSFLAG_1" +    elif value == PH_DYN_TAG_TYPE.DT_SYMINSZ: +        return "DT_SYMINSZ" +    elif value == PH_DYN_TAG_TYPE.DT_SYMINENT: +        return "DT_SYMINENT" +    elif value == PH_DYN_TAG_TYPE.DT_VALRNGHI: +        return "DT_VALRNGHI" +    # DT_VALNUM  = 12 +    elif value == PH_DYN_TAG_TYPE.DT_ADDRRNGLO: +        return "DT_ADDRRNGLO" +    elif value == PH_DYN_TAG_TYPE.DT_GNU_HASH: +        return "DT_GNU_HASH" +    elif value == PH_DYN_TAG_TYPE.DT_TLSDESC_PLT: +        return "DT_TLSDESC_PLT" +    elif value == PH_DYN_TAG_TYPE.DT_TLSDESC_GOT: +        return "DT_TLSDESC_GOT" +    elif value == PH_DYN_TAG_TYPE.DT_GNU_CONFLICT: +        return "DT_GNU_CONFLICT" +    elif value == PH_DYN_TAG_TYPE.DT_GNU_LIBLIST: +        return "DT_GNU_LIBLIST" +    elif value == PH_DYN_TAG_TYPE.DT_CONFIG: +        return "DT_CONFIG" +    elif value == PH_DYN_TAG_TYPE.DT_DEPAUDIT: +        return "DT_DEPAUDIT" +    elif value == PH_DYN_TAG_TYPE.DT_AUDIT: +        return "DT_AUDIT" +    elif value == PH_DYN_TAG_TYPE.DT_PLTPAD: +        return "DT_PLTPAD" +    elif value == PH_DYN_TAG_TYPE.DT_MOVETAB: +        return "DT_MOVETAB" +    elif value == PH_DYN_TAG_TYPE.DT_SYMINFO: +        return "DT_SYMINFO" +    elif value == PH_DYN_TAG_TYPE.DT_ADDRRNGHI: +        return "DT_ADDRRNGHI" +    # DT_ADDRNUM = 11 +    elif value == PH_DYN_TAG_TYPE.DT_VERSYM: +        return "DT_VERSYM" +    elif value == PH_DYN_TAG_TYPE.DT_RELACOUNT: +        return "DT_RELACOUNT" +    elif value == PH_DYN_TAG_TYPE.DT_RELCOUNT: +        return "DT_RELCOUNT" +    elif value == PH_DYN_TAG_TYPE.DT_FLAGS_1: +        return "DT_FLAGS_1" +    elif value == PH_DYN_TAG_TYPE.DT_VERDEF: +        return "DT_VERDEF" +    elif value == PH_DYN_TAG_TYPE.DT_VERDEFNUM: +        return "DT_VERDEFNUM" +    elif value == PH_DYN_TAG_TYPE.DT_VERNEED: +        return "DT_VERNEED" +    elif value == PH_DYN_TAG_TYPE.DT_VERNEEDNUM: +        return "DT_VERNEEDNUM" +    elif value == PH_DYN_TAG_TYPE.DT_VERSIONTAGNUM: +        return "DT_VERSIONTAGNUM" +    elif value == PH_DYN_TAG_TYPE.DT_AUXILIARY: +        return "DT_AUXILIARY" +    elif value == PH_DYN_TAG_TYPE.DT_FILTER: +        return "DT_FILTER" +    # DT_EXTRANUM = 3 +    else: +        return str(value) +    # else: return "UNKNOWN" + + +class X86_REL_TYPE: +    R_386_NONE = 0 +    R_386_32 = 1 +    R_386_PC32 = 2 +    R_386_GOT32 = 3 +    R_386_PLT32 = 4 +    R_386_COPY = 5 +    R_386_GLOB_DAT = 6 +    R_386_JMP_SLOT = 7 +    R_386_RELATIVE = 8 +    R_386_GOTOFF = 9 +    R_386_GOTPC = 10 +    R_386_32PLT = 11 +    R_386_16 = 12 +    R_386_PC16 = 13 +    R_386_8 = 14 +    R_386_PC8 = 15 +    R_386_SIZE32 = 16 + + +def get_x86_rel_type(val): +    if val == X86_REL_TYPE.R_386_NONE: +        return "R_386_NONE" +    elif val == X86_REL_TYPE.R_386_32: +        return "R_386_32" +    elif val == X86_REL_TYPE.R_386_PC32: +        return "R_386_PC32" +    elif val == X86_REL_TYPE.R_386_GOT32: +        return "R_386_GOT32" +    elif val == X86_REL_TYPE.R_386_PLT32: +        return "R_386_PLT32" +    elif val == X86_REL_TYPE.R_386_COPY: +        return "R_386_COPY" +    elif val == X86_REL_TYPE.R_386_GLOB_DAT: +        return "R_386_GLOB_DAT" +    elif val == X86_REL_TYPE.R_386_JMP_SLOT: +        return "R_386_JMP_SLOT" +    elif val == X86_REL_TYPE.R_386_RELATIVE: +        return "R_386_RELATIVE" +    elif val == X86_REL_TYPE.R_386_GOTOFF: +        return "R_386_GOTOFF" +    elif val == X86_REL_TYPE.R_386_GOTPC: +        return "R_386_GOTPC" +    elif val == X86_REL_TYPE.R_386_32PLT: +        return "R_386_32PLT" +    elif val == X86_REL_TYPE.R_386_16: +        return "R_386_16" +    elif val == X86_REL_TYPE.R_386_PC16: +        return "R_386_PC16" +    elif val == X86_REL_TYPE.R_386_8: +        return "R_386_8" +    elif val == X86_REL_TYPE.R_386_PC8: +        return "R_386_PC8" +    elif val == X86_REL_TYPE.R_386_SIZE32: +        return "R_386_SIZE32" +    else: +        return "UNKNOWN" + + +class X86_64_REL_TYPE: +    R_AMD64_NONE = 0 +    R_AMD64_64 = 1 +    R_AMD64_PC32 = 2 +    R_AMD64_GOT32 = 3 +    R_AMD64_PLT32 = 4 +    R_AMD64_COPY = 5 +    R_AMD64_GLOB_DAT = 6 +    R_AMD64_JUMP_SLOT = 7 +    R_AMD64_RELATIVE = 8 +    R_AMD64_GOTPCREL = 9 +    R_AMD64_32 = 10 +    R_AMD64_32S = 11 +    R_AMD64_16 = 12 +    R_AMD64_PC16 = 13 +    R_AMD64_8 = 14 +    R_AMD64_PC8 = 15 +    R_AMD64_PC64 = 24 +    R_AMD64_GOTOFF64 = 25 +    R_AMD64_GOTPC32 = 26 +    R_AMD64_SIZE32 = 32 +    R_AMD64_SIZE64 = 33 + + +class X86_64_REL_TYPE_2: +    R_X86_64_NONE = 0 +    R_X86_64_64 = 1 +    R_X86_64_PC32 = 2 +    R_X86_64_GOT32 = 3 +    R_X86_64_PLT32 = 4 +    R_X86_64_COPY = 5 +    R_X86_64_GLOB_DAT = 6 +    R_X86_64_JUMP_SLOT = 7 +    R_X86_64_RELATIVE = 8 +    R_X86_64_GOTPCREL = 9 +    R_X86_64_32 = 10 +    R_X86_64_32S = 11 +    R_X86_64_16 = 12 +    R_X86_64_PC16 = 13 +    R_X86_64_64_8 = 14 +    R_X86_64_PC8 = 15 +    R_X86_64_DTPMOD64 = 16 +    R_X86_64_DTPOFF64 = 17 +    R_X86_64_TPOFF64 = 18 +    R_X86_64_TLSGD = 19 +    R_X86_64_TLSLD = 20 +    R_X86_64_DTPOFF32 = 21 +    R_X86_64_GOTTPOFF = 22 +    R_X86_64_TPOFF32 = 23 +    R_X86_64_PC64 = 24 +    R_X86_64_GOTOFF64 = 25 +    R_X86_64_GOTPC32 = 26 +    R_X86_64_SIZE32 = 32 +    R_X86_64_SIZE64 = 33 +    R_X86_64_GOTPC32_TLDSEC = 34 +    R_X86_64_TLDSEC_CALL = 35 +    R_X86_64_TLDSEC = 36 +    R_X86_64_IRELATIVE = 37 + + +def get_x86_64_rel_type(val): +    if val == X86_64_REL_TYPE.R_AMD64_NONE: +        return "R_386_NONE" +    elif val == X86_64_REL_TYPE.R_AMD64_64: +        return "R_AMD64_64" +    elif val == X86_64_REL_TYPE.R_AMD64_PC32: +        return "R_AMD64_PC32" +    elif val == X86_64_REL_TYPE.R_AMD64_GOT32: +        return "R_AMD64_GOT32" +    elif val == X86_64_REL_TYPE.R_AMD64_PLT32: +        return "R_AMD64_PLT32" +    elif val == X86_64_REL_TYPE.R_AMD64_COPY: +        return "R_AMD64_COPY" +    elif val == X86_64_REL_TYPE.R_AMD64_GLOB_DAT: +        return "R_AMD64_GLOB_DAT" +    elif val == X86_64_REL_TYPE.R_AMD64_JUMP_SLOT: +        return "R_AMD64_JUMP_SLOT" +    elif val == X86_64_REL_TYPE.R_AMD64_RELATIVE: +        return "R_AMD64_RELATIVE" +    elif val == X86_64_REL_TYPE.R_AMD64_GOTPCREL: +        return "R_AMD64_GOTPCREL" +    elif val == X86_64_REL_TYPE.R_AMD64_32: +        return "R_AMD64_32" +    elif val == X86_64_REL_TYPE.R_AMD64_32S: +        return "R_AMD64_32S" +    elif val == X86_64_REL_TYPE.R_AMD64_16: +        return "R_AMD64_16" +    elif val == X86_64_REL_TYPE.R_AMD64_PC16: +        return "R_AMD64_PC16" +    elif val == X86_64_REL_TYPE.R_AMD64_8: +        return "R_AMD64_8" +    elif val == X86_64_REL_TYPE.R_AMD64_PC8: +        return "R_AMD64_PC8" +    elif val == X86_64_REL_TYPE.R_AMD64_PC64: +        return "R_AMD64_PC64" +    elif val == X86_64_REL_TYPE.R_AMD64_GOTOFF64: +        return "R_AMD64_GOTOFF64" +    elif val == X86_64_REL_TYPE.R_AMD64_GOTPC32: +        return "R_AMD64_GOTPC32" +    elif val == X86_64_REL_TYPE.R_AMD64_SIZE32: +        return "R_AMD64_SIZE32" +    elif val == X86_64_REL_TYPE.R_AMD64_SIZE64: +        return "R_AMD64_SIZE64" +    else: +        return "UNKNOWN" + + +def get_x86_64_rel_type_2(val): +    if val == X86_64_REL_TYPE_2.R_X86_64_NONE: +        return "R_X86_64_NONE" +    elif val == X86_64_REL_TYPE_2.R_X86_64_64: +        return "R_X86_64_64" +    elif val == X86_64_REL_TYPE_2.R_X86_64_PC32: +        return "R_X86_64_PC32" +    elif val == X86_64_REL_TYPE_2.R_X86_64_GOT32: +        return "R_X86_64_GOT32" +    elif val == X86_64_REL_TYPE_2.R_X86_64_PLT32: +        return "R_X86_64_PLT32" +    elif val == X86_64_REL_TYPE_2.R_X86_64_COPY: +        return "R_X86_64_COPY" +    elif val == X86_64_REL_TYPE_2.R_X86_64_GLOB_DAT: +        return "R_X86_64_GLOB_DAT" +    elif val == X86_64_REL_TYPE_2.R_X86_64_JUMP_SLOT: +        return "R_X86_64_JUMP_SLOT" +    elif val == X86_64_REL_TYPE_2.R_X86_64_RELATIVE: +        return "R_X86_64_RELATIVE" +    elif val == X86_64_REL_TYPE_2.R_X86_64_GOTPCREL: +        return "R_X86_64_GOTPCREL" +    elif val == X86_64_REL_TYPE_2.R_X86_64_32: +        return "R_X86_64_32" +    elif val == X86_64_REL_TYPE_2.R_X86_64_32S: +        return "R_X86_64_32S" +    elif val == X86_64_REL_TYPE_2.R_X86_64_16: +        return "R_X86_64_16" +    elif val == X86_64_REL_TYPE_2.R_X86_64_PC16: +        return "R_X86_64_PC16" +    elif val == X86_64_REL_TYPE_2.R_X86_64_64_8: +        return "R_X86_64_64_8" +    elif val == X86_64_REL_TYPE_2.R_X86_64_PC8: +        return "R_X86_64_PC8" +    elif val == X86_64_REL_TYPE_2.R_X86_64_DTPMOD64: +        return "R_X86_64_DTPMOD64" +    elif val == X86_64_REL_TYPE_2.R_X86_64_DTPOFF64: +        return "R_X86_64_DTPOFF64" +    elif val == X86_64_REL_TYPE_2.R_X86_64_TPOFF64: +        return "R_X86_64_TPOFF64" +    elif val == X86_64_REL_TYPE_2.R_X86_64_TLSGD: +        return "R_X86_64_TLSGD" +    elif val == X86_64_REL_TYPE_2.R_X86_64_TLSLD: +        return "R_X86_64_TLSLD" +    elif val == X86_64_REL_TYPE_2.R_X86_64_DTPOFF32: +        return "R_X86_64_DTPOFF32" +    elif val == X86_64_REL_TYPE_2.R_X86_64_GOTTPOFF: +        return "R_X86_64_GOTTPOFF" +    elif val == X86_64_REL_TYPE_2.R_X86_64_TPOFF32: +        return "R_X86_64_TPOFF32" +    elif val == X86_64_REL_TYPE_2.R_X86_64_PC64: +        return "R_X86_64_PC64" +    elif val == X86_64_REL_TYPE_2.R_X86_64_GOTOFF64: +        return "R_X86_64_GOTOFF64" +    elif val == X86_64_REL_TYPE_2.R_X86_64_GOTPC32: +        return "R_X86_64_GOTPC32" +    elif val == X86_64_REL_TYPE_2.R_X86_64_SIZE32: +        return "R_X86_64_SIZE32" +    elif val == X86_64_REL_TYPE_2.R_X86_64_SIZE64: +        return "R_X86_64_SIZE64" +    elif val == X86_64_REL_TYPE_2.R_X86_64_GOTPC32_TLDSEC: +        return "R_X86_64_GOTPC32_TLDSEC" +    elif val == X86_64_REL_TYPE_2.R_X86_64_TLDSEC_CALL: +        return "R_X86_64_TLDSEC_CALL" +    elif val == X86_64_REL_TYPE_2.R_X86_64_TLDSEC: +        return "R_X86_64_TLDSEC" +    elif val == X86_64_REL_TYPE_2.R_X86_64_IRELATIVE: +        return "R_X86_64_IRELATIVE" +    else: +        return "UNKNOWN" + + +class ELF_ST_BIND: +    STB_LOCAL = 0 +    STB_GLOBAL = 1 +    STB_WEAK = 2 +    STB_LOOS = 10 +    STB_HIOS = 12 +    STB_LOPROC = 13 +    STB_HIPROC = 15 + + +def get_elf_st_bind_string(value): +    if value == ELF_ST_BIND.STB_LOCAL: +        return "STB_LOCAL" +    elif value == ELF_ST_BIND.STB_GLOBAL: +        return "STB_GLOBAL" +    elif value == ELF_ST_BIND.STB_WEAK: +        return "STB_WEAK" +    elif value == ELF_ST_BIND.STB_LOOS: +        return "STB_LOOS" +    elif value == ELF_ST_BIND.STB_HIOS: +        return "STB_HIOS" +    elif value == ELF_ST_BIND.STB_LOPROC: +        return "STB_LOPROC" +    elif value == ELF_ST_BIND.STB_LOPROC: +        return "STB_HIPROC" +    else: +        return None + + +class ELF_ST_TYPE: +    STT_NOTYPE = 0 +    STT_OBJECT = 1 +    STT_FUNC = 2 +    STT_SECTION = 3 +    STT_FILE = 4 +    STT_COMMON = 5 +    STT_TLS = 6 +    STT_LOOS = 10 +    STT_HIOS = 12 +    STT_LOPROC = 13 +    STT_SPARC_REGISTER = 13 +    STT_HIPROC = 15 + + +def get_elf_st_type_string(value): +    if value == ELF_ST_TYPE.STT_NOTYPE: +        return "STT_NOTYPE" +    elif value == ELF_ST_TYPE.STT_OBJECT: +        return "STT_OBJECT" +    elif value == ELF_ST_TYPE.STT_FUNC: +        return "STT_FUNC" +    elif value == ELF_ST_TYPE.STT_SECTION: +        return "STT_SECTION" +    elif value == ELF_ST_TYPE.STT_FILE: +        return "STT_FILE" +    elif value == ELF_ST_TYPE.STT_COMMON: +        return "STT_COMMON" +    elif value == ELF_ST_TYPE.STT_TLS: +        return "STT_TLS" +    elif value == ELF_ST_TYPE.STT_LOOS: +        return "STT_LOOS" +    elif value == ELF_ST_TYPE.STT_HIOS: +        return "STT_HIOS" +    elif value == ELF_ST_TYPE.STT_LOPROC: +        return "STT_LOPROC" +    elif value == ELF_ST_TYPE.STT_SPARC_REGISTER: +        return "STT_SPARC_REGISTER" +    elif value == ELF_ST_TYPE.STT_HIPROC: +        return "STT_HIPROC" +    else: +        return None + + +class ELF_VIS: +    STV_DEFAULT = 0 +    STV_INTERNAL = 1 +    STV_HIDDEN = 2 +    STV_PROTECTED = 3 +    STV_EXPORTED = 4 +    STV_SINGLETON = 5 +    STV_ELIMINATE = 6 + + +def get_elf_vis_string(value): +    if value == ELF_VIS.STV_DEFAULT: +        return "STV_DEFAULT" +    elif value == ELF_VIS.STV_INTERNAL: +        return "STV_INTERNAL" +    elif value == ELF_VIS.STV_HIDDEN: +        return "STV_HIDDEN" +    elif value == ELF_VIS.STV_PROTECTED: +        return "STV_PROTECTED" +    elif value == ELF_VIS.STV_EXPORTED: +        return "STV_EXPORTED" +    elif value == ELF_VIS.STV_SINGLETON: +        return "STV_SINGLETON" +    elif value == ELF_VIS.STV_ELIMINATE: +        return "STV_ELIMINATE" +    else: +        return None + + +class Colors: +    purple = "\033[95m" +    blue = "\033[94m" +    green = "\033[92m" +    yellow = "\033[93m" +    red = "\033[91m" +    grey = "\033[1;37m" +    darkgrey = "\033[1;30m" +    cyan = "\033[1;36m" +    ENDC = "\033[0m" +    BOLD = "\033[1m" +    UNDERLINE = "\033[4m" + + +def openSO_r(path): +    so = open(path, "rb") +    return so + + +def openSO_w(path): +    so = open(path, "wb") +    return so + + +class ELFHDR: +    def __init__( +        self, +        ei_mag, +        ei_class, +        ei_data, +        ei_version, +        ei_osabi, +        ei_abiversion, +        ei_pad, +        e_type, +        e_machine, +        e_version, +        e_entry, +        e_phoff, +        e_shoff, +        e_flags, +        e_ehsize, +        e_phentsize, +        e_phnum, +        e_shentsize, +        e_shnum, +        e_shstrndx, +    ): +        self.ei_mag = ei_mag +        self.ei_class = ei_class +        self.ei_data = ei_data +        self.ei_version = ei_version +        self.ei_osabi = ei_osabi +        self.ei_abiversion = ei_abiversion +        self.ei_pad = ei_pad +        self.e_type = e_type +        self.e_machine = e_machine +        self.e_version = e_version +        self.e_entry = e_entry +        self.e_phoff = e_phoff +        self.e_shoff = e_shoff +        self.e_flags = e_flags +        self.e_ehsize = e_ehsize +        self.e_phentsize = e_phentsize +        self.e_phnum = e_phnum +        self.e_shentsize = e_shentsize +        self.e_shnum = e_shnum +        self.e_shstrndx = e_shstrndx + + +class PHDR: +    def __init__( +        self, +        p_type, +        p_flags, +        p_offset, +        p_vaddr, +        p_paddr, +        p_filesz, +        p_memsz, +        p_flags2, +        p_align, +    ): +        self.p_type = p_type +        self.p_flags = p_flags +        self.p_offset = p_offset +        self.p_vaddr = p_vaddr +        self.p_paddr = p_paddr +        self.p_filesz = p_filesz +        self.p_memsz = p_memsz +        self.p_flags2 = p_flags2 +        self.p_align = p_align + + +class SHDR: +    def __init__( +        self, +        sh_name, +        sh_type, +        sh_flags, +        sh_addr, +        sh_offset, +        sh_size, +        sh_link, +        sh_info, +        sh_addralign, +        sh_entsize, +    ): +        self.sh_name = sh_name +        self.sh_type = sh_type +        self.sh_flags = sh_flags +        self.sh_addr = sh_addr +        self.sh_offset = sh_offset +        self.sh_size = sh_size +        self.sh_link = sh_link +        self.sh_info = sh_info +        self.sh_addralign = sh_addralign +        self.sh_entsize = sh_entsize + + +class Symbol_Table_Entry64: +    def __init__( +        self, +        st_name, +        st_info, +        st_other, +        st_shndx, +        st_value, +        st_size, +        st_bind, +        st_type, +    ): +        self.st_name = st_name +        self.st_info = st_info +        self.st_other = st_other +        self.st_shndx = st_shndx +        self.st_value = st_value +        self.st_size = st_size +        self.st_bind = st_bind +        self.st_type = st_type + + +class ELF(object): +    def __init__(self, so): +        self.so = so +        self.so.seek(0, 0) +        self.elfhdr = ELFHDR(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) +        self.phdr = [] +        self.shhdr = [] +        self.size = int() +        self.string_tb_e = [] +        self.string_tb_e_dyn = [] +        self.symbol_table_e = [] +        self.data_section = [] +        self.text_section = [] +        self.dlpath = str() +        self.ph_dyn_ent = [] +        self.dyn_section = [] +        self.dyn_section_ents = [] +        self.rela_dyn = [] +        self.rela_dyn_ents = [] +        self.rela_plt = [] +        self.rela_plt_ents = [] +        self.rodata = [] +        self.plt = [] +        self.got = [] +        self.got_plt = [] +        self.plt_got = [] +        self.plt_ents = [] +        self.plt_got_ents = [] +        self.got_ents = [] +        self.got_plt_ents = [] + +    def init(self, size): +        self.size = size +        self.read_ELF_H(size) +        self.so.seek(byte2int(self.elfhdr.e_phoff)) +        phnum = byte2int(self.elfhdr.e_phnum) +        for i in range(0, phnum): +            self.read_PHDR(size) +        self.so.seek(byte2int(self.elfhdr.e_shoff)) +        shnum = byte2int(self.elfhdr.e_shnum) +        for i in range(0, shnum): +            self.read_SHDR(size) +        for i in range(0, shnum): +            type = byte2int(self.shhdr[i].sh_type) +            if type == sh_type_e.SHT_SYMTAB: +                self.so.seek(byte2int(self.shhdr[i].sh_offset), 0) +                symbol_tb = self.so.read(byte2int(self.shhdr[i].sh_size)) +                offset = 0 +                num = int(byte2int(self.shhdr[i].sh_size) / 24) +                for j in range(0, num): +                    self.read_st_entry( +                        symbol_tb[offset : offset + 24], self.string_tb_e +                    ) +                    offset += 24 +            if type == sh_type_e.SHT_DYNSYM: +                self.so.seek(byte2int(self.shhdr[i].sh_offset), 0) +                symbol_tb = self.so.read(byte2int(self.shhdr[i].sh_size)) +                offset = 0 +                num = int(byte2int(self.shhdr[i].sh_size) / 24) +                for j in range(0, num): +                    self.read_st_entry( +                        symbol_tb[offset : offset + 24], self.string_tb_e_dyn +                    ) +                    offset += 24 +        self.pop_data_section() +        self.pop_text_section() +        self.get_ph_dyn_entries() +        self.pop_dynamic_entries(".dynamic", self.dyn_section_ents) +        self.pop_rela(".rela.plt", self.rela_plt, self.rela_plt_ents) +        self.pop_rela(".rela.dyn", self.rela_dyn, self.rela_dyn_ents) +        # self.pop_rel() + +    def read_ELF_H(self, size): +        self.elfhdr.ei_mag = self.so.read(4) +        self.elfhdr.ei_class = self.so.read(1) +        self.elfhdr.ei_data = self.so.read(1) +        self.elfhdr.ei_version = self.so.read(1) +        self.elfhdr.ei_osabi = self.so.read(1) +        self.elfhdr.ei_abiversion = self.so.read(1) +        self.elfhdr.ei_pad = self.so.read(7) +        self.elfhdr.e_type = self.so.read(2) +        self.elfhdr.e_machine = self.so.read(2) +        self.elfhdr.e_version = self.so.read(4) +        if size == 32: +            self.elfhdr.e_entry = self.so.read(4) +        elif size == 64: +            self.elfhdr.e_entry = self.so.read(8) +        if size == 32: +            self.elfhdr.e_phoff = self.so.read(4) +        elif size == 64: +            self.elfhdr.e_phoff = self.so.read(8) +        if size == 32: +            self.elfhdr.e_shoff = self.so.read(4) +        elif size == 64: +            self.elfhdr.e_shoff = self.so.read(8) +        self.elfhdr.e_flags = self.so.read(4) +        self.elfhdr.e_ehsize = self.so.read(2) +        self.elfhdr.e_phentsize = self.so.read(2) +        self.elfhdr.e_phnum = self.so.read(2) +        self.elfhdr.e_shentsize = self.so.read(2) +        self.elfhdr.e_shnum = self.so.read(2) +        self.elfhdr.e_shstrndx = self.so.read(2) + +    def read_PHDR(self, size): +        dummy = PHDR(0, 0, 0, 0, 0, 0, 0, 0, 0) +        dummy.p_type = self.so.read(4) +        if size == 64: +            dummy.p_flags = self.so.read(4) +        if size == 32: +            dummy.p_offset = self.so.read(4) +        elif size == 64: +            dummy.p_offset = self.so.read(8) +        if size == 32: +            dummy.p_vaddr = self.so.read(4) +        elif size == 64: +            dummy.p_vaddr = self.so.read(8) +        if size == 32: +            dummy.p_paddr = self.so.read(4) +        elif size == 64: +            dummy.p_paddr = self.so.read(8) +        if size == 32: +            dummy.p_filesz = self.so.read(4) +        elif size == 64: +            dummy.p_filesz = self.so.read(8) +        if size == 32: +            dummy.p_memsz = self.so.read(4) +        elif size == 64: +            dummy.p_memsz = self.so.read(8) +        if size == 32: +            dummy.p_flags2 = self.so.read(4) +        elif size == 64: +            pass +        if size == 32: +            dummy.p_align = self.so.read(4) +        elif size == 64: +            dummy.p_align = self.so.read(8) +        self.phdr.append(dummy) + +    def read_SHDR(self, size): +        dummy = SHDR(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) +        dummy.sh_name = self.so.read(4) +        dummy.sh_type = self.so.read(4) +        if size == 32: +            dummy.sh_flags = self.so.read(4) +        elif size == 64: +            dummy.sh_flags = self.so.read(8) +        if size == 32: +            dummy.sh_addr = self.so.read(4) +        elif size == 64: +            dummy.sh_addr = self.so.read(8) +        if size == 32: +            dummy.sh_offset = self.so.read(4) +        elif size == 64: +            dummy.sh_offset = self.so.read(8) +        if size == 32: +            dummy.sh_size = self.so.read(4) +        elif size == 64: +            dummy.sh_size = self.so.read(8) +        dummy.sh_link = self.so.read(4) +        dummy.sh_info = self.so.read(4) +        if size == 32: +            dummy.sh_addralign = self.so.read(4) +        elif size == 64: +            dummy.sh_addralign = self.so.read(8) +        if size == 32: +            dummy.sh_entsize = self.so.read(4) +        elif size == 64: +            dummy.sh_entsize = self.so.read(8) +        self.shhdr.append(dummy) + +    def read_st_entry(self, st, entry_list): +        dummy = Symbol_Table_Entry64(0, 0, 0, 0, 0, 0, 0, 0) +        dummy.st_name = st[0:4] +        dummy.st_info = st[4:5] +        dummy.st_other = st[5:6] +        dummy.st_shndx = st[6:8] +        dummy.st_value = st[8:16] +        dummy.st_size = st[16:24] +        dummy.st_bind = byte2int(dummy.st_info) >> 4 +        dummy.st_type = byte2int(dummy.st_info) & 0x0F +        entry_list.append(dummy) + +    def read_section_name(self, index): +        shstrtab_index = byte2int(self.elfhdr.e_shstrndx) +        name = [] +        self.so.seek(byte2int(self.shhdr[shstrtab_index].sh_offset), 0) +        strings = self.so.read(byte2int(self.shhdr[shstrtab_index].sh_size)) +        char = strings[index] +        while chr(char) != "\0": +            index += 1 +            name.append(chr(char)) +            char = strings[index] +        return "".join(name) + +    def get_ph_dyn_entries(self): +        size = 0 +        for phdr in self.phdr: +            if byte2int(phdr.p_type) == p_type_e.PT_DYNAMIC: +                self.so.seek(byte2int(phdr.p_offset), 0) +                size = byte2int(phdr.p_filesz) +                ph_dyn = self.so.read(size) +        for i in range(int(size / 8)): +            d_tag = byte2int(ph_dyn[8 * i : 8 * i + 4]) +            d_un = byte2int(ph_dyn[8 * i + 4 : 8 * i + 8]) +            self.ph_dyn_ent.append(ph_dynamic_entry(d_tag, d_un)) + +    def dump_ph_dyn_entries(self): +        header = ["d_tag", "d_un"] +        tag_list = [get_ph_dynamic_ent_tag_type(ph.d_tag) for ph in self.ph_dyn_ent] +        un_list = [ph.d_un for ph in self.ph_dyn_ent] +        lines = ffs(2, header, True, tag_list, un_list) +        for line in lines: +            print(line) + +    def dump_funcs(self, dump_b): +        ret_list = [] +        dummy = [] +        ret_list_int = [] +        for iter in self.string_tb_e: +            if iter.st_type == ELF_ST_TYPE.STT_FUNC: +                self.so.seek(int.from_bytes(iter.st_value, byteorder="little")) +                obj = self.so.read(int.from_bytes(iter.st_size, byteorder="little")) +                ret_list.append(obj) +                for byte in obj: +                    dummy.append(int(byte)) +                ret_list_int.append(dummy) +                dummy = [] +        if dump_b: +            for obj in ret_list_int: +                for byte in obj: +                    print(format(byte, "02x") + " ", end="") +                print("\n") + +        return ret_list_int + +    def dump_symbol_string(self, stt_type, dump_b): +        ret_list = [] +        for entry in self.string_tb_e: +            if entry.st_type == stt_type: +                ret_list.append( +                    "".join( +                        self.get_st_entry_symbol_string( +                            byte2int(entry.st_name), ".strtab" +                        ) +                    ) +                ) +        if dump_b: +            for name in ret_list: +                print(name) +        return ret_list + +    def dump_section(self, section_name, dump): +        hit = False +        for section in self.shhdr: +            name = self.read_section_name(byte2int(section.sh_name)) +            if name == section_name: +                hit = True +                self.so.seek(byte2int(section.sh_offset)) +                obj = self.so.read(byte2int(section.sh_size)) +                if section_name == ".interp": +                    self.dlpath = repr(obj) +                count = int() +                if dump: +                    strrep = [] +                    for byte in obj: +                        if count % 16 == 0: +                            for ch in strrep: +                                if ord(ch) > 32 and ord(ch) < 127: +                                    print(ch, end="") +                                else: +                                    print(" ", end="") +                            print() +                            strrep = [] +                            print(format(count, "06x"), ": ", end="") +                            strrep.append(str(chr(byte))) +                            print(format(byte, "02x") + " ", end="") +                        else: +                            strrep += str(chr(byte)) +                            print(format(byte, "02x") + " ", end="") +                        count += 1 +                    for i in range(0, 16 - count % 16): +                        print("   ", end="") +                    for ch in strrep: +                        if ord(ch) > 32 and ord(ch) < 127: +                            print(ch, end="") +                        else: +                            print(" ", end="") +                    print() + +                ret_dummy = [] +                for i in range(0, len(obj)): +                    ret_dummy.append(obj[i]) +                # print(ret_dummy) +                return ret_dummy +        if not hit: +            print(Colors.red + Colors.BOLD + "section is not present" + Colors.ENDC) + +    def dump_obj_size(self, stt_type, dump_b): +        ret_list = [] +        for entry in self.string_tb_e: +            if entry.st_type == stt_type: +                ret_list.append(byte2int(entry.st_size)) +        if dump_b: +            for name in ret_list: +                print(name) +        return ret_list + +    def dump_symbol_idx(self): +        header = ["name", "size", "value", "info", "other", "shndx"] +        name_list = [byte2int(st.st_name) for st in self.string_tb_e] +        size_list = [byte2int(st.st_size) for st in self.string_tb_e] +        value_list = [byte2int(st.st_value) for st in self.string_tb_e] +        info_list = [byte2int(st.st_info) for st in self.string_tb_e] +        other_list = [byte2int(st.st_other) for st in self.string_tb_e] +        shndx_list = [byte2int(st.st_shndx) for st in self.string_tb_e] +        lines = ffs( +            2, +            header, +            True, +            name_list, +            size_list, +            value_list, +            info_list, +            other_list, +            shndx_list, +        ) +        print(Colors.green + Colors.BOLD + "symbol:" + Colors.ENDC) +        for line in lines: +            print(line) +        print(Colors.green + Colors.BOLD + "dyn symbol:" + Colors.ENDC) +        header = ["name", "size", "value", "info", "other", "shndx"] +        name_list = [byte2int(st.st_name) for st in self.string_tb_e_dyn] +        size_list = [byte2int(st.st_size) for st in self.string_tb_e_dyn] +        value_list = [byte2int(st.st_value) for st in self.string_tb_e_dyn] +        info_list = [byte2int(st.st_info) for st in self.string_tb_e_dyn] +        other_list = [byte2int(st.st_other) for st in self.string_tb_e_dyn] +        shndx_list = [byte2int(st.st_shndx) for st in self.string_tb_e_dyn] +        lines = ffs( +            2, +            header, +            True, +            name_list, +            size_list, +            value_list, +            info_list, +            other_list, +            shndx_list, +        ) +        for line in lines: +            print(line) + +    def dump_header(self): +        header = [ +            "ei_mag", +            "ei_class", +            "ei_data", +            "ei_version", +            "ei_osabi", +            "ei_abiversion", +            "ei_pad", +            "e_type", +            "e_machine", +            "e_version", +            "e_version", +            "e_entry", +            "e_phoff", +            "e_shoff", +            "e_flags", +            "e_entsize", +            "e_phentsize", +            "e_phnum", +            "e_shentsize", +            "e_shnum", +            "e_shstrndx", +        ] +        mag_list = [self.elfhdr.ei_mag] +        class_list = [byte2int(self.elfhdr.ei_class)] +        data_list = [byte2int(self.elfhdr.ei_data)] +        version_list = [byte2int(self.elfhdr.ei_version)] +        osabi_list = [byte2int(self.elfhdr.ei_osabi)] +        abiversion_list = [byte2int(self.elfhdr.ei_abiversion)] +        pad_list = [byte2int(self.elfhdr.ei_pad)] +        type_list = [byte2int(self.elfhdr.e_type)] +        machine_list = [byte2int(self.elfhdr.e_machine)] +        # e_version_list = [byte2int(self.elfhdr.e_version)] +        entry_list = [byte2int(self.elfhdr.e_entry)] +        phoff_list = [byte2int(self.elfhdr.e_phoff)] +        shoff_list = [byte2int(self.elfhdr.e_shoff)] +        flags_list = [byte2int(self.elfhdr.e_flags)] +        ehsize_list = [byte2int(self.elfhdr.e_ehsize)] +        phentsize_list = [byte2int(self.elfhdr.e_phentsize)] +        phnum_list = [byte2int(self.elfhdr.e_phnum)] +        shentsize_list = [byte2int(self.elfhdr.e_shentsize)] +        shnum_list = [byte2int(self.elfhdr.e_shnum)] +        shstrndx_list = [byte2int(self.elfhdr.e_shstrndx)] +        lines = ffs( +            2, +            header, +            True, +            mag_list, +            class_list, +            data_list, +            version_list, +            osabi_list, +            abiversion_list, +            pad_list, +            type_list, +            machine_list, +            version_list, +            entry_list, +            phoff_list, +            shoff_list, +            flags_list, +            ehsize_list, +            phentsize_list, +            phnum_list, +            shentsize_list, +            phnum_list, +            shentsize_list, +            shnum_list, +            shstrndx_list, +        ) +        for line in lines: +            print(line) + +    def dump_phdrs(self): +        header = [ +            "p_type", +            "p_flags", +            "p_offset", +            "p_vaddr", +            "p_paddr", +            "p_filesz", +            "p_memsz", +            "p_flags2", +            "p_align", +        ] +        type_list = [get_ph_type(byte2int(phdr.p_type)) for phdr in self.phdr] +        flags_list = [get_elf_seg_flag(byte2int(phdr.p_type)) for phdr in self.phdr] +        offset_list = [byte2int(phdr.p_offset) for phdr in self.phdr] +        vaddr_list = [byte2int(phdr.p_vaddr) for phdr in self.phdr] +        paddr_list = [byte2int(phdr.p_paddr) for phdr in self.phdr] +        filesz_list = [byte2int(phdr.p_filesz) for phdr in self.phdr] +        memsz_list = [byte2int(phdr.p_memsz) for phdr in self.phdr] +        flags2_list = [phdr.p_flags2 for phdr in self.phdr] +        align_list = [byte2hex(phdr.p_align) for phdr in self.phdr] + +        lines = ffs( +            2, +            header, +            True, +            type_list, +            flags_list, +            offset_list, +            vaddr_list, +            paddr_list, +            filesz_list, +            memsz_list, +            flags2_list, +            align_list, +        ) +        for line in lines: +            print(line) + +    def dump_shdrs(self): +        header = [ +            "sh_name", +            "sh_type", +            "sh_flags", +            "sh_addr", +            "sh_offset", +            "sh_size", +            "sh_link", +            "sh_info", +            "sh_addralign", +            "sh_entsize", +        ] +        name_list = [ +            self.read_section_name(byte2int(shhdr.sh_name)) for shhdr in self.shhdr +        ] +        type_list = [ +            get_section_type_string(byte2int(shhdr.sh_type)) for shhdr in self.shhdr +        ] +        flag_list = [byte2int(shhdr.sh_flags) for shhdr in self.shhdr] +        addr_list = [byte2int(shhdr.sh_addr) for shhdr in self.shhdr] +        offset_list = [byte2int(shhdr.sh_offset) for shhdr in self.shhdr] +        size_list = [byte2int(shhdr.sh_size) for shhdr in self.shhdr] +        link_list = [byte2int(shhdr.sh_link) for shhdr in self.shhdr] +        info_list = [byte2int(shhdr.sh_info) for shhdr in self.shhdr] +        allign_list = [byte2int(shhdr.sh_addralign) for shhdr in self.shhdr] +        entsize_list = [byte2int(shhdr.sh_entsize) for shhdr in self.shhdr] + +        lines = ffs( +            2, +            header, +            True, +            name_list, +            type_list, +            flag_list, +            addr_list, +            offset_list, +            size_list, +            link_list, +            info_list, +            allign_list, +            entsize_list, +        ) +        for line in lines: +            print(line) + +    def dump_symbol_tb(self, name, type): +        for i in range(0, byte2int(self.elfhdr.e_shnum)): +            if byte2int(self.shhdr[i].sh_type) == type: +                if name == self.read_section_name(byte2int(self.shhdr[i].sh_name)): +                    print(Colors.BOLD + Colors.yellow + "STRING TABLE:" + Colors.ENDC) +                    self.so.seek(byte2int(self.shhdr[i].sh_offset), 0) +                    symbol_tb = self.so.read(byte2int(self.shhdr[i].sh_size)) +                    for byte in symbol_tb: +                        print(chr(byte), end="") +                        if chr(byte) == "\0": +                            print() + +    def dump_st_entries(self): +        header = [ +            "name_index", +            "name", +            "value", +            "size", +            "info", +            "other", +            "shndx", +            "bind", +            "type", +        ] +        idx_list = [byte2int(entry.st_name) for entry in self.string_tb_e] +        name_list = [ +            "".join(self.get_st_entry_symbol_string(byte2int(entry.st_name), ".strtab")) +            for entry in self.string_tb_e +        ] +        value_list = [byte2int(entry.st_value) for entry in self.string_tb_e] +        size_list = [byte2int(entry.st_size) for entry in self.string_tb_e] +        info_list = [byte2int(entry.st_info) for entry in self.string_tb_e] +        other_list = [byte2int(entry.st_other) for entry in self.string_tb_e] +        shndx_list = [byte2int(entry.st_shndx) for entry in self.string_tb_e] +        bind_list = [ +            get_elf_st_bind_string(entry.st_bind) for entry in self.string_tb_e +        ] +        type_list = [ +            get_elf_st_type_string(entry.st_type) for entry in self.string_tb_e +        ] + +        lines = ffs( +            2, +            header, +            True, +            idx_list, +            name_list, +            value_list, +            size_list, +            info_list, +            other_list, +            shndx_list, +            bind_list, +            type_list, +        ) +        for line in lines: +            print(line) + +    def dump_st_entries_dyn(self): +        header = [ +            "name_index", +            "name", +            "value", +            "size", +            "info", +            "other", +            "shndx", +            "bind", +            "type", +        ] +        idx_list = [byte2int(entry.st_name) for entry in self.string_tb_e_dyn] +        name_list = [ +            "".join(self.get_st_entry_symbol_string(byte2int(entry.st_name), ".dynstr")) +            for entry in self.string_tb_e_dyn +        ] +        value_list = [byte2int(entry.st_value) for entry in self.string_tb_e_dyn] +        size_list = [byte2int(entry.st_size) for entry in self.string_tb_e_dyn] +        info_list = [byte2int(entry.st_info) for entry in self.string_tb_e_dyn] +        other_list = [byte2int(entry.st_other) for entry in self.string_tb_e_dyn] +        shndx_list = [byte2int(entry.st_shndx) for entry in self.string_tb_e_dyn] +        bind_list = [ +            get_elf_st_bind_string(entry.st_bind) for entry in self.string_tb_e_dyn +        ] +        type_list = [ +            get_elf_st_type_string(entry.st_type) for entry in self.string_tb_e_dyn +        ] + +        lines = ffs( +            2, +            header, +            True, +            idx_list, +            name_list, +            value_list, +            size_list, +            info_list, +            other_list, +            shndx_list, +            bind_list, +            type_list, +        ) +        for line in lines: +            print(line) + +    def dump_dyn_sec_ents(self, who): +        header = ["type_string", "tag", "value", "value(hex)"] +        tag_string_list = [entry["type_string"] for entry in who] +        tag_list = [entry["tag"] for entry in who] +        value_list = [entry["value"] for entry in who] +        value_list_hex = [hex(entry["value"]) for entry in who] +        lines = ffs( +            2, +            header, +            True, +            tag_string_list, +            tag_list, +            value_list, +            value_list_hex, +        ) +        for line in lines: +            print(line) + +    def dump_rela(self, to_dump): +        header = ["r_offset", "r_info", "r_addend"] +        r_offset_list = [entry["r_offset"] for entry in to_dump] +        r_info_list = [entry["r_info"] for entry in to_dump] +        addend_list = [entry["r_addend"] for entry in to_dump] +        lines = ffs(2, header, True, r_offset_list, r_info_list, addend_list) +        for line in lines: +            print(line) + +    def dump_rel(self, to_dump): +        header = ["r_offset", "r_info"] +        r_offset_list = [entry["r_offset"] for entry in to_dump] +        r_info_list = [entry["r_info"] for entry in to_dump] +        lines = ffs(2, header, True, r_offset_list, r_info_list) +        for line in lines: +            print(line) + +    def get_st_entry_symbol_string(self, index, section_name): +        symbol = [] +        for i in range(0, byte2int(self.elfhdr.e_shnum)): +            name = self.read_section_name(byte2int(self.shhdr[i].sh_name)) +            if ( +                byte2int(self.shhdr[i].sh_type) == sh_type_e.SHT_STRTAB +                and name == section_name +            ): +                self.so.seek(byte2int(self.shhdr[i].sh_offset) + index, 0) +                byte = self.so.read(1) +                while chr(byte[0]) != "\0": +                    if chr(byte[0]) != "\0": +                        symbol.append(chr(byte[0])) +                    byte = self.so.read(1) +                return symbol + +    def get_symbol_string_table(self, offset): +        symbol = [] +        for i in range( +            0, +            int.from_bytes(self.elfhdr.e_shnum, byteorder="little", signed=False), +        ): +            if ( +                int.from_bytes(self.shhdr[i].sh_type, byteorder="little", signed=False) +                == sh_type_e.SHT_STRTAB +            ): +                self.so.seek( +                    int.from_bytes( +                        self.shhdr[i].sh_offset, +                        byteorder="little", +                        signed=False, +                    ) +                    + offset +                    - 0, +                    0, +                ) +                byte = self.so.read(1) +                while chr(byte[0]) != "\0": +                    if chr(byte[0]) != "\0": +                        symbol.append(chr(byte[0])) +                    byte = self.so.read(1) +                return symbol + +    def dump_inst_sections(self): +        indices = [] +        for section in self.shhdr: +            if ( +                int.from_bytes(section.sh_flags, byteorder="little", signed=False) +                & sh_flags_e.SHF_EXECINSTR +                == sh_flags_e.SHF_EXECINSTR +            ): +                indices.append(int.from_bytes(section.sh_name, byteorder="little")) +        return indices + +    def pop_data_section(self): +        for section in self.shhdr: +            name = self.read_section_name(byte2int(section.sh_name)) +            if name == ".data": +                self.so.seek(byte2int(section.sh_offset)) +                self.data_section = self.so.read(byte2int(section.sh_size)) + +    def pop_text_section(self): +        for section in self.shhdr: +            name = self.read_section_name(byte2int(section.sh_name)) +            if name == ".text": +                self.so.seek(byte2int(section.sh_offset)) +                self.text_section = self.so.read(byte2int(section.sh_size)) + +    def pop_dynamic_entries(self, section_name, struct_to_pop): +        for section in self.shhdr: +            name = self.read_section_name(byte2int(section.sh_name)) +            if name == section_name: +                self.so.seek(byte2int(section.sh_offset)) +                self.dyn_section = self.so.read(byte2int(section.sh_size)) +        length = int(len(self.dyn_section)) +        dummy = {} +        if self.size == 64: +            jmp_val = 8 +        elif self.size == 32: +            jmp_val = 4 +        else: +            jmp_val = 8 +            print("self.size is not set for class " "elf.going with 8 as a default.") +        for offset in range(0, length, jmp_val * 2): +            tag_type = byte2int(self.dyn_section[offset : offset + jmp_val]) +            dummy["tag"] = tag_type +            value = byte2int( +                self.dyn_section[offset + jmp_val : offset + (jmp_val * 2)] +            ) +            dummy["value"] = value +            type_string = get_ph_dynamic_ent_tag_type(tag_type) +            dummy["type_string"] = type_string +            type_string = str() +            struct_to_pop.append(dummy) +            dummy = {} + +    def pop_rela(self, section_name, section_whole, to_pop): +        size = int() +        entsize = int() +        dummy = {} +        step = int() +        if self.size == 64: +            step = 8 +        if self.size == 32: +            step = 4 +        for section in self.shhdr: +            name = self.read_section_name(byte2int(section.sh_name)) +            if name == section_name: +                self.so.seek(byte2int(section.sh_offset)) +                section_whole = self.so.read(byte2int(section.sh_size)) +                size = byte2int(section.sh_size) +                entsize = byte2int(section.sh_entsize) +        if entsize != 0: +            for i in range(0, int(size / entsize)): +                dummy["r_offset"] = byte2int( +                    section_whole[i * entsize : i * entsize + step] +                ) +                dummy["r_info"] = byte2int( +                    section_whole[i * entsize + step : i * entsize + (step * 2)] +                ) +                dummy["r_addend"] = byte2int( +                    section_whole[i * entsize + (step * 2) : i * entsize + (step * 3)], +                    sign=True, +                ) +                to_pop.append(dummy) +                dummy = {} + +    def pop_rel(self, section_name, section_whole, to_pop): +        size = int() +        entsize = int() +        dummy = {} +        step = int() +        if self.size == 64: +            step = 8 +        if self.size == 32: +            step = 4 +        for section in self.shhdr: +            name = self.read_section_name(byte2int(section.sh_name)) +            if name == section_name: +                self.so.seek(byte2int(section.sh_offset)) +                section_whole = self.so.read(byte2int(section.sh_size)) +                size = byte2int(section.sh_size) +                entsize = byte2int(section.sh_entsize) +        for i in range(0, int(size / entsize)): +            dummy["r_offset"] = byte2int( +                section_whole[i * entsize : i * entsize + step] +            ) +            dummy["r_info"] = byte2int( +                section_whole[i * entsize + step : i * entsize + (step * 2)] +            ) +            to_pop.append(dummy) +            dummy = {} + +    # FIXME-ELF64 only +    def pop_got(self): +        for shhdr in self.shhdr: +            name = self.read_section_name(byte2int(shhdr.sh_name)) +            if name == ".got": +                self.so.seek(byte2int(shhdr.sh_offset)) +                self.got = self.so.read(byte2int(shhdr.sh_size)) +                self.so.seek(byte2int(shhdr.sh_offset)) +                for i in range(0, int(byte2int(shhdr.sh_size) / 8)): +                    self.got_ents.append(byte2int(self.so.read(8))) + +    # FIXME-ELF64 only +    def pop_got_plt(self): +        for shhdr in self.shhdr: +            name = self.read_section_name(byte2int(shhdr.sh_name)) +            if name == ".got.plt": +                self.so.seek(byte2int(shhdr.sh_offset)) +                self.got_plt = self.so.read(byte2int(shhdr.sh_size)) +                self.so.seek(byte2int(shhdr.sh_offset)) +                for i in range(0, int(byte2int(shhdr.sh_size) / 8)): +                    self.got_plt_ents.append(byte2int(self.so.read(8))) + +    def dump_got(self): +        header = ["value"] +        value_list = [entry for entry in self.got_ents] +        lines = ffs(2, header, True, value_list) +        for line in lines: +            print(line) + +    def dump_got_plt(self): +        header = ["value"] +        value_list = [entry for entry in self.got_plt_ents] +        lines = ffs(2, header, True, value_list) +        for line in lines: +            print(line) + + +class obj_loader: +    def __init__(self, bytes): +        self.memory = bytes() + +    def load(self, obj): +        for byte in obj: +            self.memory.append(byte) + + +def ch_so_to_exe(path): +    so = open(path, "r+b") +    so.seek(16) +    so.write(bytes([2])) +    print(Colors.purple + "changed so to exe" + Colors.ENDC) +    so.close + + +def ch_exe_to_so(path): +    so = open(path, "r+b") +    so.seek(16) +    so.write(bytes([3])) +    print(Colors.purple + "changed exe to so" + Colors.ENDC) +    so.close + + +def elf_init(): +    so = openSO_r(sys.argv[1]) +    elf = ELF(so) +    elf.init(64) + + +def elf_get_func_names(): +    so = openSO_r(sys.argv[1]) +    elf = ELF(so) +    elf.init(64) +    return elf.dump_symbol_string(ELF_ST_TYPE.STT_FUNC, False) + + +def elf_get_text_section(): +    so = openSO_r(sys.argv[1]) +    elf = ELF(so) +    elf.init(64) +    return elf.dump_section(".text", False) + + +def elf_get_section(name): +    so = openSO_r(sys.argv[1]) +    elf = ELF(so) +    elf.init(64) +    return elf.dump_section(name, False) + + +def elf_get_rodata_section(): +    so = openSO_r(sys.argv[1]) +    elf = ELF(so) +    elf.init(64) +    return elf.dump_section(".rodata", False) + + +# obj here means variables or what the C standard means by objects + + +def elf_get_obj_names(): +    so = openSO_r(sys.argv[1]) +    elf = ELF(so) +    elf.init(64) +    return elf.dump_symbol_string(ELF_ST_TYPE.STT_OBJECT, False) + + +# obj here means variables or what the C standard means by objects + + +def elf_get_obj_sizes(): +    so = openSO_r(sys.argv[1]) +    elf = ELF(so) +    elf.init(64) +    return elf.dump_obj_size(ELF_ST_TYPE.STT_OBJECT, False) + + +def elf_get_func_code(): +    so = openSO_r(sys.argv[1]) +    elf = ELF(so) +    elf.init(64) +    return elf.dump_funcs(False) + + +def elf_get_func_code_byname(): +    so = openSO_r(sys.argv[1]) +    arg = openSO_r(sys.argv[2]) +    elf = ELF(so) +    elf.init(64) +    counter = 0 +    # hit = False +    for name in elf.dump_symbol_string(ELF_ST_TYPE.STT_FUNC, False): +        if name == arg: +            code = elf.dump_funcs(False)[counter] +            # hit = True +        counter += 1 +    return code + + +class Call_Rewriter(object): +    # def __init__(self, obj_code, arch, mode): +    def __init__(self, obj_code): +        self.obj_code = bytes(obj_code) +        self.md = Cs(CS_ARCH_X86, CS_MODE_64) +        # self.md = Cs(arch, mode) + +    def dumpall(self): +        for i in self.md.disasm(self.obj_code, 0x1): +            print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str)) + +    def run(self): +        for i in self.md.disasm(self.obj_code, 0x1): +            if i.mnemonic == "call": +                print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str)) +                print(i.bytes) + + +class Global_Rewriter(object): +    def __init__(self): +        pass + + +class Rewriter(object): +    def __init__(self, path, new_name): +        so = openSO_r(path) +        self.elf = ELF(so) +        self.elf.init(64) +        # shutil.copyfile(path, "/tmp/exe") +        self.magic_section_number = int() +        self.new_name = new_name +        self.shdr_new_size = [] +        self.shdr_new_offset = [] + +    def fix_section_offsets(self, section_name, new_size: int, new_section: bytes): +        # file_w = open(self.new_name, "wb") +        # magic_number = int() +        for i in range(0, byte2int(self.elf.elfhdr.e_shnum)): +            name = self.elf.read_section_name(byte2int(self.elf.shhdr[i].sh_name)) +            if section_name == name: +                self.magic_section_number = i +        print(self.magic_section_number) + +        # copy the sections before magic_number +        # write in the new section +        # fix section headers + +        end = int() +        for i in range(0, byte2int(self.elf.elfhdr.e_shnum)): +            if i > self.magic_section_number: +                extra_chunk = end % byte2int(self.elf.shhdr[i].sh_addralign) +                missing_chunk = byte2int(self.elf.shhdr[i].sh_addralign) - extra_chunk +                assert missing_chunk > 0, "missing chunk is negative" +                self.shdr_new_size.append(byte2int(self.elf.shhdr[i].sh_size)) +                self.shdr_new_offset.append( +                    end + missing_chunk % byte2int(self.elf.shhdr[i].sh_addralign) +                ) +                end = self.shdr_new_offset[-1] + self.shdr_new_size[-1] + +            elif i < self.magic_section_number: +                self.shdr_new_size.append(byte2int(self.elf.shhdr[i].sh_size)) +                self.shdr_new_offset.append(byte2int(self.elf.shhdr[i].sh_offset)) +            elif i == self.magic_section_number: +                self.shdr_new_size.append(new_size) +                self.shdr_new_offset.append(byte2int(self.elf.shhdr[i].sh_offset)) +                end = byte2int(self.elf.shhdr[i].sh_offset) + new_size +        for size in self.shdr_new_size: +            print(repr(i) + " new size is " + repr(size)) +        for offset in self.shdr_new_offset: +            print(repr(i) + " new offset is " + repr(offset)) + + +def main() -> None: +    argparser = CLIArgParser() +    so = openSO_r(argparser.args.obj) +    elf = ELF(so) +    elf.init(64) +    if argparser.args.header: +        elf.dump_header() +    elif argparser.args.symboltable: +        elf.dump_symbol_tb(".strtab", sh_type_e.SHT_STRTAB) +        elf.dump_symbol_tb(".dynstr", sh_type_e.SHT_STRTAB) +    elif argparser.args.phdrs: +        elf.dump_phdrs() +    elif argparser.args.shdrs: +        elf.dump_shdrs() +    elif argparser.args.symbolindex: +        elf.dump_symbol_idx() +    elif argparser.args.stentries: +        elf.dump_st_entries() +    elif argparser.args.objcode: +        elf.dump_funcs(True) +    elif argparser.args.funcs: +        elf.dump_symbol_string(ELF_ST_TYPE.STT_FUNC, True) +    elif argparser.args.objs: +        elf.dump_symbol_string(ELF_ST_TYPE.STT_OBJECT, True) +    elif argparser.args.dynsym: +        elf.dump_st_entries_dyn() +    elif argparser.args.dlpath: +        elf.dump_section(".interp", True) +    elif argparser.args.section: +        elf.dump_section(argparser.args.section, True) +    elif argparser.args.test2: +        rewriter = Rewriter(argparser.args.obj, "new_exe") +        new_text = bytes() +        rewriter.fix_section_offsets(".text", 1000, new_text) +    elif argparser.args.dumpfunc: +        counter = 0 +        for name in elf.dump_symbol_string(ELF_ST_TYPE.STT_FUNC, False): +            if name == argparser.args.dumpfunc: +                print(Colors.red + Colors.BOLD + name + Colors.ENDC) +                code = elf.dump_funcs(False)[counter] +                print(code) +            counter += 1 +    elif argparser.args.dumpfuncasm: +        counter = 0 +        hit = False +        for name in elf.dump_symbol_string(ELF_ST_TYPE.STT_FUNC, False): +            if name == argparser.args.dumpfuncasm: +                code = elf.dump_funcs(False)[counter] +                hit = True +            counter += 1 +        if hit: +            md = Cs(CS_ARCH_X86, CS_MODE_64) +            for i in md.disasm(bytes(code), 0x0): +                print(hex(i.address).ljust(7), i.mnemonic.ljust(7), i.op_str) +    elif argparser.args.phdynent: +        elf.dump_ph_dyn_entries() +    elif argparser.args.disass: +        for section in elf.shhdr: +            name = elf.read_section_name(byte2int(section.sh_name)) +            if name == argparser.args.disass: +                if byte2int(section.sh_flags) & 0x4 != 0x04: +                    print( +                        "section is not executable...but, " +                        "since you asked, here you go..." +                    ) +                elf.so.seek(byte2int(section.sh_offset)) +                code = elf.so.read(byte2int(section.sh_size)) +                md = Cs(CS_ARCH_X86, CS_MODE_64) +                for i in md.disasm(bytes(code), 0x0): +                    print(hex(i.address).ljust(7), i.mnemonic.ljust(7), i.op_str) +    elif argparser.args.disassp is not None: +        index = argparser.args.disassp +        # section not executable message +        if byte2int(elf.phdr[index].p_flags) & 0x1 != 1: +            print("program header section is not " "executable but since you asked...") +        header_offset = elf.phdr[index].p_offset +        header_size = elf.phdr[index].p_filesz +        elf.so.seek(byte2int(header_offset)) +        code = elf.so.read(byte2int(header_size)) +        md = Cs(CS_ARCH_X86, CS_MODE_64) +        for i in md.disasm(bytes(code), 0x0): +            print(hex(i.address).ljust(7), i.mnemonic.ljust(7), i.op_str) +    elif argparser.args.textasm: +        md = Cs(CS_ARCH_X86, CS_MODE_64) +        for i in md.disasm(bytes(elf.text_section), 0x0): +            print(hex(i.address).ljust(7), i.mnemonic.ljust(7), i.op_str) +    elif argparser.args.dynsecents: +        elf.dump_dyn_sec_ents(elf.dyn_section_ents) +    elif argparser.args.reladyn: +        elf.dump_rela(elf.rela_dyn_ents) +    elif argparser.args.relaplt: +        elf.dump_rela(elf.rela_plt_ents) +    elif argparser.args.got: +        elf.pop_got() +        elf.dump_got() +    elif argparser.args.gotplt: +        elf.pop_got_plt() +        elf.dump_got_plt() +    elif argparser.args.listdso: +        os.environ["LD_TRACE_LOADED_OBJECTS"] = "1" +        os.environ["LD_WARN"] = "yes" +        os.environ["LD_BIND_NOW"] = "yes" +        # os.environ["LD_VERBOSE"] = "yes" +        # os.environ["LD_DEBUG"] = "all" +        rtldlist = [ +            "/usr/lib/ld-linux.so.2", +            "/usr/lib64/ld-linux-x86-64.so.2", +            "/usr/libx32/ld-linux-x32.so.2", +        ] +        for rtld in rtldlist: +            if os.path.exists(rtld): +                result = subprocess.run( +                    [rtld, argparser.args.obj], +                    capture_output=True, +                ) +                print(result.stdout.decode("utf-8")) +                break +    else: +        print("why even bother if you were not gonna type anythng decent in?") + + +if __name__ == "__main__": +    main() | 
