diff options
| -rwxr-xr-x | load.py | 153 | 
1 files changed, 144 insertions, 9 deletions
| @@ -84,7 +84,10 @@ class CLIArgParser(object):          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="disassemblt a section") +        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.") @@ -167,11 +170,11 @@ def ffs(offset,header_list, numbered, *args):      if numbered:          numbers_f.extend(range(1, len(args[-1])+1)) -        max_column_width.append(max([len(repr(number)) for number in numbers_f])) +        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])) +        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): @@ -539,6 +542,41 @@ class X86_64_REL_TYPE:      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" @@ -563,6 +601,42 @@ def get_x86_64_rel_type(val):      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_TPE_2.R_X86_64_NONE: return"R_X86_64_NONE" +    elif val == X86_64_REL_TPE_2.R_X86_64_64: return"R_X86_64_64" +    elif val == X86_64_REL_TPE_2.R_X86_64_PC32: return"R_X86_64_PC32" +    elif val == X86_64_REL_TPE_2.R_X86_64_GOT32: return"R_X86_64_GOT32" +    elif val == X86_64_REL_TPE_2.R_X86_64_PLT32: return"R_X86_64_PLT32" +    elif val == X86_64_REL_TPE_2.R_X86_64_COPY: return"R_X86_64_COPY" +    elif val == X86_64_REL_TPE_2.R_X86_64_GLOB_DAT: return"R_X86_64_GLOB_DAT" +    elif val == X86_64_REL_TPE_2.R_X86_64_JUMP_SLOT: return"R_X86_64_JUMP_SLOT" +    elif val == X86_64_REL_TPE_2.R_X86_64_RELATIVE: return"R_X86_64_RELATIVE" +    elif val == X86_64_REL_TPE_2.R_X86_64_GOTPCREL: return"R_X86_64_GOTPCREL" +    elif val == X86_64_REL_TPE_2.R_X86_64_32: return"R_X86_64_32" +    elif val == X86_64_REL_TPE_2.R_X86_64_32S: return"R_X86_64_32S" +    elif val == X86_64_REL_TPE_2.R_X86_64_16: return"R_X86_64_16" +    elif val == X86_64_REL_TPE_2.R_X86_64_PC16: return"R_X86_64_PC16" +    elif val == X86_64_REL_TPE_2.R_X86_64_64_8: return"R_X86_64_64_8" +    elif val == X86_64_REL_TPE_2.R_X86_64_PC8: return"R_X86_64_PC8" +    elif val == X86_64_REL_TPE_2.R_X86_64_DTPMOD64: return"R_X86_64_DTPMOD64" +    elif val == X86_64_REL_TPE_2.R_X86_64_DTPOFF64: return"R_X86_64_DTPOFF64" +    elif val == X86_64_REL_TPE_2.R_X86_64_TPOFF64: return"R_X86_64_TPOFF64" +    elif val == X86_64_REL_TPE_2.R_X86_64_TLSGD: return"R_X86_64_TLSGD" +    elif val == X86_64_REL_TPE_2.R_X86_64_TLSLD: return"R_X86_64_TLSLD" +    elif val == X86_64_REL_TPE_2.R_X86_64_DTPOFF32: return"R_X86_64_DTPOFF32" +    elif val == X86_64_REL_TPE_2.R_X86_64_GOTTPOFF: return"R_X86_64_GOTTPOFF" +    elif val == X86_64_REL_TPE_2.R_X86_64_TPOFF32: return"R_X86_64_TPOFF32" +    elif val == X86_64_REL_TPE_2.R_X86_64_PC64: return"R_X86_64_PC64" +    elif val == X86_64_REL_TPE_2.R_X86_64_GOTOFF64: return"R_X86_64_GOTOFF64" +    elif val == X86_64_REL_TPE_2.R_X86_64_GOTPC32: return"R_X86_64_GOTPC32" +    elif val == X86_64_REL_TPE_2.R_X86_64_SIZE32: return"R_X86_64_SIZE32" +    elif val == X86_64_REL_TPE_2.R_X86_64_SIZE64: return"R_X86_64_SIZE64" +    elif val == X86_64_REL_TPE_2.R_X86_64_GOTPC32_TLDSEC: return"R_X86_64_GOTPC32_TLDSEC" +    elif val == X86_64_REL_TPE_2.R_X86_64_TLDSEC_CALL: return"R_X86_64_TLDSEC_CALL" +    elif val == X86_64_REL_TPE_2.R_X86_64_TLDSEC: return"R_X86_64_TLDSEC" +    elif val == X86_64_REL_TPE_2.R_X86_64_IRELATIVE: return"R_X86_64_IRELATIVE" +    else: return "UNKNOWN" +  class ELF_ST_BIND:      STB_LOCAL = 0      STB_GLOBAL = 1 @@ -737,6 +811,14 @@ class ELF(object):          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 @@ -1205,12 +1287,13 @@ class ELF(object):                  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)]) -            dummy["r_addend"] = byte2int(section_whole[i*entsize+(step*2):i*entsize+(step*3)], sign=True) -            to_pop.append(dummy) -            dummy = {} +        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() @@ -1232,6 +1315,41 @@ class ELF(object):              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): @@ -1438,6 +1556,17 @@ def premain(argparser):                  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 != 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): @@ -1445,6 +1574,12 @@ def premain(argparser):      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()      else: print("why even bother if you were not gonna type anythng decent in?")  def main(): | 
