diff options
| -rwxr-xr-x | bfd/load.py | 126 | ||||
| -rw-r--r-- | bfd/test/makefile | 5 | ||||
| -rw-r--r-- | bruiser/bruiser.cpp | 17 | ||||
| -rw-r--r-- | bruiser/bruisercapstone.c | 2 | ||||
| -rw-r--r-- | bruiser/lua-scripts/asmrw.lua | 2 | ||||
| -rw-r--r-- | bruiser/lua-scripts/df-demo.lua | 46 | ||||
| -rw-r--r-- | bruiser/makefile | 2 | ||||
| -rwxr-xr-x | bruiser/run.sh | 2 | 
8 files changed, 186 insertions, 16 deletions
| diff --git a/bfd/load.py b/bfd/load.py index cb53722..4e85ca7 100755 --- a/bfd/load.py +++ b/bfd/load.py @@ -63,13 +63,14 @@ class CLIArgParser(object):          parser.add_argument("--dumpfuncasm", type=str, help="dump a functions assembly code")          parser.add_argument("--textasm", action='store_true', help="disassemble the text section", default=False)          parser.add_argument("--dynsecents", action='store_true', help="dynamic section entries", default=False) -        parser.add_argument("--reladynents", action='store_true', help=".rela.dyn entries", default=False) +        parser.add_argument("--reladyn", action='store_true', help=".rela.dyn entries", default=False) +        parser.add_argument("--relaplt", action='store_true', help=".rela.plt entries", default=False)          self.args = parser.parse_args()          if self.args.obj is None:              raise Exception("no object file provided. please specify an object with --obj.") -def byte2int(value): -    return int.from_bytes(value, byteorder="little", signed=False) +def byte2int(value,sign = False): +    return int.from_bytes(value, byteorder="little", signed=sign)  def byte2hex(value):      return hex(int.from_bytes(value, byteorder="little", signed=False)) @@ -475,14 +476,34 @@ class X86_REL_TYPE:      R_386_PC8 = 15      R_386_SIZE32 = 16 +def get_x86_rel_type(val): +    if val == X86_REL_TYPE.R_386_NONE: return "R_386_NONE" +    elif val == X86_REL_TYPE.R_386_32: return "R_386_32" +    elif val == X86_REL_TYPE.R_386_PC32: return "R_386_PC32" +    elif val == X86_REL_TYPE.R_386_GOT32: return "R_386_GOT32" +    elif val == X86_REL_TYPE.R_386_PLT32: return "R_386_PLT32" +    elif val == X86_REL_TYPE.R_386_COPY: return "R_386_COPY" +    elif val == X86_REL_TYPE.R_386_GLOB_DAT: return "R_386_GLOB_DAT" +    elif val == X86_REL_TYPE.R_386_JMP_SLOT: return "R_386_JMP_SLOT" +    elif val == X86_REL_TYPE.R_386_RELATIVE: return "R_386_RELATIVE" +    elif val == X86_REL_TYPE.R_386_GOTOFF: return "R_386_GOTOFF" +    elif val == X86_REL_TYPE.R_386_GOTPC: return "R_386_GOTPC" +    elif val == X86_REL_TYPE.R_386_32PLT: return "R_386_32PLT" +    elif val == X86_REL_TYPE.R_386_16: return "R_386_16" +    elif val == X86_REL_TYPE.R_386_PC16: return "R_386_PC16" +    elif val == X86_REL_TYPE.R_386_8: return "R_386_8" +    elif val == X86_REL_TYPE.R_386_PC8: return "R_386_PC8" +    elif val == X86_REL_TYPE.R_386_SIZE32: return "R_386_SIZE32" +    else: return "UNKNOWN" +  class X86_64_REL_TYPE:      R_AMD64_NONE = 0      R_AMD64_64 = 1      R_AMD64_PC32 = 2 -    R_AMD6_GOT32 = 3 +    R_AMD64_GOT32 = 3      R_AMD64_PLT32 = 4      R_AMD64_COPY = 5 -    R_AMD64_GLOV_DAT = 6 +    R_AMD64_GLOB_DAT = 6      R_AMD64_JUMP_SLOT = 7      R_AMD64_RELATIVE = 8      R_AMD64_GOTPCREL = 9 @@ -498,6 +519,30 @@ class X86_64_REL_TYPE:      R_AMD64_SIZE32 = 32      R_AMD64_SIZE64 = 33 +def get_x86_64_rel_type(val): +    if val == X86_64_REL_TYPE.R_AMD64_NONE: return "R_386_NONE" +    elif val == X86_64_REL_TYPE.R_AMD64_64: return "R_AMD64_64" +    elif val == X86_64_REL_TYPE.R_AMD64_PC32: return "R_AMD64_PC32" +    elif val == X86_64_REL_TYPE.R_AMD64_GOT32: return "R_AMD64_GOT32" +    elif val == X86_64_REL_TYPE.R_AMD64_PLT32: return "R_AMD64_PLT32" +    elif val == X86_64_REL_TYPE.R_AMD64_COPY: return "R_AMD64_COPY" +    elif val == X86_64_REL_TYPE.R_AMD64_GLOB_DAT: return "R_AMD64_GLOB_DAT" +    elif val == X86_64_REL_TYPE.R_AMD64_JUMP_SLOT: return "R_AMD64_JUMP_SLOT" +    elif val == X86_64_REL_TYPE.R_AMD64_RELATIVE: return "R_AMD64_RELATIVE" +    elif val == X86_64_REL_TYPE.R_AMD64_GOTPCREL: return "R_AMD64_GOTPCREL" +    elif val == X86_64_REL_TYPE.R_AMD64_32: return "R_AMD64_32" +    elif val == X86_64_REL_TYPE.R_AMD64_32S: return "R_AMD64_32S" +    elif val == X86_64_REL_TYPE.R_AMD64_16: return "R_AMD64_16" +    elif val == X86_64_REL_TYPE.R_AMD64_PC16: return "R_AMD64_PC16" +    elif val == X86_64_REL_TYPE.R_AMD64_8: return "R_AMD64_8" +    elif val == X86_64_REL_TYPE.R_AMD64_PC8: return "R_AMD64_PC8" +    elif val == X86_64_REL_TYPE.R_AMD64_PC64: return "R_AMD64_PC64" +    elif val == X86_64_REL_TYPE.R_AMD64_GOTOFF64: return "R_AMD64_GOTOFF64" +    elif val == X86_64_REL_TYPE.R_AMD64_GOTPC32: return "R_AMD64_GOTPC32" +    elif val == X86_64_REL_TYPE.R_AMD64_SIZE32: return "R_AMD64_SIZE32" +    elif val == X86_64_REL_TYPE.R_AMD64_SIZE64: return "R_AMD64_SIZE64" +    else: return "UNKNOWN" +  class ELF_ST_BIND:      STB_LOCAL = 0      STB_GLOBAL = 1 @@ -669,6 +714,8 @@ class ELF(object):          self.dyn_section_ents = []          self.rela_dyn = []          self.rela_dyn_ents = [] +        self.rela_plt = [] +        self.rela_plt_ents = []      def init(self, size):          self.size = size @@ -703,7 +750,9 @@ class ELF(object):          self.pop_text_section()          self.get_ph_dyn_entries()          self.pop_dynamic_entries(".dynamic", self.dyn_section_ents) -        self.pop_dynamic_entries(".rela.dyn", self.rela_dyn_ents) +        self.pop_rela(".rela.plt", self.rela_plt, self.rela_plt_ents) +        self.pop_rela(".rela.dyn", self.rela_dyn, self.rela_dyn_ents) +        #self.pop_rel()      def read_ELF_H(self, size):          self.elfhdr.ei_mag = self.so.read(4) @@ -1027,14 +1076,30 @@ class ELF(object):              print(line)      def dump_dyn_sec_ents(self, who): -        header = ["type_string", "tag", "value"] +        header = ["type_string", "tag", "value", "value(hex)"]          tag_string_list = [entry["type_string"] for entry in who]          tag_list = [entry["tag"] for entry in who]          value_list = [entry["value"] for entry in who] -        lines = ffs(2, header, True, tag_string_list, tag_list, value_list) +        value_list_hex = [hex(entry["value"]) for entry in who] +        lines = ffs(2, header, True, tag_string_list, tag_list, value_list, value_list_hex)          for line in lines:              print(line) +    def dump_rela(self, to_dump): +        header = ["r_offset", "r_info", "r_addend"] +        r_offset_list = [entry["r_offset"] for entry in to_dump] +        r_info_list = [entry["r_info"] for entry in to_dump] +        addend_list = [entry["r_addend"] for entry in to_dump] +        lines = ffs(2, header, True, r_offset_list, r_info_list, addend_list) +        for line in lines: print(line) + +    def dump_rel(self, to_dump): +        header = ["r_offset", "r_info"] +        r_offset_list = [entry["r_offset"] for entry in to_dump] +        r_info_list = [entry["r_info"] for entry in to_dump] +        lines = ffs(2, header, True, r_offset_list, r_info_list) +        for line in lines: print(line) +      def get_st_entry_symbol_string(self, index, section_name):          symbol = []          for i in range(0, byte2int(self.elfhdr.e_shnum)): @@ -1105,6 +1170,48 @@ class ELF(object):              struct_to_pop.append(dummy)              dummy = {} +    def pop_rela(self, section_name, section_whole, to_pop): +        size = int() +        entsize = int() +        dummy = {} +        step = int() +        if self.size == 64: step = 8 +        if self.size == 32: step = 4 +        for section in self.shhdr: +            name = self.read_section_name(byte2int(section.sh_name)) +            if name == section_name: +                self.so.seek(byte2int(section.sh_offset)) +                section_whole = self.so.read(byte2int(section.sh_size)) +                size = byte2int(section.sh_size) +                entsize = byte2int(section.sh_entsize) +        for i in range(0, int(size/entsize)): +            dummy["r_offset"] = byte2int(section_whole[i*entsize:i*entsize+step]) +            dummy["r_info"] = byte2int(section_whole[i*entsize+step:i*entsize+(step*2)]) +            dummy["r_addend"] = byte2int(section_whole[i*entsize+(step*2):i*entsize+(step*3)], sign=True) +            to_pop.append(dummy) +            dummy = {} + +    def pop_rel(self, section_name, section_whole, to_pop): +        size = int() +        entsize = int() +        dummy = {} +        step = int() +        if self.size == 64: step = 8 +        if self.size == 32: step = 4 +        for section in self.shhdr: +            name = self.read_section_name(byte2int(section.sh_name)) +            if name == section_name: +                self.so.seek(byte2int(section.sh_offset)) +                section_whole = self.so.read(byte2int(section.sh_size)) +                size = byte2int(section.sh_size) +                entsize = byte2int(section.sh_entsize) +        for i in range(0, int(size/entsize)): +            dummy["r_offset"] = byte2int(section_whole[i*entsize:i*entsize+step]) +            dummy["r_info"] = byte2int(section_whole[i*entsize+step:i*entsize+(step*2)]) +            to_pop.append(dummy) +            dummy = {} + +  class obj_loader():      def __init__(self, bytes):          self.memory = bytes() @@ -1266,7 +1373,8 @@ def premain(argparser):          for i in md.disasm(bytes(elf.text_section), 0x0):              print(hex(i.address).ljust(7), i.mnemonic.ljust(7), i.op_str)      elif argparser.args.dynsecents: elf.dump_dyn_sec_ents(elf.dyn_section_ents) -    elif argparser.args.reladynents: elf.dump_dyn_sec_ents(elf.rela_dyn_ents) +    elif argparser.args.reladyn: elf.dump_rela(elf.rela_dyn_ents) +    elif argparser.args.relaplt: elf.dump_rela(elf.rela_plt_ents)      else: print("why even bother if you were not gonna type anythng decent in?")  def main(): diff --git a/bfd/test/makefile b/bfd/test/makefile index 3512579..eb8576f 100644 --- a/bfd/test/makefile +++ b/bfd/test/makefile @@ -1,7 +1,8 @@  ##################################VARS################################# -CC=clang -CC_FLAGS=-fpic -O0 +CC?=gcc +CC=gcc +CC_FLAGS=-fpic -O0 -g -v --debug  LD_FLAGS= -l bfd  TARGET=test  ##################################RULES################################ diff --git a/bruiser/bruiser.cpp b/bruiser/bruiser.cpp index 82cd632..cdb4ef4 100644 --- a/bruiser/bruiser.cpp +++ b/bruiser/bruiser.cpp @@ -166,7 +166,10 @@ template <typename T>  std::vector<T> getLuaTableInt(lua_State* __ls, int numargs, int argnum) {    std::vector<T> ret;    int table_length = lua_rawlen(__ls, argnum); -  lua_checkstack(__ls, table_length); +  if (!lua_checkstack(__ls, table_length)) { +    std::cout << RED << "need to grow lua stack by " << table_length << ":"; +    PRINT_WITH_COLOR_LB(RED, "cant grow lua stack by that much."); +  }    for (int i = 1; i <= table_length; ++i) {      lua_rawgeti(__ls, argnum, i);      ret.push_back(lua_tointeger(__ls, i + numargs)); @@ -177,7 +180,10 @@ std::vector<T> getLuaTableInt(lua_State* __ls, int numargs, int argnum) {  std::vector<std::string> getLuaTableString(lua_State* __ls, int numargs, int argnum) {    std::vector<std::string> ret;    int table_length = lua_rawlen(__ls, argnum); -  lua_checkstack(__ls, table_length); +  if (!lua_checkstack(__ls, table_length)) { +    std::cout << RED << "need to grow lua stack by " << table_length << ":"; +    PRINT_WITH_COLOR_LB(RED, "cant grow lua stack by that much."); +  }    for (int i = 1; i <= table_length; ++i) {      lua_rawgeti(__ls, argnum, i);      ret.push_back(lua_tostring(__ls, i + numargs)); @@ -189,7 +195,10 @@ template <typename T>  std::vector<T> getLuaTableNumber(lua_State* __ls, int numargs, int argnum) {    std::vector<T> ret;    int table_length = lua_rawlen(__ls, argnum); -  lua_checkstack(__ls, table_length); +  if (!lua_checkstack(__ls, table_length)) { +    std::cout << RED << "need to grow lua stack by " << table_length << ":"; +    PRINT_WITH_COLOR_LB(RED, "cant grow lua stack by that much."); +  }    for (int i = 1; i <= table_length; ++i) {      lua_rawgeti(__ls, argnum, i);      ret.push_back(lua_tonumber(__ls, i + numargs)); @@ -1605,7 +1614,9 @@ class LuaWrapper        if (numargs != 2) {PRINT_WITH_COLOR_LB(RED, "expected exactly two args. did not get that.");return 0;}        uint64_t size = lua_tointeger(__ls, 1);        std::vector<uint8_t> code_v = getLuaTableInt<uint8_t>(__ls, 2, 2); +      if (Verbose) PRINT_WITH_COLOR_LB(BLUE, "making jump table...");        auto head = makejmptable(size, code_v.data(), Verbose, __ls); +      if (Verbose) PRINT_WITH_COLOR_LB(GREEN, "finished makejmptable call.");        jmpt_push_args(__ls, head);        new_jmpt_2(__ls);        return 1; diff --git a/bruiser/bruisercapstone.c b/bruiser/bruisercapstone.c index 8edc7ad..abb21aa 100644 --- a/bruiser/bruisercapstone.c +++ b/bruiser/bruisercapstone.c @@ -234,7 +234,9 @@ JMP_S_T* makejmptable(size_t size, uint8_t* obj, bool Verbose, lua_State* __ls)    if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) return NULL;  #pragma GCC diagnostic push  #pragma GCC diagnostic ignored "-Wpointer-sign" +  printf("starting to disassemble...\n");    count = cs_disasm(handle, obj, size, 0x0, 0, &insn); +  printf("finished disassembling.\n");  #pragma GCC diagnostic pop    if (Verbose) printf("number of instructions: %zu.\n\n", count);    cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); diff --git a/bruiser/lua-scripts/asmrw.lua b/bruiser/lua-scripts/asmrw.lua index 2f68d2b..68603fa 100644 --- a/bruiser/lua-scripts/asmrw.lua +++ b/bruiser/lua-scripts/asmrw.lua @@ -19,6 +19,8 @@  --start of asmrewriter module  local asmrw = {}  xobj = require("lua-scripts.xobj") +-- this will hold a copy of the original text section +local text_buffer = {}  setmetatable(jmp_s_t, {__call =       function(self, arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12) diff --git a/bruiser/lua-scripts/df-demo.lua b/bruiser/lua-scripts/df-demo.lua new file mode 100644 index 0000000..35a6b7a --- /dev/null +++ b/bruiser/lua-scripts/df-demo.lua @@ -0,0 +1,46 @@ + +xobj = require("lua-scripts.xobj") +asmrw = require("lua-scripts.asmrw") +colors = require("ansicolors") + +df_exe = "/home/bloodstalker/df/df_44_09_linux/df_linux/libs/Dwarf_Fortress" + +function main() +  local text_section = xobj.getTextSection(df_exe) +end + +function pretty_dump() +  count = 0 +  local text_section = xobj.getTextSection(df_exe) +  io.write(colors("%{blue}".."    ".."\t".."00 ".."01 ".."02 ".."03 ".."04 ".."05 ".."06 ".."07 ".."08 ".."09 ".."0A ".."0B ".."0C ".."0D ".."0E ".."0F")) +  for k,v in pairs(text_section) do +    if count % 16 == 0 then +      print() +      io.write(colors("%{blue}".."0x"..string.format("%03x",count)), "\t") +    end +    io.write(colors("%{green}"..string.format("%02x", v)), " ") +    count = count + 1 +  end +  count = 0 +  print() +end + +function jmp_table_test() +  local text_section = xobj.getTextSection(df_exe) +  local head = jmp_s_t() +  -- messes up the stack. I could fix it but not sure why i would want to keep this in +  --local head2 = jmp_s_t:new() +  io.write("lua:calling getjmptable\n") +  head = getjmptable(#text_section, text_section) + +  while head:inext() ~= nil do +    head:dump("entry") +    io.write("type:", head:type(), "\tlocation:", "0x"..string.format("%x", head:location())) +    print() +    head = head:inext() +  end +end + +--main() +--pretty_dump() +jmp_table_test() diff --git a/bruiser/makefile b/bruiser/makefile index 31a6892..60c90c6 100644 --- a/bruiser/makefile +++ b/bruiser/makefile @@ -71,5 +71,5 @@ help:  	@echo 'there is help.'  	@echo 'all is the defualt target.'  	@echo 'clean runs clean.' -	@echo 'deepclean will also clean the lua build' +	@echo 'deepclean will also clean lua and luajit'  	@echo 'for a more complete and detaild list of BUILD_MODE and other things look at the main makefiles help under project root.' diff --git a/bruiser/run.sh b/bruiser/run.sh index 226271b..955fc70 100755 --- a/bruiser/run.sh +++ b/bruiser/run.sh @@ -1,4 +1,4 @@  #!/bin/bash  cd $(dirname $0) -"./bruiser"  ../test/bruisertest/test.cpp +"./bruiser"  ../test/bruisertest/test.cpp --verbose | 
