aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xload.py153
1 files changed, 144 insertions, 9 deletions
diff --git a/load.py b/load.py
index 73ff05e..da361d6 100755
--- a/load.py
+++ b/load.py
@@ -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():