From 05b8359e3f798d54c67d095ae30b9e51fb07c3f0 Mon Sep 17 00:00:00 2001 From: bloodstalker Date: Wed, 6 Dec 2017 10:14:43 +0330 Subject: obfuscator doesnt mess up var declations with init values, python driver has been updated, not finished yet, bruiser now gets the objects from load.py, executioner will handle running the objects and registering them with lua --- bfd/load.py | 332 ++++++++++++++++++++++++++++++---------------- bruiser/bruiser-extra.h | 3 +- bruiser/bruiser.cpp | 85 ++++++++++-- bruiser/bruiser.h | 121 ++++++++++++++++- bruiser/executioner.cpp | 47 +++++++ mutator.py | 31 ++--- obfuscator/obfuscator.cpp | 1 + 7 files changed, 476 insertions(+), 144 deletions(-) create mode 100644 bruiser/executioner.cpp 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 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 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> 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 hexobj_str; + std::vector> 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 +#include +#include "lua-5.3.4/src/lua.hpp" +/**********************************************************************************************************************/ +namespace { + constexpr int MEMORY_SIZE = 30000; + std::vector memory(MEMORY_SIZE, 0); +} + +class Executioner { + public: + Executioner() {} + ~Executioner() {} + + void getObjs(std::vector> _objs) { + objs = _objs; + } + + void registerWithLua(lua_State* _lua_State) {} + + private: + std::vector> objs; +}; +/**********************************************************************************************************************/ +/*last line intentionally left blank.*/ + diff --git a/mutator.py b/mutator.py index 376140c..aa9c0aa 100755 --- a/mutator.py +++ b/mutator.py @@ -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*/ -- cgit v1.2.3