diff options
Diffstat (limited to '')
| -rwxr-xr-x | bfd/load.py | 61 | ||||
| -rw-r--r-- | bruiser/README.md | 18 | ||||
| -rw-r--r-- | bruiser/bruiser.cpp | 46 | ||||
| -rw-r--r-- | bruiser/defaults.lua | 2 | ||||
| -rw-r--r-- | bruiser/lua-scripts/demo2.lua | 35 | ||||
| -rw-r--r-- | bruiser/lua-scripts/xobj.lua | 34 | 
6 files changed, 159 insertions, 37 deletions
diff --git a/bfd/load.py b/bfd/load.py index aeaa67b..9178db6 100755 --- a/bfd/load.py +++ b/bfd/load.py @@ -741,7 +741,7 @@ class ELF(object):                  print(name)          return ret_list -    def dump_section(self, section_name): +    def dump_section(self, section_name, dump):          for section in self.shhdr:              name = self.read_section_name(byte2int(section.sh_name))              if name == section_name: @@ -749,27 +749,34 @@ class ELF(object):                  obj = self.so.read(byte2int(section.sh_size))                  if section_name == ".interp":  self.dlpath = repr(obj)                  count = int() -                strrep = [] -                for byte in obj: -                    if count%16 == 0: -                        for ch in strrep: -                            if ord(ch) > 16: print(ch, end = '') -                            else: pass -                        print() -                        strrep = [] -                        print(format(count, "06x"), ': ', end='') -                        strrep.append(str(chr(byte))) -                        print(format(byte, '02x') + ' ', end='') -                    else: -                        strrep += str(chr(byte)) -                        print(format(byte, '02x') + ' ', end='') -                    count += 1 -                for i in range(0, 16-count%16): print("   ", end="") -                for ch in strrep: -                    if ord(ch) > 16: print(ch, end = '') -                    else: pass -                print() -                return self.dlpath +                if dump: +                    strrep = [] +                    for byte in obj: +                        if count%16 == 0: +                            for ch in strrep: +                                if ord(ch) > 16 and ord(ch) < 127: print(ch, end = '') +                                else: pass +                            print() +                            strrep = [] +                            print(format(count, "06x"), ': ', end='') +                            strrep.append(str(chr(byte))) +                            print(format(byte, '02x') + ' ', end='') +                        else: +                            pass +                            strrep += str(chr(byte)) +                            print(format(byte, '02x') + ' ', end='') +                        count += 1 +                    for i in range(0, 16-count%16): print("   ", end="") +                    #for ch in strrep: +                        #if ord(ch) > 63 and ord(ch) < 100: print(repr(ch), end = '') +                        #else: pass +                    print() + +                ret_dummy = [] +                for i in range(0, len(obj)): +                    ret_dummy.append(obj[i]) +                #print(ret_dummy) +                return ret_dummy      def dump_obj_size(self, stt_type, dump_b):          ret_list = [] @@ -991,6 +998,12 @@ def elf_get_func_names():      elf.init(64)      return elf.dump_symbol_string(ELF_ST_TYPE.STT_FUNC, False) +def elf_get_text_section(): +    so = openSO_r(sys.argv[1]) +    elf = ELF(so) +    elf.init(64) +    return elf.dump_section(".text", False) +  # obj here means variables or what the C standard means by objects  def elf_get_obj_names():      so = openSO_r(sys.argv[1]) @@ -1050,8 +1063,8 @@ def main():          elif argparser.args.funcs: elf.dump_symbol_string(ELF_ST_TYPE.STT_FUNC, True)          elif argparser.args.objs: elf.dump_symbol_string(ELF_ST_TYPE.STT_OBJECT, True)          elif argparser.args.dynsym: elf.dump_st_entries_dyn() -        elif argparser.args.dlpath: elf.dump_section(".interp") -        elif argparser.args.section: elf.dump_section(argparser.args.section) +        elif argparser.args.dlpath: elf.dump_section(".interp", True) +        elif argparser.args.section: elf.dump_section(argparser.args.section, True)          elif argparser.args.test:              counter = 0              print(elf.dump_funcs(False)[10]) diff --git a/bruiser/README.md b/bruiser/README.md index da86ce5..72b44d8 100644 --- a/bruiser/README.md +++ b/bruiser/README.md @@ -77,3 +77,21 @@ Running the following command will return a table containing the names of the ob  ```lua  objload("elf_get_obj_names", "../bfd/test/test.so", "symbol_list")  ``` +For a more detailed example look at the wiki here on github.<br/> +The xobj functionality is provided as a lua module. You can use it by:<br/> +```lua +xobj = require("lua-scripts.xobj") +``` +you can see a working example if you run `lua-scripts/demo2.lua`. The example requires `ansicolors`. You can get that by `luarocks install ansicolors`.<br/> + +#### Lua Defaults +Upon start-up, bruiser will look to find a file called `defaults.lua` in the same directory as the bruiser executable to run before running any user provided lua code, both in interactive and non-interactive modes. The path to the lua default file could be changed from the default value by the `LuaDefault` option passed to bruiser on startup.<br/> +If you use `luarocks`, you can run `luarocks path --bin` to see where rocks on your machine are and then add that to your path to have the rocks available in bruiser as well.<br/> +One way do to that is to add the following lines to your `defaults.lua`:<br/> +```lua + +package.path = package.path .. ";LUA_PATH" +packege.cpath = package.cpath .. ";LUA_CPATH" + +``` +The following lines make the rocks in `LUA_PATH` and `LUA_CPATH` available on bruiser. You can get `LUA_PATH` and `LUA_CPATH` by runnin `luarocks path --bin`. You can also look at the `default.lua` that is shipped with bruiser.<br/> diff --git a/bruiser/bruiser.cpp b/bruiser/bruiser.cpp index 808010f..50c01cc 100644 --- a/bruiser/bruiser.cpp +++ b/bruiser/bruiser.cpp @@ -106,6 +106,7 @@ cl::opt<std::string> M0XMLPath("xmlpath", cl::desc("tells bruiser where to find  cl::opt<bool> LuaJIT("jit", cl::desc("should bruiser use luajit or not."), cl::init(true), cl::cat(BruiserCategory), cl::ZeroOrMore);  cl::opt<bool> Verbose("verbose", cl::desc("verbosity"), cl::init(false), cl::cat(BruiserCategory), cl::ZeroOrMore);  cl::opt<std::string> NonCLILuaScript("lua", cl::desc("specifies a lua script for bruiser to run in non-interactive mode"), cl::init(""), cl::cat(BruiserCategory), cl::Optional); +cl::opt<std::string> LuaDefault("luadefault", cl::desc("the path to the luadefault file. the default option is where the bruiser executable is."), cl::init("./defaults.lua"), cl::cat(BruiserCategory), cl::ZeroOrMore);  /**********************************************************************************************************************/  class LuaEngine  { @@ -139,6 +140,10 @@ class LuaEngine        luaL_openlibs(LS);      } +    void RunLuaDefaults(void) { +      luaL_dofile(LS, LuaDefault.c_str()); +    } +      void RunString(char* __lua_string) {}      void RunChunk(char* __lua_chunk) { @@ -247,6 +252,9 @@ class PyExec {      return 0;      } +    //std::vector<std::string> actionParser(std::string action) {} +    //void convertPush(PyObject* pyobject) {} +      int getAsCppStringVec(void) {        if (Verbose) PRINT_WITH_COLOR_LB(BLUE, "processing return result...");        if (PyList_Check(pValue)) { @@ -266,6 +274,19 @@ class PyExec {        return 0;      } +    int getAsCppByte_PyIntList(void) { +      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 (PyLong_Check(pybytes)) { +            text_section.push_back(PyLong_AsLong(pybytes)); +          } +        } +      } +      return 0; +    } +      int getAsCppByte(void) {        if (Verbose) PRINT_WITH_COLOR_LB(BLUE, "processing return result...");        std::vector<uint8_t> tempvec; @@ -308,6 +329,7 @@ class PyExec {      std::vector<std::vector<uint8_t>> exportObjs(void) {return hexobj;}      std::vector<std::string> exportStrings(void) {return hexobj_str;} +    std::vector<std::uint8_t> exportTextSection(void) {return text_section;}    private:      std::string py_script_name; @@ -323,6 +345,7 @@ class PyExec {      char** argv;      std::vector<std::string> hexobj_str;      std::vector<std::vector<uint8_t>> hexobj; +    std::vector<uint8_t> text_section;  };  /**********************************************************************************************************************/  class XObjReliquary {}; @@ -1165,8 +1188,11 @@ class LuaWrapper        if (numargs == 3) {          if (Verbose) std::cout << CYAN << "got args." << NORMAL << "\n";          funcname = lua_tostring(__ls, 1); +        if (funcname == "") PRINT_WITH_COLOR_LB(RED, "first argument is nil");          objjpath = lua_tostring(__ls, 2); +        if (objjpath == "") PRINT_WITH_COLOR_LB(RED, "second argument is nil");          action = lua_tostring(__ls, 3); +        if (action == "") PRINT_WITH_COLOR_LB(RED, "third argument is nil");          lua_pop(__ls, 3);        }        else { @@ -1203,8 +1229,7 @@ class LuaWrapper            tableindex1++;            lua_settable(__ls, -3);          } -      } -      else if (action == "symbol_list") { +      } else if (action == "symbol_list") {          py.getAsCppStringVec();          int tableindex = 1 ;          // the return type to lua is a table @@ -1218,6 +1243,20 @@ class LuaWrapper            lua_pushstring(__ls, iter.c_str());            lua_settable(__ls, -3);          } +      } else if (action == "bytes") { +        py.getAsCppByte_PyIntList(); +        int tableindex = 1 ; +        // the return type to lua is a table +        lua_newtable(__ls); +        if (!lua_checkstack(__ls, py.exportStrings().size())) { +          PRINT_WITH_COLOR_LB(RED, "cant grow lua stack. current size is too small."); +        } +        for (auto& iter : py.exportTextSection()) { +          lua_pushnumber(__ls, tableindex); +          tableindex++; +          lua_pushinteger(__ls, iter); +          lua_settable(__ls, -3); +        }        }        if (Verbose) PRINT_WITH_COLOR_LB(GREEN, "done."); @@ -1990,6 +2029,7 @@ int main(int argc, const char **argv) {      LuaEngine LE;      LE.LoadEverylib(); +    LE.RunLuaDefaults();      *static_cast<LuaWrapper**>(lua_getextraspace(LE.GetLuaState())) = &LW;      /*@DEVI-this part is just registering our LuaWrapper member functions with lua so we can call them from lua.*/ @@ -2043,6 +2083,7 @@ int main(int argc, const char **argv) {      while((command = linenoise(">>>")) != NULL) {        linenoiseHistoryAdd(command);        linenoiseHistorySave(SHELL_HISTORY_FILE); +#if 0        if (std::string(command).find("!", 0) == 0) {          std::string histnumber_str = std::string(command).substr(1, std::string::npos);          unsigned int history_num = std::stoi(histnumber_str, 0, 10); @@ -2051,6 +2092,7 @@ int main(int argc, const char **argv) {            continue;          } else {}        } +#endif        LE.RunChunk(command);        linenoiseFree(command);      } diff --git a/bruiser/defaults.lua b/bruiser/defaults.lua new file mode 100644 index 0000000..8dd09df --- /dev/null +++ b/bruiser/defaults.lua @@ -0,0 +1,2 @@ +package.path = package.path .. ";/home/bloodstalker/.luarocks/share/lua/5.3/?.lua;/home/bloodstalker/.luarocks/share/lua/5.3/?/init.lua;/usr/share/lua/5.3/?.lua;/usr/share/lua/5.3/?/init.lua;/usr/lib64/lua/5.3/?.lua;/usr/lib64/lua/5.3/?/init.lua;./?.lua;./?/init.lua" +package.cpath = package.cpath .. ";/home/bloodstalker/.luarocks/lib64/lua/5.3/?.so;/usr/lib64/lua/5.3/?.so;/usr/lib64/lua/5.3/loadall.so;./?.so" diff --git a/bruiser/lua-scripts/demo2.lua b/bruiser/lua-scripts/demo2.lua new file mode 100644 index 0000000..3b6007a --- /dev/null +++ b/bruiser/lua-scripts/demo2.lua @@ -0,0 +1,35 @@ + +xobj = require("lua-scripts.xobj") +colors = require("ansicolors") +elf_file = "../bfd/test/test.so" +elf_exe = "../bfd/test/test" + +function main() +  xobj.getSO(elf_file) +  local add2_code = xobj.codeTableByName_number("'add2'") +  local sub2_code = xobj.codeTableByName_number("'sub2'") +  local adddouble_code = xobj.codeTableByName_number("'adddouble'") +  local subdouble_code = xobj.codeTableByName_number("'subdouble'") +  local triple_code = xobj.codeTableByName_number("'triple'") +  local quad_code = xobj.codeTableByName_number("'quad'") +  local passthrough_code = xobj.codeTableByName_number("'passthrough'") + +  --xobj.printFuncSizes() + +  xobjregister(add2_code, "add2") +  xobjregister(sub2_code, "sub2") +  xobjregister(adddouble_code, "adddouble") +  xobjregister(subdouble_code, "subdouble") +  xobjregister(triple_code, "triple") +  xobjregister(quad_code, "quad") +  xobjregister(passthrough_code, "passthrough") +end + +function asm_rewriter() +  local text_section = xobj.getTextSection() +  for k,v in pairs(text_section) do io.write(colors("%{blue}"..string.format("%02x",k)),":",colors("%{green}"..string.format("%02x",v)),"\t") end +  io.write("\n") +end + +--main() +asm_rewriter() diff --git a/bruiser/lua-scripts/xobj.lua b/bruiser/lua-scripts/xobj.lua index b69f0e5..880730a 100644 --- a/bruiser/lua-scripts/xobj.lua +++ b/bruiser/lua-scripts/xobj.lua @@ -1,4 +1,5 @@  ------------------------------------------------Project Mutator----------------------------------------------- +--bruiser's xobj module  --Copyright (C) 2018 Farzad Sadeghi  --This program is free software; you can redistribute it and/or @@ -15,11 +16,15 @@  --along with this program; if not, write to the Free Software  --Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.*/  -------------------------------------------------------------------------------------------------------------- -function getSO(so_path) +--start of xobj module +local xobj = {} + +local elf_file = "" +function xobj.getSO(so_path)    elf_file = so_path  end -function getGlobalTable() +function xobj.getGlobalTable()    local return_table = {}    local names = objload("elf_get_obj_names", elf_file, "symbol_list")    local sizes = objload("elf_get_obj_sizes", elf_file, "symbol_list") @@ -29,28 +34,28 @@ function getGlobalTable()    return return_table  end -function printObjNames() +function xobj.printObjNames()    local c = objload("elf_get_obj_names", elf_file, "symbol_list")    for k,v in ipairs(c) do      print(k,v)    end  end -function printObjSizes() +function xobj.printObjSizes()    local c = objload("elf_get_obj_sizes", elf_file, "symbol_list")    for k,v in ipairs(c) do      print(k,v)    end  end -function printFuncNames() +function xobj.printFuncNames()    local c = objload("elf_get_func_names", elf_file, "symbol_list")    for k,v in ipairs(c) do      print(k,v)    end  end -function printFuncCode() +function xobj.printFuncCode()    local c = objload("elf_get_func_code", elf_file, "code_list")    for k,v in ipairs(c) do      print(k,v) @@ -63,7 +68,7 @@ function printFuncCode()    end  end -function findMain() +function xobj.findMain()    local c = objload("elf_get_func_names", elf_file, "symbol_list")    for k,v in ipairs(c) do      if v == "'main'" then  @@ -73,7 +78,7 @@ function findMain()    end  end -function codeTables() +function xobj.codeTables()    local return_table = {}    local func_name_table = objload("elf_get_func_names", elf_file, "symbol_list")    local code_table = objload("elf_get_func_code", elf_file, "code_list") @@ -83,7 +88,7 @@ function codeTables()    return return_table  end -function codeTableByName(name) +function xobj.codeTableByName(name)    local return_table = {}    local func_name_table = objload("elf_get_func_names", elf_file, "symbol_list")    local code_table = objload("elf_get_func_code", elf_file, "code_list") @@ -98,7 +103,7 @@ function codeTableByName(name)    return nil  end -function codeTableByName_number(name) +function xobj.codeTableByName_number(name)    local return_table = {}    local func_name_table = objload("elf_get_func_names", elf_file, "symbol_list")    local code_table = objload("elf_get_func_code", elf_file, "code_list") @@ -113,7 +118,7 @@ function codeTableByName_number(name)    return nil  end -function printFuncSizes() +function xobj.printFuncSizes()    local func_name_table = objload("elf_get_func_names", elf_file, "symbol_list")    local code_table = objload("elf_get_func_code", elf_file, "code_list")    local counter = 1 @@ -123,5 +128,12 @@ function printFuncSizes()      counter = counter + 1    end  end + +function xobj.getTextSection() +  return objload("elf_get_text_section", elf_exe, "bytes") +end + +--end of xobj module +return xobj  --------------------------------------------------------------------------------------------------------------  | 
