diff options
author | terminaldweller <devi@terminaldweller.com> | 2023-11-09 01:16:43 +0000 |
---|---|---|
committer | terminaldweller <devi@terminaldweller.com> | 2023-11-09 01:16:43 +0000 |
commit | 143898301ae86e2cca2ade4088fe63a9b7d84331 (patch) | |
tree | cd727b87a0feeab2266990276ea6d0957fc0bc09 /load.py | |
parent | added a new option --listdso, fixes #1, formatted code with black (diff) | |
download | delf-143898301ae86e2cca2ade4088fe63a9b7d84331.tar.gz delf-143898301ae86e2cca2ade4088fe63a9b7d84331.zip |
added to pypi
Diffstat (limited to 'load.py')
-rwxr-xr-x | load.py | 2448 |
1 files changed, 0 insertions, 2448 deletions
diff --git a/load.py b/load.py deleted file mode 100755 index 091926d..0000000 --- a/load.py +++ /dev/null @@ -1,2448 +0,0 @@ -#!/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 signal -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 ExceptionHandler(object): - def __init__(self, globals, locals): - self.variables = globals().copy() - self.variables.update(locals()) - self.shell = code.InteractiveConsole() - - -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") - elif 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 premain(argparser): - 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?") - - -def main(): - argparser = CLIArgParser() - if argparser.args.dbg: - try: - premain(argparser) - except Exception as e: - print(e.__doc__) - if e.message: - print(e.message) - signal.signal(signal.SIGINT, SigHandler_SIGINT) - variables = globals().copy() - variables.update(locals()) - shell = code.InteractiveConsole(variables) - shell.interact(banner="DELF REPL") - else: - premain(argparser) - - -if __name__ == "__main__": - main() |