diff options
-rwxr-xr-x | bfd/load.py | 332 | ||||
-rw-r--r-- | bruiser/bruiser-extra.h | 3 | ||||
-rw-r--r-- | bruiser/bruiser.cpp | 85 | ||||
-rw-r--r-- | bruiser/bruiser.h | 121 | ||||
-rw-r--r-- | bruiser/executioner.cpp | 47 | ||||
-rwxr-xr-x | mutator.py | 31 | ||||
-rw-r--r-- | obfuscator/obfuscator.cpp | 1 |
7 files changed, 476 insertions, 144 deletions
diff --git a/bfd/load.py b/bfd/load.py index 4c681c3..94e51ad 100755 --- a/bfd/load.py +++ b/bfd/load.py @@ -1,6 +1,15 @@ #!/bin/python3 import argparse import sys +import readline +import code + +class ExceptionHandler(object): + def __init__(self, globals, locals): + self.variables = globals().copy() + self.variables.update(locals()) + self.shell = code.InteractiveConsole() + shell.interact(banner="Object Loader Prototype") class CLIArgParser(object): def __init__(self): @@ -10,6 +19,36 @@ class CLIArgParser(object): if self.args.obj is None: raise Exception("no object file provided. please specify an object with --obj.") +def byte2int(value): + return int.from_bytes(value, byteorder="little", signed=False) + +def byte2hex(value): + return hex(int.from_bytes(value, byteorder="little", signed=False)) + +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 @@ -30,7 +69,9 @@ class sh_type_e: SHT_SYMTAB_SHNDX = 0x12 SHT_NUM = 0x13 SHT_LOOS = 0x60000000 - + GNU_HASH = 0x6ffffff6 + VERSYM = 0x6fffffff + VERNEED= 0x6ffffffe class sh_flags_e: SHF_WRITE = 0x1 @@ -48,7 +89,6 @@ class sh_flags_e: SHF_ORDERED = 0x4000000 SHF_EXCLUDE = 0x8000000 - class p_type_e: PT_NULL = 0x0 PT_LOAD = 0x1 @@ -61,7 +101,26 @@ class p_type_e: 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 Colors: purple = '\033[95m' @@ -76,17 +135,14 @@ class Colors: 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, @@ -113,7 +169,6 @@ class ELFHDR(): 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): @@ -127,7 +182,6 @@ class PHDR(): 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): @@ -142,7 +196,6 @@ class SHDR(): 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): self.st_name = st_name @@ -152,7 +205,6 @@ class Symbol_Table_Entry64(): self.st_value = st_value self.st_size = st_size - class ELF(object): def __init__(self, so): self.so = so @@ -163,7 +215,9 @@ class ELF(object): self.size = int() self.string_tb_e = [] self.string_tb_e_dyn = [] - self.symbols = [] + self.symbol_table_e = [] + self.data_section = [] + self.text_section = [] def init(self, size): self.size = size @@ -176,39 +230,27 @@ class ELF(object): shnum = int.from_bytes(self.elfhdr.e_shnum, byteorder="little", signed=False) for i in range(0, shnum): self.read_SHDR(size) - #self.read_SHDR(size) for i in range(0, shnum): type = int.from_bytes(self.shhdr[i].sh_type, byteorder="little", signed=False) if type == sh_type_e.SHT_SYMTAB: - print(Colors.green, end="") - print("size: " + repr(int.from_bytes(self.shhdr[i].sh_size, byteorder="little"))) - print("offset: " + repr(int.from_bytes(self.shhdr[i].sh_offset, byteorder="little"))) self.so.seek(int.from_bytes(self.shhdr[i].sh_offset, byteorder="little", signed=False), 0) symbol_tb = self.so.read(int.from_bytes(self.shhdr[i].sh_size, byteorder="little", signed=False)) - #print(symbol_tb) offset = 0 num = int(int.from_bytes(self.shhdr[i].sh_size, byteorder="little") / 24) - print(num) for j in range(0, num): self.read_st_entry(symbol_tb[offset:offset + 24], self.string_tb_e) offset += 8*24 - print(Colors.ENDC) if type == sh_type_e.SHT_DYNSYM: - print(Colors.green, end="") - print("size: " + repr(int.from_bytes(self.shhdr[i].sh_size, byteorder="little"))) - print("offset: " + repr(int.from_bytes(self.shhdr[i].sh_offset, byteorder="little"))) self.so.seek(int.from_bytes(self.shhdr[i].sh_offset, byteorder="little", signed=False), 0) symbol_tb = self.so.read(int.from_bytes(self.shhdr[i].sh_size, byteorder="little", signed=False)) - #print(symbol_tb) offset = 0 num = int(int.from_bytes(self.shhdr[i].sh_size, byteorder="little") / 24) - print(num) for j in range(0, num): self.read_st_entry(symbol_tb[offset:offset + 24], self.string_tb_e_dyn) offset += 8*24 - print(Colors.ENDC) + self.pop_data_section() + self.pop_text_section() - # 32 or 64 def read_ELF_H(self, size): self.elfhdr.ei_mag = self.so.read(4) self.elfhdr.ei_class = self.so.read(1) @@ -284,114 +326,179 @@ class ELF(object): dummy.st_size = st[16:24] 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 dump_objs(self): + ret_list = [] + dummy = [] + ret_list_int = [] for iter in self.string_tb_e: - self.so.seek(int.from_bytes(iter.st_value, byteorder="little")) - obj = self.so.read(int.from_bytes(iter.st_size, byteorder="little")) - for byte in obj: - print(chr(byte)) + if byte2int(iter.st_size) != 0: + 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 = [] + return ret_list_int def dump_symbol_idx(self): print(Colors.green + "symbol:" + Colors.ENDC) for iter in self.string_tb_e: - if not int.from_bytes(iter.st_size, byteorder="little") == 0: - print("-----------------------------------------------------------------") - print(Colors.blue + "name: " + Colors.cyan + repr(int.from_bytes(iter.st_name, byteorder="little")) + Colors.ENDC) - print(Colors.blue + "size: " + Colors.cyan + repr(int.from_bytes(iter.st_size, byteorder="little")) + Colors.ENDC) - print(Colors.blue + "value: " + Colors.cyan + repr(int.from_bytes(iter.st_value, byteorder="little")) + Colors.ENDC) - print(Colors.blue + "info: " + Colors.cyan + repr(int.from_bytes(iter.st_info, byteorder="little")) + Colors.ENDC) - print(Colors.blue + "other: " + Colors.cyan + repr(int.from_bytes(iter.st_other, byteorder="little")) + Colors.ENDC) - print(Colors.blue + "shndx: " + Colors.cyan + repr(int.from_bytes(iter.st_shndx, byteorder="little")) + Colors.ENDC) - print("-----------------------------------------------------------------") + print(Colors.blue + "name: " + Colors.cyan + repr(int.from_bytes(iter.st_name, byteorder="little")) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "size: " + Colors.cyan + repr(int.from_bytes(iter.st_size, byteorder="little")) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "value: " + Colors.cyan + repr(int.from_bytes(iter.st_value, byteorder="little")) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "info: " + Colors.cyan + repr(int.from_bytes(iter.st_info, byteorder="little")) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "other: " + Colors.cyan + repr(int.from_bytes(iter.st_other, byteorder="little")) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "shndx: " + Colors.cyan + repr(int.from_bytes(iter.st_shndx, byteorder="little")) + Colors.ENDC) print(Colors.green + "dyn symbol:" + Colors.ENDC) for iter in self.string_tb_e_dyn: - if not int.from_bytes(iter.st_size, byteorder="little") == 0: - print("-----------------------------------------------------------------") - print(Colors.blue + "name: " + Colors.cyan + repr(int.from_bytes(iter.st_name, byteorder="little")) + Colors.ENDC) - print(Colors.blue + "size: " + Colors.cyan + repr(int.from_bytes(iter.st_size, byteorder="little")) + Colors.ENDC) - print(Colors.blue + "value: " + Colors.cyan + repr(int.from_bytes(iter.st_value, byteorder="little")) + Colors.ENDC) - print(Colors.blue + "info: " + Colors.cyan + repr(int.from_bytes(iter.st_info, byteorder="little")) + Colors.ENDC) - print(Colors.blue + "other: " + Colors.cyan + repr(int.from_bytes(iter.st_other, byteorder="little")) + Colors.ENDC) - print(Colors.blue + "shndx: " + Colors.cyan + repr(int.from_bytes(iter.st_shndx, byteorder="little")) + Colors.ENDC) - print("-----------------------------------------------------------------") + print(Colors.blue + "name: " + Colors.cyan + repr(int.from_bytes(iter.st_name, byteorder="little")) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "size: " + Colors.cyan + repr(int.from_bytes(iter.st_size, byteorder="little")) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "value: " + Colors.cyan + repr(int.from_bytes(iter.st_value, byteorder="little")) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "info: " + Colors.cyan + repr(int.from_bytes(iter.st_info, byteorder="little")) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "other: " + Colors.cyan + repr(int.from_bytes(iter.st_other, byteorder="little")) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "shndx: " + Colors.cyan + repr(int.from_bytes(iter.st_shndx, byteorder="little")) + Colors.ENDC) def dump_header(self): print("------------------------------------------------------------------------------") print(Colors.green + "elf header:" + Colors.ENDC) print(Colors.blue + "ei_mag: " + Colors.cyan + repr(self.elfhdr.ei_mag) + Colors.ENDC) - print(Colors.blue + "ei_class: " + Colors.cyan + repr(self.elfhdr.ei_class) + Colors.ENDC) - print(Colors.blue + "ei_data: " + Colors.cyan + repr(self.elfhdr.ei_data) + Colors.ENDC) - print(Colors.blue + "ei_version: " + Colors.cyan + repr(self.elfhdr.ei_version) + Colors.ENDC) - print(Colors.blue + "ei_osabi: " + Colors.cyan + repr(self.elfhdr.ei_osabi) + Colors.ENDC) - print(Colors.blue + "ei_abiversion: " + Colors.cyan + repr(self.elfhdr.ei_abiversion) + Colors.ENDC) - print(Colors.blue + "ei_pad: " + Colors.cyan + repr(self.elfhdr.ei_pad) + Colors.ENDC) - print(Colors.blue + "e_type: " + Colors.cyan + repr(self.elfhdr.e_type) + Colors.ENDC) - print(Colors.blue + "e_machine: " + Colors.cyan + repr(self.elfhdr.e_machine) + Colors.ENDC) - print(Colors.blue + "e_version: " + Colors.cyan + repr(self.elfhdr.e_version) + Colors.ENDC) - print(Colors.blue + "e_entry: " + Colors.cyan + repr(self.elfhdr.e_entry) + Colors.ENDC) - print(Colors.blue + "e_phoff: " + Colors.cyan + repr(self.elfhdr.e_phoff) + Colors.ENDC) - print(Colors.blue + "e_shoff: " + Colors.cyan + repr(self.elfhdr.e_shoff) + Colors.ENDC) - print(Colors.blue + "e_flags: " + Colors.cyan + repr(self.elfhdr.e_flags) + Colors.ENDC) - print(Colors.blue + "e_ehsize: " + Colors.cyan + repr(self.elfhdr.e_ehsize) + Colors.ENDC) - print(Colors.blue + "e_phentsize: " + Colors.cyan + repr(self.elfhdr.e_phentsize) + Colors.ENDC) - print(Colors.blue + "e_phnum: " + Colors.cyan + repr(self.elfhdr.e_phnum) + Colors.ENDC) - print(Colors.blue + "e_shentsize: " + Colors.cyan + repr(self.elfhdr.e_shentsize) + Colors.ENDC) - print(Colors.blue + "e_shnum: " + Colors.cyan + repr(self.elfhdr.e_shnum) + Colors.ENDC) - print(Colors.blue + "e_shstrndx: " + Colors.cyan + repr(self.elfhdr.e_shstrndx) + Colors.ENDC) + print(Colors.blue + "ei_class: " + Colors.cyan + repr(byte2int(self.elfhdr.ei_class)) + Colors.ENDC) + print(Colors.blue + "ei_data: " + Colors.cyan + repr(byte2int(self.elfhdr.ei_data)) + Colors.ENDC) + print(Colors.blue + "ei_version: " + Colors.cyan + repr(byte2int(self.elfhdr.ei_version)) + Colors.ENDC) + print(Colors.blue + "ei_osabi: " + Colors.cyan + repr(byte2int(self.elfhdr.ei_osabi)) + Colors.ENDC) + print(Colors.blue + "ei_abiversion: " + Colors.cyan + repr(byte2int(self.elfhdr.ei_abiversion)) + Colors.ENDC) + print(Colors.blue + "ei_pad: " + Colors.cyan + repr(byte2int(self.elfhdr.ei_pad)) + Colors.ENDC) + print(Colors.blue + "e_type: " + Colors.cyan + repr(byte2int(self.elfhdr.e_type)) + Colors.ENDC) + print(Colors.blue + "e_machine: " + Colors.cyan + repr(byte2int(self.elfhdr.e_machine)) + Colors.ENDC) + print(Colors.blue + "e_version: " + Colors.cyan + repr(byte2int(self.elfhdr.e_version)) + Colors.ENDC) + print(Colors.blue + "e_entry: " + Colors.cyan + repr(byte2int(self.elfhdr.e_entry)) + Colors.ENDC) + print(Colors.blue + "e_phoff: " + Colors.cyan + repr(byte2int(self.elfhdr.e_phoff)) + Colors.ENDC) + print(Colors.blue + "e_shoff: " + Colors.cyan + repr(byte2int(self.elfhdr.e_shoff)) + Colors.ENDC) + print(Colors.blue + "e_flags: " + Colors.cyan + repr(byte2int(self.elfhdr.e_flags)) + Colors.ENDC) + print(Colors.blue + "e_ehsize: " + Colors.cyan + repr(byte2int(self.elfhdr.e_ehsize)) + Colors.ENDC) + print(Colors.blue + "e_phentsize: " + Colors.cyan + repr(byte2int(self.elfhdr.e_phentsize)) + Colors.ENDC) + print(Colors.blue + "e_phnum: " + Colors.cyan + repr(byte2int(self.elfhdr.e_phnum)) + Colors.ENDC) + print(Colors.blue + "e_shentsize: " + Colors.cyan + repr(byte2int(self.elfhdr.e_shentsize)) + Colors.ENDC) + print(Colors.blue + "e_shnum: " + Colors.cyan + repr(byte2int(self.elfhdr.e_shnum)) + Colors.ENDC) + print(Colors.blue + "e_shstrndx: " + Colors.cyan + repr(byte2int(self.elfhdr.e_shstrndx)) + Colors.ENDC) print("------------------------------------------------------------------------------") def dump_phdrs(self): - print(Colors.green + "pheaders:" + Colors.ENDC) + print(Colors.green + Colors.BOLD + "pheaders:" + Colors.ENDC) for i in range(0, int.from_bytes(self.elfhdr.e_phnum, byteorder="little", signed=False)): - print("------------------------------------------------------------------------------") - print(Colors.blue + "p_type: " + Colors.cyan + repr(self.phdr[i].p_type) + Colors.ENDC) - print(Colors.blue + "p_flags: " + Colors.cyan + repr(self.phdr[i].p_flags) + Colors.ENDC) - print(Colors.blue + "p_offset: " + Colors.cyan + repr(self.phdr[i].p_offset) + Colors.ENDC) - print(Colors.blue + "p_vaddr: " + Colors.cyan + repr(self.phdr[i].p_vaddr) + Colors.ENDC) - print(Colors.blue + "p_paddr: " + Colors.cyan + repr(self.phdr[i].p_paddr) + Colors.ENDC) - print(Colors.blue + "p_filesz: " + Colors.cyan + repr(self.phdr[i].p_filesz) + Colors.ENDC) - print(Colors.blue + "p_memsz: " + Colors.cyan + repr(self.phdr[i].p_memsz) + Colors.ENDC) - print(Colors.blue + "p_flags2: " + Colors.cyan + repr(self.phdr[i].p_flags2) + Colors.ENDC) - print(Colors.blue + "p_align: " + Colors.cyan + repr(self.phdr[i].p_align) + Colors.ENDC) - print("------------------------------------------------------------------------------") + type = get_ph_type(byte2int(self.phdr[i].p_type)) + print(Colors.blue + "p_type: " + Colors.cyan + type + Colors.ENDC, end="") + print(Colors.blue + " p_flags: " + Colors.cyan + repr(byte2int(self.phdr[i].p_flags)) + Colors.ENDC, end="") + print(Colors.blue + " p_offset: " + Colors.cyan + repr(byte2int(self.phdr[i].p_offset)) + Colors.ENDC, end="") + print(Colors.blue + " p_vaddr: " + Colors.cyan + repr(byte2int(self.phdr[i].p_vaddr)) + Colors.ENDC, end="") + print(Colors.blue + " p_paddr: " + Colors.cyan + repr(byte2int(self.phdr[i].p_paddr)) + Colors.ENDC, end="") + print(Colors.blue + " p_filesz: " + Colors.cyan + repr(byte2int(self.phdr[i].p_filesz)) + Colors.ENDC, end="") + print(Colors.blue + " p_memsz: " + Colors.cyan + repr(byte2int(self.phdr[i].p_memsz)) + Colors.ENDC, end="") + print(Colors.blue + " p_flags2: " + Colors.cyan + repr(self.phdr[i].p_flags2) + Colors.ENDC, end="") + print(Colors.blue + " p_align: " + Colors.cyan + repr(byte2int(self.phdr[i].p_align)) + Colors.ENDC) def dump_shdrs(self): - print(Colors.green + "sheaders:" + Colors.ENDC) + print(Colors.green + Colors.BOLD + "sheaders:" + Colors.ENDC) + counter = int() for i in range(0, int.from_bytes(self.elfhdr.e_shnum, byteorder="little", signed=False)): - print("------------------------------------------------------------------------------") - print(Colors.blue + "sh_name: " + Colors.cyan + repr(self.shhdr[i].sh_name) + Colors.ENDC) - print(Colors.blue + "sh_type: " + Colors.cyan + repr(self.shhdr[i].sh_type) + Colors.ENDC) - print(Colors.blue + "sh_flags: " + Colors.cyan + repr(self.shhdr[i].sh_flags) + Colors.ENDC) - print(Colors.blue + "sh_addr: " + Colors.cyan + repr(self.shhdr[i].sh_addr) + Colors.ENDC) - print(Colors.blue + "sh_offset: " + Colors.cyan + repr(self.shhdr[i].sh_offset) + Colors.ENDC) - print(Colors.blue + "sh_size: " + Colors.cyan + repr(self.shhdr[i].sh_size) + Colors.ENDC) - print(Colors.blue + "sh_link: " + Colors.cyan + repr(self.shhdr[i].sh_link) + Colors.ENDC) - print(Colors.blue + "sh_info: " + Colors.cyan + repr(self.shhdr[i].sh_info) + Colors.ENDC) - print(Colors.blue + "sh_addralign: " + Colors.cyan + repr(self.shhdr[i].sh_addralign) + Colors.ENDC) - print(Colors.blue + "sh_entsize: " + Colors.cyan + repr(self.shhdr[i].sh_entsize) + Colors.ENDC) - print("------------------------------------------------------------------------------") + name = self.read_section_name(byte2int(self.shhdr[i].sh_name)) + print(Colors.green + Colors.BOLD + repr(counter) + Colors.ENDC, end="") + print(" ", end="") + print(Colors.blue + "sh_name: " + Colors.cyan + name + Colors.ENDC, end="") + print("\t", end="") + type = get_section_type_string(byte2int(self.shhdr[i].sh_type)) + print(Colors.blue + "sh_type: " + Colors.cyan + type + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "sh_flags: " + Colors.cyan + repr(byte2int(self.shhdr[i].sh_flags)) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "sh_addr: " + Colors.cyan + repr(byte2int(self.shhdr[i].sh_addr)) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "sh_offset: " + Colors.cyan + repr(byte2int(self.shhdr[i].sh_offset)) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "sh_size: " + Colors.cyan + repr(byte2int(self.shhdr[i].sh_size)) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "sh_link: " + Colors.cyan + repr(byte2int(self.shhdr[i].sh_link)) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "sh_info: " + Colors.cyan + repr(byte2int(self.shhdr[i].sh_info)) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "sh_addralign: " + Colors.cyan + repr(byte2int(self.shhdr[i].sh_addralign)) + Colors.ENDC, end="") + print("\t", end="") + print(Colors.blue + "sh_entsize: " + Colors.cyan + repr(byte2int(self.shhdr[i].sh_entsize)) + Colors.ENDC) + counter += 1 def dump_symbol_tb(self): for i in range(0, int.from_bytes(self.elfhdr.e_shnum, byteorder="little", signed=False)): - #print(repr(int.from_bytes(self.shhdr[i].sh_type, byteorder="little", signed=False)) + " : ", end='') - #print(int.from_bytes(self.shhdr[i].sh_size, byteorder="little", signed=False)) - if int.from_bytes(self.shhdr[i].sh_type, byteorder="little", signed=False) == sh_type_e.SHT_SYMTAB: - self.so.seek(int.from_bytes(self.shhdr[i].sh_offset, byteorder="little", signed=False), 0) - #print(self.so.read(int.from_bytes(self.shhdr[i].sh_size, byteorder="little", signed=False))) - symbol_tb = self.so.read(int.from_bytes(self.shhdr[i].sh_size, byteorder="little", signed=False)) - if int.from_bytes(self.shhdr[i].sh_type, byteorder="little", signed=False) == sh_type_e.SHT_DYNSYM: - self.so.seek(int.from_bytes(self.shhdr[i].sh_offset, byteorder="little", signed=False), 0) - #print(self.so.read(int.from_bytes(self.shhdr[i].sh_size, byteorder="little", signed=False))) - symbol_tb = self.so.read(int.from_bytes(self.shhdr[i].sh_size, byteorder="little", signed=False)) if int.from_bytes(self.shhdr[i].sh_type, byteorder="little", signed=False) == sh_type_e.SHT_STRTAB: + print(Colors.BOLD + Colors.yellow + "STRING TABLE:" + Colors.ENDC) self.so.seek(int.from_bytes(self.shhdr[i].sh_offset, byteorder="little", signed=False), 0) - #print(self.so.read(int.from_bytes(self.shhdr[i].sh_size, byteorder="little", signed=False))) symbol_tb = self.so.read(int.from_bytes(self.shhdr[i].sh_size, byteorder="little", signed=False)) - #print(symbol_tb.decode("utf-8")) for byte in symbol_tb: print(chr(byte), end='') if chr(byte) == '\0': print() + def dump_st_entries(self): + for entry in self.string_tb_e: + print(Colors.green + "name: " + Colors.ENDC + repr(byte2int(entry.st_name)), end="") + print(Colors.green + " value: " + Colors.ENDC + repr(byte2int(entry.st_value)), end="") + print(Colors.green + " size: " + Colors.ENDC + repr(byte2int(entry.st_size)), end="") + print(Colors.green + " info: " + Colors.ENDC + repr(byte2int(entry.st_info)), end="") + print(Colors.green + " other: " + Colors.ENDC + repr(byte2int(entry.st_other)), end="") + print(Colors.green + " shndx: " + Colors.ENDC + repr(byte2int(entry.st_shndx))) + + 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)) class obj_loader(): def __init__(self, bytes): @@ -401,7 +508,6 @@ class obj_loader(): for byte in obj: self.memory.append(byte) - def ch_so_to_exe(path): so = open(path, "r+b") so.seek(16) @@ -409,13 +515,12 @@ def ch_so_to_exe(path): 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 main(): #argparser = CLIArgParser() @@ -427,18 +532,13 @@ def main(): #elf.dump_header() #elf.dump_symbol_tb() #elf.dump_phdrs() - elf.dump_shdrs() + #elf.dump_shdrs() #elf.dump_symbol_idx() + #elf.dump_st_entries() #elf.dump_objs() - ''' - so.close() - ch_so_to_exe("./test/test.so") - so = openSO_r("./test/test.so") - elf2 = ELF(so) - elf2.init(64) - elf.dump_header() - ''' - return 0; + + return elf.dump_objs() + #return 0; if __name__ == "__main__": main() diff --git a/bruiser/bruiser-extra.h b/bruiser/bruiser-extra.h index 40af99f..40e22f0 100644 --- a/bruiser/bruiser-extra.h +++ b/bruiser/bruiser-extra.h @@ -121,7 +121,8 @@ std::vector<std::string> LUA_FUNCS = "changedirectory", "yolo", "pwd()", - "objload", + "objload()", + "listObjects", "_G", "_VERSION", "assert", diff --git a/bruiser/bruiser.cpp b/bruiser/bruiser.cpp index dfd12f6..3197a5e 100644 --- a/bruiser/bruiser.cpp +++ b/bruiser/bruiser.cpp @@ -231,12 +231,11 @@ class PyExec { pArgs = nullptr; std::cout << BLUE << "calling python function..." << NORMAL << "\n"; pValue = PyObject_CallObject(pFunc, pArgs); - //std::cout << BLUE << "i made it here" << NORMAL << "\n"; //Py_DECREF(pArgs); if (pValue != nullptr) { std::cout << GREEN << "call finished successfully." << NORMAL << "\n"; printf("Result of call: %ld\n", PyLong_AsLong(pValue)); - Py_DECREF(pValue); + //Py_DECREF(pValue); } else { Py_DECREF(pFunc); Py_DECREF(pModule); @@ -262,18 +261,77 @@ class PyExec { return 0; } + int getAsCppStringVec(void) { + if (PyList_Check(pValue)) { + std::cout << GREEN << "got a python list\n" << NORMAL; + int list_length = PyList_Size(pValue); + std::cout << BLUE << "length of list: " << list_length << "\n" << NORMAL; + for (int i = 0; i < list_length; ++i) { + PyObject* pybytes = PyList_GetItem(pValue, i); + std::cout << CYAN << "bytes size: " << PyBytes_Size(pybytes) << "\n" << NORMAL; + PyObject* pyrepr = PyObject_Repr(pybytes); + PyObject* pyunicode = PyUnicode_AsEncodedString(pyrepr, "utf-8", "surrogateescape"); + const char* dummy = PyBytes_AsString(pyunicode); + std::cout << RED << dummy << "\n" << NORMAL; + hexobj_str.push_back(std::string(dummy)); + } + } + return 0; + } + + int getAsCppByte(void) { + std::vector<uint8_t> tempvec; + if(PyList_Check(pValue)) { + int list_length = PyList_Size(pValue); + for(int i = 0; i < list_length; ++i) { + PyObject* pybytes = PyList_GetItem(pValue, i); + if(PyList_Check(pybytes)) { + int list_length_2 = PyList_Size(pybytes); + for(int j = 0; j < list_length_2; ++j) { + PyObject* dummy_int = PyList_GetItem(pybytes, j); + if (PyLong_Check(dummy_int)) { + unsigned char byte = PyLong_AsLong(dummy_int); + tempvec.push_back(int(byte)); + } + } + hexobj.push_back(tempvec); + } + } + } + return 0; + } + + void killPyObj(void) { + Py_DECREF(pValue); + } + + void printHexObjs(void) { + for (auto &iter : hexobj) { + for (auto &iterer : iter) { + std::cout << RED << int(iterer) << " "; + } + std::cout << "\n" << NORMAL; + } + } + + std::vector<std::vector<uint8_t>> exportObjs(void) { + return hexobj; + } + private: std::string py_script_name; std::string py_func_name; std::string obj_path; - PyObject *pName; - PyObject *pModule; - PyObject *pDict; - PyObject *pFunc; - PyObject *pArgs; - PyObject *pValue; + PyObject* pName; + PyObject* pModule; + PyObject* pDict; + PyObject* pFunc; + PyObject* pArgs; + PyObject* pValue; int argc; char** argv; + std::vector<std::string> hexobj_str; + std::vector<std::vector<uint8_t>> hexobj; }; /**********************************************************************************************************************/ class CompilationDatabaseProcessor @@ -1154,6 +1212,10 @@ class LuaWrapper { std::cout << BLUE << "running load.py: " << NORMAL << "\n"; py.run(); + //py.getAsCppStringVec(); + py.getAsCppByte(); + py.printHexObjs(); + //py.killPyObj(); lua_pushnumber(__ls, 0); exit(EXIT_SUCCESS); } @@ -1596,6 +1658,11 @@ class LuaWrapper return 0; } + int BruiserLuaListObjects(lua_State* __ls) { + // @DEVI-has one string object to signify what kind of object to list + return 0; + } + int BruiserLuaPWD(lua_State* __ls) { pid_t pid = fork(); @@ -1756,6 +1823,7 @@ int main(int argc, const char **argv) lua_register(LE.GetLuaState(), "yolo", &LuaDispatch<&LuaWrapper::BruiserLuaYolo>); lua_register(LE.GetLuaState(), "pwd", &LuaDispatch<&LuaWrapper::BruiserLuaPWD>); lua_register(LE.GetLuaState(), "objload", &LuaDispatch<&LuaWrapper::BruiserPyLoader>); + lua_register(LE.GetLuaState(), "listObjects", &LuaDispatch<&LuaWrapper::BruiserLuaListObjects>); /*its just regisering the List function from LuaWrapper with X-macros.*/ #define X(__x1, __x2) lua_register(LE.GetLuaState(), #__x1, &LuaDispatch<&LuaWrapper::List##__x1>); @@ -1812,5 +1880,6 @@ int main(int argc, const char **argv) } //end of cli block } //end of main +/**********************************************************************************************************************/ /*last line intentionally left blank.*/ diff --git a/bruiser/bruiser.h b/bruiser/bruiser.h index e311c7e..3cd8eaa 100644 --- a/bruiser/bruiser.h +++ b/bruiser/bruiser.h @@ -144,7 +144,8 @@ help CMDHelp[] = { {"getsourcefiles()", "getsourcefiles()", "gets the currently loaded source files that bruiser will look through", "none", "array of strings"}, {"changedirectory()", "changedirectory()", "changes bruiser's working directory. only use it when you know what you are doing.", "destination directory, [string]", "return value"}, {"pwd()", "pwd()", "pwd", "", ""}, - {"objload()", "objload(\"main\", \"../bfd/test/test.so\")", "load the compiled functions into bruiser", "string", "success or failure"} + {"objload()", "objload(\"main\", \"../bfd/test/test.so\")", "load the compiled functions into bruiser", "string", "success or failure"}, + {"listObjects()", "listObjects(\"function\")", "lists the loaded objects of the given type", "string", "success or failure"} }; /**********************************************************************************************************************/ /** @@ -263,7 +264,6 @@ class SearchM0 if (!RootPointer->NoChildren()) { const XMLElement* XMLE [[maybe_unused]] = RootPointer->FirstChildElement(); - } } @@ -276,13 +276,126 @@ class Daemonize public: Daemonize (std::string __exe, std::string __opts) : Exe(__exe), Opts(__opts) {} - - private: std::string Exe; std::string Opts; }; /**********************************************************************************************************************/ +/*structs to hold load.py's return values*/ +/*@DEVI-at some point in the future i might revert to using libbfd or libelf.*/ + +/*elf*/ +#define ELF_EI_MAGIC = 0x000000000000ffff; +#define ELF_EI_CLASS = 0x00000000000f0000; +#define ELF_EI_DATA = 0x0000000000f00000; +#define ELF_EI_VERSION = 0x000000000f000000; +#define ELF_EI_OSABI = 0x00000000f0000000; +#define ELF_EI_ABIVERSION = 0x0000000f00000000; +#define ELF_EI_PAD = 0xfffffff000000000; + +// @DEVI-FIXME-using uint128 here +struct ELFHDR_64 { + public: + ELFHDR_64() = default; + ELFHDR_64(__uint128_t _ident, uint16_t _type, uint16_t _machine, + uint32_t _version, uint64_t _entry, uint64_t _phoff, uint64_t _shoff, + uint32_t _flags, uint16_t _ehsize, uint16_t _phentsize, + uint16_t _phnum, uint16_t _shentsize, uint16_t _shnum, uint16_t _shstrndx) { + e_ident = _ident; e_type = _type; e_machine = _machine; e_version = _version; + e_entry = _entry; e_phoff = _phoff; e_shoff = _shoff; e_flags = _flags; + e_ehsize = _ehsize; e_phentsize = _phentsize; e_phnum = _phnum; + e_shentsize = _shentsize; e_shnum = _shnum; e_shstrndx = _shstrndx; + } + __uint128_t e_ident; uint16_t e_type; uint16_t e_machine; uint32_t e_version; + uint64_t e_entry; uint64_t e_phoff; uint64_t e_shoff; uint32_t e_flags; + uint16_t e_ehsize; uint16_t e_phentsize; uint16_t e_phnum; uint16_t e_shentsize; + uint16_t e_shnum; uint16_t e_shstrndx; +}; + +// @DEVI-FIXME-using uint128 here +struct ELFHDR_32 { + public: + ELFHDR_32() = default; + ELFHDR_32(__uint128_t _ident, uint16_t _type, uint16_t _machine, uint32_t _version, + uint32_t _entry, uint32_t _phoff, uint32_t _shoff, uint32_t _flags, + uint16_t _ehsize, uint16_t _phentsize, uint16_t _phnum, uint16_t _shentsize, + uint16_t _shnum, uint16_t _shstrndx) { + e_ident = _ident; e_type = _type; e_machine = _machine; e_version = _version; + e_entry = _entry; e_phoff = _phoff; e_shoff = _shoff; e_flags = _flags; + e_ehsize = _ehsize; e_phentsize = _phentsize; e_phnum = _phnum; + e_shentsize = _shentsize; e_shnum = _shnum; e_shstrndx = _shstrndx; + } + + __uint128_t e_ident; uint16_t e_type; uint16_t e_machine; uint32_t e_version; + uint32_t e_entry; uint32_t e_phoff; uint32_t e_shoff; uint32_t e_flags; + uint16_t e_ehsize; uint16_t e_phentsize; uint16_t e_phnum; uint16_t e_shentsize; + uint16_t e_shnum; uint16_t e_shstrndx; +}; +/*program header*/ +struct PHDR_64 { + public: + PHDR_64() = default; + PHDR_64(uint32_t _type, uint32_t _flags, uint64_t _offset, uint64_t _vaddr, + uint64_t _paddr, uint64_t _filesz, uint64_t _memsz, uint64_t _align) { + p_type = _type; p_flags = _flags; p_offset = _offset; p_vaddr = _vaddr; + p_paddr = _paddr; p_filesz = _filesz; p_memsz = _memsz; p_align = _align; + } + + uint32_t p_type; uint32_t p_flags; uint64_t p_offset; uint64_t p_vaddr; + uint64_t p_paddr; uint64_t p_filesz; uint64_t p_memsz; uint64_t p_align; +}; +struct PHDR_32 { + public: + PHDR_32() = default; + PHDR_32(uint32_t _type, uint32_t _offset, uint32_t _vaddr, uint32_t _paddr, + uint32_t _filesz, uint32_t _memsz, uint32_t _flags, uint32_t _align) { + p_type = _type; p_flags = _flags; p_offset = _offset; p_vaddr = _vaddr; + p_paddr = _paddr; p_filesz = _filesz; p_memsz = _memsz; p_align = _align; + }; + + uint32_t p_type; + uint32_t p_offset; + uint32_t p_vaddr; + uint32_t p_paddr; + uint32_t p_filesz; + uint32_t p_memsz; + uint32_t p_flags; + uint32_t p_align; +}; +/*section header*/ +struct SHDR_64 { + public: + SHDR_64() = default; + SHDR_64(uint32_t _name, uint32_t _type, uint64_t _flags, uint64_t _addr, + uint64_t _offset, uint64_t _size, uint32_t _link, uint32_t _info, + uint64_t _addralign, uint64_t _entsize) { + sh_name = _name; sh_type = _type; sh_flags = _flags; sh_addr = _addr; + sh_offset = _offset; sh_size = _size; sh_link = _link; sh_info = _info; + sh_addralign = _addralign; sh_entsize = _entsize; + }; + + uint32_t sh_name; uint32_t sh_type; uint64_t sh_flags; uint64_t sh_addr; + uint64_t sh_offset; uint64_t sh_size; uint32_t sh_link; uint32_t sh_info; + uint64_t sh_addralign; uint64_t sh_entsize; +}; +struct SHDR_32 { + public: + SHDR_32() = default; + SHDR_32(uint32_t _name, uint32_t _type, uint32_t _flags, uint32_t _addr, + uint32_t _offset, uint32_t _size, uint32_t _link, uint32_t _info, + uint32_t _addralign, uint32_t _entsize) { + sh_name = _name; sh_type = _type; sh_flags = _flags; sh_addr = _addr; + sh_offset = _offset; sh_size = _size; sh_link = _link; sh_info = _info; + sh_addralign = _addralign; sh_entsize = _entsize; + }; + + uint32_t sh_name; uint32_t sh_type; uint32_t sh_flags; uint32_t sh_addr; + uint32_t sh_offset; uint32_t sh_size; uint32_t sh_link; uint32_t sh_info; + uint32_t sh_addralign; uint32_t sh_entsize; +}; +/*symbol table entry*/ +struct ST_Entry_64 {}; +struct ST_Entry_32 {}; /**********************************************************************************************************************/ } // end of namespace bruiser #endif diff --git a/bruiser/executioner.cpp b/bruiser/executioner.cpp new file mode 100644 index 0000000..5aad56b --- /dev/null +++ b/bruiser/executioner.cpp @@ -0,0 +1,47 @@ + +/***************************************************Project Mutator****************************************************/ +//-*-c++-*- +/*first line intentionally left blank.*/ +/*loads the objects into executable memory and registers them with lua.*/ +/*Copyright (C) 2017 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 2 +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.*/ +/**********************************************************************************************************************/ +#include <vector> +#include <cstdint> +#include "lua-5.3.4/src/lua.hpp" +/**********************************************************************************************************************/ +namespace { + constexpr int MEMORY_SIZE = 30000; + std::vector<uint8_t> memory(MEMORY_SIZE, 0); +} + +class Executioner { + public: + Executioner() {} + ~Executioner() {} + + void getObjs(std::vector<std::vector<uint8_t>> _objs) { + objs = _objs; + } + + void registerWithLua(lua_State* _lua_State) {} + + private: + std::vector<std::vector<uint8_t>> objs; +}; +/**********************************************************************************************************************/ +/*last line intentionally left blank.*/ + @@ -28,7 +28,7 @@ class ArgParser(object): parser = argparse.ArgumentParser() parser.add_argument("-help", action='store_true', help="display the driver's help", default=False) parser.add_argument("-f", "--file", type=str, help="run an action file") - parser.add_argument("-c", "--command", type=str, help="run a command") + parser.add_argument("-c", "--command", nargs="+", type=str, help="run a command") parser.add_argument("-v", "--version", action='store_true', help="display version info", default=False) parser.add_argument("-i", "--input", type=str, help="the input file(s)") parser.add_argument("-o", "--output", type=str, help="the output file(s)") @@ -41,6 +41,7 @@ class ArgParser(object): def run(self): if self.args.file is not None: self.parseActionFile(self.args.file) + self.runActionFile() if self.args.command is not None: self.runCommand(self.args.command) @@ -108,29 +109,29 @@ class ArgParser(object): pass def runCommand(self, command): - if command == "clean": + if command[0] == "clean": call(["make", "clean"]) - elif command == "build": - call(["make", "all"]) - elif command == "install": + elif command[0] == "make": + call(["make", self.args.command[1]]) + elif command[0] == "install": call(["make", "install"]) - elif command == "format": + elif command[0] == "format": pass - elif command == "test": + elif command[0] == "test": pass - elif command == "build-all": - call(["make", "build-all"]) - elif command == "m0": + elif command[0] == "buildall" or command[0] == "makeall": + call(["make"]) + elif command[0] == "m0": pass - elif command == "m1": + elif command[0] == "m1": pass - elif command == "m2": + elif command[0] == "m2": pass - elif command == "bruiser": + elif command[0] == "bruiser": pass - elif command == "obfuscator": + elif command[0] == "obfuscator": pass - elif command == "safercpp": + elif command[0] == "safercpp": pass else: raise Exception(Colors.red + "unknown command. for a list of valid commands run with -h." + Colors.ENDC); diff --git a/obfuscator/obfuscator.cpp b/obfuscator/obfuscator.cpp index f987fc8..a028955 100644 --- a/obfuscator/obfuscator.cpp +++ b/obfuscator/obfuscator.cpp @@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* /*code structure inspired by Eli Bendersky's tutorial on Rewriters.*/ /**********************************************************************************************************************/ /*FIXME-all classes should use replacements.*/ +//@DEVI-FIXME-will mess up macros /**********************************************************************************************************************/ /*included modules*/ /*project headers*/ |