diff options
-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 -------------------------------------------------------------------------------------------------------------- |