diff options
Diffstat (limited to '')
-rw-r--r-- | bruiser/README.md | 3 | ||||
-rw-r--r-- | bruiser/asmrewriter.c | 149 | ||||
-rw-r--r-- | bruiser/asmrewriter.h | 89 | ||||
-rw-r--r-- | bruiser/bruiser-extra.h | 3 | ||||
-rw-r--r-- | bruiser/bruiser.cpp | 175 | ||||
-rw-r--r-- | bruiser/bruiser.h | 5 | ||||
-rw-r--r-- | bruiser/bruisercapstone.c | 188 | ||||
-rw-r--r-- | bruiser/bruisercapstone.h | 31 | ||||
-rw-r--r-- | bruiser/bruiserffi.c | 3 | ||||
-rw-r--r-- | bruiser/lua-scripts/demo2.lua | 30 | ||||
-rw-r--r-- | bruiser/lua-scripts/xobj.lua | 8 | ||||
-rw-r--r-- | bruiser/makefile | 4 |
12 files changed, 672 insertions, 16 deletions
diff --git a/bruiser/README.md b/bruiser/README.md index 72b44d8..29c66c5 100644 --- a/bruiser/README.md +++ b/bruiser/README.md @@ -94,4 +94,5 @@ 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/> +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 `defaults.lua` that is shipped with bruiser.<br/> +Also since there is a cli option that tells bruiser which lua script to load before handing control over to user code, you can have more than one such script to suit your needs.<br/> diff --git a/bruiser/asmrewriter.c b/bruiser/asmrewriter.c new file mode 100644 index 0000000..2bfdcf1 --- /dev/null +++ b/bruiser/asmrewriter.c @@ -0,0 +1,149 @@ + + +/***************************************************Project Mutator****************************************************/ +/*first line intentionally left blank.*/ +/*bruiser's lua asmrewriter implementation for jump tables*/ +/*Copyright (C) 2018 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 "./lua-5.3.4/src/lua.hpp" +#include "./bruisercapstone.h" +#include "./asmrewriter.h" + +#include <inttypes.h> +/**********************************************************************************************************************/ +static JMP_S_T* convert_jmpt(lua_State* __ls, int index) { + JMP_S_T* dummy = (JMP_S_T*)lua_touserdata(__ls, index); + if (dummy == NULL) luaL_typerror(__ls, index, dummy); + return dummy; +} + +static JMP_S_T* check_jmpt(lua_State* __ls, int index) { + JMP_S_T* dummy; + luaL_checktype(__ls, index, LUA_TUSERDATA); + dummy = (JMP_S_T*)luaL_checkudata(__ls, index, JMP_S_T); + if (dummy == NULL) luaL_typerror(__ls, index, dummy); + return dummy; +} + +static JMP_S_T* push_jmpt(lua_State* __ls) { + JMP_S_T* dummy = (JMP_S_T*)lua_newuserdata(__ls, sizeof(JMP_S_T)); + luaL_getmetatable(__ls, JMP_S_T); + lua_setmetatable(__ls, -2); + return dummy; +} + +static int new_jmpt(lua_State* __ls) { + JMP_T jmp_t = luaL_optint(__ls, 1, 0); + uint64_t location = luaL_optint(__ls, 2, 0); + uint8_t size = luaL_optint(__ls, 3, 0); + // + // + // + uint64_t address = luaL_optint(__ls, 7, 0); + uint64_t address_y = luaL_optint(__ls, 8, 0); + uint64_t address_n = luaL_optint(__ls, 9, 0); + unsigned char y = luaL_optint(__ls, 10, 0); + unsigned char n = luaL_optint(__ls, 11, 0); + unsigned char z = luaL_optint(__ls, 12, 0); + JMP_S_T* dummy = push_jmpt(__ls); + dummy->type = jmp_t; + dummy->location = location; + dummy->size = size; + //dummy->next =; + //dummy->next_y =; + //dummy->next_n =; + dummy->address = address; + dummy->address_y = address_y; + dummy->address_n = address_n; + dummy->y = y; + dummy->n = n; + dummy->z = z; + return 1; +} + +static int jmpt_custom(lua_State* __ls) { + JMP_S_T* dummy = check_jmpt(__ls, 1); + printf("this is the jump table custom function.\n"); + lua_pushnumber(__ls, dummy->type); + lua_pushnumber(__ls, dummy->location); + lua_pushnumber(__ls, dummy->size); + lua_pushlightuserdata(__ls, dummy->next); + lua_pushlightuserdata(__ls, dummy->next_y); + lua_pushlightuserdata(__ls, dummy->next_n); + lua_pushnumber(__ls, dummy->address); + lua_pushnumber(__ls, dummy->address_y); + lua_pushnumber(__ls, dummy->address_n); + lua_pushnumber(__ls, dummy->y); + lua_pushnumber(__ls, dummy->n); + lua_pushnumber(__ls, dummy->z); + return 12; +} + +#define SET_GENERATOR(X) \ + static int jmpt_set_##X(lua_State* __ls) {\ + JMP_S_T* dummy = check_jmpt(__ls,1);\ + dummy->type = luaL_checkint(__ls, 2);\ + lua_settop(__ls, 1);\ + return 1;\ +} + +#define X_LIST_GEN \ + X(type, "setter method for type")\ + X(location, "setter method for location")\ + X(size, "setter method for size")\ + X(address, "setter method for address")\ + X(address_y, "setter method for address_y")\ + X(address_n, "setter method for address_n")\ + X(y, "setter method for y")\ + X(n, "setter method for n")\ + X(z, "setter method for z") + +#define X(X1,X2) SET_GENERATOR(X1) +X_LIST_GEN +#undef X +#undef X_LIST_GEN +#undef SET_GENERATOR + +static int jmpt_set_next(lua_State* __ls) {} +static int jmpt_set_next_y(lua_State* __ls) {} +static int jmpt_set_next_n(lua_State* __ls) {} + +static int jmpt_gc(lua_State* __ls) {} + +int jmpt_register(lua_State* __ls) { + luaL_openlib(__ls, JMP_S_T, jmpt_methods, 0); + luaL_newmetatable(__ls, JMP_S_T); + luaL_openlib(__ls, 0, jmpt_meta, 0); + lua_pushliteral(__ls, "__index"); + lua_pushvalue(__ls, -3); + lua_rawset(__ls, -3); + lua_pushliteral(__ls, "__metatable"); + lua_pushvalue(__ls, -3); + lua_rawset(__ls, -3); + lua_pop(__ls, 1); + return 1; +} +//@DEVI-after jmpt_register, the methods are still on the stack. remove them by lua_pop(__ls, 1) +/**********************************************************************************************************************/ +//@DEVI-the main is only meant for testing +#pragma weak main +int main(int argc, char** argv) { + return 0; +} +/**********************************************************************************************************************/ +/*last line intentionally left blank.*/ + diff --git a/bruiser/asmrewriter.h b/bruiser/asmrewriter.h new file mode 100644 index 0000000..ce28dcd --- /dev/null +++ b/bruiser/asmrewriter.h @@ -0,0 +1,89 @@ + + +/***************************************************Project Mutator****************************************************/ +/*first line intentionally left blank.*/ +/*bruiser's lua asmrewriter implementation for jump tables*/ +/*Copyright (C) 2018 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 "./lua-5.3.4/src/lua.hpp" +#include "./bruisercapstone.h" + +#include <inttypes.h> +/**********************************************************************************************************************/ +#ifndef ASM_REWRITER_H +#define ASM_REWRITER_H + +static JMP_S_T* convert_jmpt(lua_State* __ls, int index); +static JMP_S_T* check_jmpt(lua_State* __ls, int index); +static JMP_S_T* push_jmpt(lua_State* __ls); +static int new_jmpt(lua_State* __ls); +static int jmpt_custom(lua_State* __ls); + +#define SET_GENERATOR(X) \ + static int jmpt_set_##X(lua_State* __ls); + +#define X_LIST_GEN \ + X(type, "setter method for type")\ + X(location, "setter method for location")\ + X(size, "setter method for size")\ + X(address, "setter method for address")\ + X(address_y, "setter method for address_y")\ + X(address_n, "setter method for address_n")\ + X(y, "setter method for y")\ + X(n, "setter method for n")\ + X(z, "setter method for z") + +#define X(X1,X2) SET_GENERATOR(X1) +X_LIST_GEN +#undef X +#undef X_LIST_GEN +#undef SET_GENERATOR + +static int jmpt_set_next(lua_State* __ls) {} +static int jmpt_set_next_y(lua_State* __ls) {} +static int jmpt_set_next_n(lua_State* __ls) {} + +static const luaL_reg jmpt_methods[] = { + {"new", new_jmpt}, + {"set_type", jmpt_set_type}, + {"set_location", jmpt_set_location}, + {"set_size", jmpt_set_size}, + {"set_address", jmpt_set_address}, + {"set_address_y", jmpt_set_address_y}, + {"set_address_n", jmpt_set_address_n}, + {"set_next", jmpt_set_next}, + {"set_next_y", jmpt_set_next_y}, + {"set_next_n", jmpt_set_next_n}, + {"set_y", jmpt_set_y}, + {"set_n", jmpt_set_n}, + {"set_z", jmpt_set_z}, + {0,0} +}; + +static int jmpt_gc(lua_State* __ls) {} + +static const luaL_reg jmpt_meta[] = { + {"__gc", jmpt_gc}, + {0, 0} +} + +int jmpt_register(lua_State* __ls) { + +#endif +/**********************************************************************************************************************/ +/*last line intentionally left blank.*/ + diff --git a/bruiser/bruiser-extra.h b/bruiser/bruiser-extra.h index b834345..94392e2 100644 --- a/bruiser/bruiser-extra.h +++ b/bruiser/bruiser-extra.h @@ -131,6 +131,9 @@ std::vector<std::string> LUA_FUNCS = "xobjlist()", "xallocglobal(", "xallocallglobals()", + "getjmptable(", + "freejmptable(", + "dumpjmptable(", "_G", "_VERSION", "assert", diff --git a/bruiser/bruiser.cpp b/bruiser/bruiser.cpp index 50c01cc..e6a3520 100644 --- a/bruiser/bruiser.cpp +++ b/bruiser/bruiser.cpp @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* #include "ORCmutation.h" #include "executioner.h" #include "bruiserffi.h" +#include "bruisercapstone.h" /*standard headers*/ #include <fstream> #include <string> @@ -105,9 +106,96 @@ cl::opt<bool> MainFileOnly("MainOnly", cl::desc("bruiser will only report the re cl::opt<std::string> M0XMLPath("xmlpath", cl::desc("tells bruiser where to find the XML file containing the Mutator-LVL0 report."), cl::init(bruiser::M0REP), cl::cat(BruiserCategory), cl::ZeroOrMore); 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); +// @DEVI-FIXME-we need something like python's code module. lua's -i is not it. +cl::opt<bool> LuaInteractive("interactive", cl::desc("run in interactive mode"), 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); /**********************************************************************************************************************/ +template <typename T> +int pushLuaTableInt(lua_State* __ls, std::vector<T> vec) { + int tableindex = 1; + lua_newtable(__ls); + if (!lua_checkstack(__ls, vec.size())) { + PRINT_WITH_COLOR_LB(RED, "cant grow lua stack. current size is too small."); + return -1; + } + for (auto& iter : vec) { + lua_pushinteger(__ls, tableindex); + tableindex++; + lua_pushinteger(__ls, iter); + lua_settable(__ls, -3); + } + return 0; +} + +int pushLuaTableString(lua_State* __ls, std::vector<std::string> vec) { + int tableindex = 1; + lua_newtable(__ls); + if (!lua_checkstack(__ls, vec.size())) { + PRINT_WITH_COLOR_LB(RED, "cant grow lua stack. current size is too small."); + return -1; + } + for (auto& iter : vec) { + lua_pushinteger(__ls, tableindex); + tableindex++; + lua_pushstring(__ls, iter.c_str()); + lua_settable(__ls, -3); + } + return 0; +} + +template <typename T> +int pushLuaTableNumber(lua_State* __ls, std::vector<T> vec) { + int tableindex = 1; + lua_newtable(__ls); + if (!lua_checkstack(__ls, vec.size())) { + PRINT_WITH_COLOR_LB(RED, "cant grow lua stack. current size is too small."); + return -1; + } + for (auto& iter : vec) { + lua_pushinteger(__ls, tableindex); + tableindex++; + lua_pushnumber(__ls, iter); + lua_settable(__ls, -3); + } + return 0; +} + +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); + for (int i = 1; i <= table_length; ++i) { + lua_rawgeti(__ls, argnum, i); + ret.push_back(lua_tointeger(__ls, i + numargs)); + } + return ret; +} + +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); + for (int i = 1; i <= table_length; ++i) { + lua_rawgeti(__ls, argnum, i); + ret.push_back(lua_tostring(__ls, i + numargs)); + } + return ret; +} + +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); + for (int i = 1; i <= table_length; ++i) { + lua_rawgeti(__ls, argnum, i); + ret.push_back(lua_tonumber(__ls, i + numargs)); + } + return ret; +} +/**********************************************************************************************************************/ class LuaEngine { public: @@ -252,8 +340,59 @@ class PyExec { return 0; } - //std::vector<std::string> actionParser(std::string action) {} - //void convertPush(PyObject* pyobject) {} + std::vector<std::string> actionParser(std::string action) {} + void convertNPush(PyObject* pyobject) {} + + int64_t pyInt(PyObject* po) {return PyLong_AsLong(po);} + + double pyFloat(PyObject* po) {return PyFloat_AsDouble(po);} + + std::vector<PyObject*> pyList_unpack(PyObject* po) { + std::vector<PyObject*> dummy; + if (PyList_Check(po)) { + int size = PyList_Size(po); + for (int i = 0; i < size; ++i) { + dummy.push_back(PyList_GetItem(po, i)); + } + } else { + PRINT_WITH_COLOR_LB(RED, "Not a PyList object."); + } + return dummy; + } + + std::string pyString(PyObject* po) { + return PyBytes_AsString(PyUnicode_AsEncodedString(PyObject_Repr(po), "utf-8", "surrogateescape")); + } + + std::pair<std::vector<PyObject*>, std::vector<PyObject*>> pyDict_unpack(PyObject* po) { + std::vector<PyObject*> Keys, Values; + if (PyDict_Check(po)) { + Keys = pyList_unpack(PyDict_Keys(po)); + Values = pyList_unpack(PyDict_Values(po)); + } else { + PRINT_WITH_COLOR_LB(RED, "Not a PyDict object."); + } + return std::make_pair(Keys, Values); + } + + char* pyBytes(PyObject* po) { + char* dummy; + if (PyBytes_Check(po)) { + dummy = PyBytes_AsString(po); + } else { + PRINT_WITH_COLOR_LB(RED, "Not a PyBytes object."); + } + return dummy; + } + + char* pyByteArray(PyObject* po) { + char* dummy; + if (PyByteArray_Check(po)) { + dummy = PyByteArray_AsString(po); + } else { + PRINT_WITH_COLOR_LB(RED, "Not a PyByteArray object."); + } + } int getAsCppStringVec(void) { if (Verbose) PRINT_WITH_COLOR_LB(BLUE, "processing return result..."); @@ -1443,7 +1582,7 @@ class LuaWrapper int BruiserLuaXObjAllocGlobal(lua_State* __ls) { int numargs = lua_gettop(__ls); - if (numargs != 2) {PRINT_WITH_COLOR_LB(RED, "expected exactly two args. did not get that.");} + if (numargs != 2) {PRINT_WITH_COLOR_LB(RED, "expected exactly two args. did not get that.");return 0;} std::string glob_name = lua_tostring(__ls , 1); size_t size = lua_tointeger(__ls, 2); xglobals.reserve(size); @@ -1452,6 +1591,33 @@ class LuaWrapper int BruiserLuaXObjAllocAllGlobals(lua_State* __ls) {} + int BruiserGetJumpTable(lua_State* __ls) { + int numargs = lua_gettop(__ls); + 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); + auto ptr = makejmptable(size, code_v.data()); + std::cout << RED << &ptr << NORMAL << "\n"; + lua_pushlightuserdata(__ls, ptr); + return 1; + } + + int BruiserFreeJumpTable(lua_State* __ls) { + int numargs = lua_gettop(__ls); + if (numargs != 1) {PRINT_WITH_COLOR_LB(RED, "expected exactly one argument.");} + uint64_t head = lua_tointeger(__ls, 1); + freejmptable((JMP_S_T*)head); + return 0; + } + + int BruiserDumpJumpTable(lua_State* __ls) { + int numargs = lua_gettop(__ls); + if (numargs != 1) {PRINT_WITH_COLOR_LB(RED, "expected exactly one argument of type lightuserdata.");} + uint64_t ptr = lua_tointeger(__ls, 1); + dumpjmptable((JMP_S_T*)ptr); + return 0; + } + /*read the m0 report*/ int BruiserLuaM0(lua_State* __ls) { @@ -2064,6 +2230,9 @@ int main(int argc, const char **argv) { lua_register(LE.GetLuaState(), "xobjlist", &LuaDispatch<&LuaWrapper::BruiserLuaXObjGetList>); lua_register(LE.GetLuaState(), "xallocglobal", &LuaDispatch<&LuaWrapper::BruiserLuaXObjAllocGlobal>); lua_register(LE.GetLuaState(), "xallocallglobals", &LuaDispatch<&LuaWrapper::BruiserLuaXObjAllocAllGlobals>); + lua_register(LE.GetLuaState(), "getjmptable", &LuaDispatch<&LuaWrapper::BruiserGetJumpTable>); + lua_register(LE.GetLuaState(), "freejmptable", &LuaDispatch<&LuaWrapper::BruiserFreeJumpTable>); + lua_register(LE.GetLuaState(), "dumpjmptable", &LuaDispatch<&LuaWrapper::BruiserDumpJumpTable>); /*its just regisering the List function from LuaWrapper with X-macros.*/ #define X(__x1, __x2) lua_register(LE.GetLuaState(), #__x1, &LuaDispatch<&LuaWrapper::List##__x1>); diff --git a/bruiser/bruiser.h b/bruiser/bruiser.h index 616f2c8..584d652 100644 --- a/bruiser/bruiser.h +++ b/bruiser/bruiser.h @@ -157,7 +157,10 @@ help CMDHelp[] = { {"xcall", "xcall(index, num_args)", "call xobj with the given index in to the xobj vector with the given number of args", "", "returns the xobj call result"}, {"xobjlist", "xobjlist()", "return a table containing xobj pointers and names. names are keys, values are the pointers.", "", "table of pairs"}, {"xallocglobal", "xallocglobal(index)", "allocate a global value with index index", "", ""}, - {"xallocallglobals", "xallocallglobals()", "allocate all globals", "", ""} + {"xallocallglobals", "xallocallglobals()", "allocate all globals", "", ""}, + {"getjmptable", "getjmptable(size, code)", "get a table of all jumps", "", "returns a pointer to the head of the jump table linked-list as lightuserdata"}, + {"freejmptable", "freejmptable(head)", "free the jmp table linked-list", "", "nothing"}, + {"dumpjmptable", "dumpjmptable(head)", "dumps the jmp table linked-list", "", "nothing"} }; /**********************************************************************************************************************/ /** diff --git a/bruiser/bruisercapstone.c b/bruiser/bruisercapstone.c index aea791d..8e190c5 100644 --- a/bruiser/bruisercapstone.c +++ b/bruiser/bruisercapstone.c @@ -31,17 +31,28 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* #include <string.h> /**********************************************************************************************************************/ /**********************************************************************************************************************/ +JMP_S_T* head = NULL; +JMP_S_T* tail = NULL; extern char etext, edata, end; // quad #define CODE_1 "\x55\x48\x89\xe5\x48\x83\xec\x20\x89\x7d\xfc\x89\x75\xf8\x89\x55\xf4\x89\x4d\xf0\x8b\x7d\xfc\x8b\x75\xf8\xe8\xd1\xfd\xff\xff\x8b\x7d\xf4\x8b\x75\xf0\x89\x45\xec\xe8\xc3\xfd\xff\xff\x8b\x4d\xec\x1\xc1\x89\xc8\x48\x83\xc4\x20\x5d\xc3" // glob #define CODE_2 "\x55\x48\x89\xe5\x48\x8b\x05\x0d\x15\x20\x00\x48\x8b\x0d\xee\x14\x20\x00\x48\x8b\x15\xf7\x14\x20\x00\x48\x8b\x35\xd8\x14\x20\x00\x8b\x3e\x03\x3a\x03\x39\x03\x38\x89\xf8\x5d\xc3" +// main +# define CODE_3 "\x31\xed\x49\x89\xd1\x5e\x48\x89\xe2\x48\x83\xe4\xf0\x50\x54\x49\xc7\xc0\x60\x07\x40\x00\x48\xc7\xc1\xf0\x06\x40\x00\x48\xc7\xc7\x90\x06\x40\x00\xff\x15\xa6\x0b\x20\x00\xf4\x0f\x1f\x44\x00\x00\x55\xb8\x38\x10\x60\x00\x48\x3d\x38\x10\x60\x00\x48\x89\xe5\x74\x17\xb8\x00\x00\x00\x00\x48\x85\xc0\x74\x0d\x5d\xbf\x38\x10\x60\x00\xff\xe0\x0f\x1f\x44\x00\x00\x5d\xc3\x66\x0f\x1f\x44\x00\x00\xbe\x38\x10\x60\x00\x55\x48\x81\xee\x38\x10\x60\x00\x48\x89\xe5\x48\xc1\xfe\x03\x48\x89\xf0\x48\xc1\xe8\x3f\x48\x01\xc6\x48\xd1\xfe\x74\x15\xb8\x00\x00\x00\x00\x48\x85\xc0\x74\x0b\x5d\xbf\x38\x10\x60\x00\xff\xe0\x0f\x1f\x00\x5d\xc3\x66\x0f\x1f\x44\x00\x00\x80\x3d\x6d\x0b\x20\x00\x00\x75\x17\x55\x48\x89\xe5\xe8\x7e\xff\xff\xff\xc6\x05\x5b\x0b\x20\x00\x01\x5d\xc3\x0f\x1f\x44\x00\x00\xf3\xc3\x0f\x1f\x40\x00\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00\x55\x48\x89\xe5\x5d\xeb\x89\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x55\x48\x89\xe5\xb8\x01\x00\x00\x00\x5d\xc3\x0f\x1f\x44\x00\x00\x55\x48\x89\xe5\xb8\x02\x00\x00\x00\x5d\xc3\x0f\x1f\x44\x00\x00\x55\x48\x89\xe5\xb8\x03\x00\x00\x00\x5d\xc3\x0f\x1f\x44\x00\x00\x55\x48\x89\xe5\xb8\x04\x00\x00\x00\x5d\xc3\x0f\x1f\x44\x00\x00\x55\x48\x89\xe5\xb8\x05\x00\x00\x00\x5d\xc3\x0f\x1f\x44\x00\x00\x55\x48\x89\xe5\xb8\x06\x00\x00\x00\x5d\xc3\x0f\x1f\x44\x00\x00\x55\x48\x89\xe5\x89\x7d\xfc\x89\x75\xf8\x8b\x75\xfc\x03\x75\xf8\x89\xf0\x5d\xc3\x66\x66\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00\x55\x48\x89\xe5\x89\x7d\xfc\x89\x75\xf8\x8b\x75\xfc\x2b\x75\xf8\x89\xf0\x5d\xc3\x66\x66\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00\x55\x48\x89\xe5\xf2\x0f\x11\x45\xf8\xf2\x0f\x11\x4d\xf0\xf2\x0f\x10\x45\xf8\xf2\x0f\x58\x45\xf0\x5d\xc3\x66\x0f\x1f\x44\x00\x00\x55\x48\x89\xe5\xf2\x0f\x11\x45\xf8\xf2\x0f\x11\x4d\xf0\xf2\x0f\x10\x45\xf8\xf2\x0f\x5c\x45\xf0\x5d\xc3\x66\x0f\x1f\x44\x00\x00\x55\x48\x89\xe5\xf2\x0f\x11\x45\xf8\xf2\x0f\x11\x4d\xf0\xf2\x0f\x11\x55\xe8\xf2\x0f\x10\x45\xf8\xf2\x0f\x58\x45\xf0\xf2\x0f\x58\x45\xe8\x5d\xc3\x66\x66\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00\x55\x48\x89\xe5\x48\x83\xec\x20\x89\x7d\xfc\x89\x75\xf8\x89\x55\xf4\x89\x4d\xf0\x8b\x7d\xfc\x8b\x75\xf8\xe8\x31\xff\xff\xff\x8b\x7d\xf4\x8b\x75\xf0\x89\x45\xec\xe8\x23\xff\xff\xff\x8b\x4d\xec\x01\xc1\x89\xc8\x48\x83\xc4\x20\x5d\xc3\x66\x0f\x1f\x44\x00\x00\x55\x48\x89\xe5\x48\x89\x7d\xf8\x48\x8b\x45\xf8\x5d\xc3\x66\x90\x55\x48\x89\xe5\x48\x8d\x05\xc5\x09\x20\x00\x48\x8d\x0d\xba\x09\x20\x00\x48\x8d\x15\xaf\x09\x20\x00\x48\x8d\x35\xa4\x09\x20\x00\x8b\x3e\x03\x3a\x03\x39\x03\x38\x89\xf8\x5d\xc3\x0f\x1f\x40\x00\x55\x48\x89\xe5\x48\x83\xec\x20\xb8\x0a\x00\x00\x00\xb9\x14\x00\x00\x00\xc7\x45\xfc\x00\x00\x00\x00\x89\x7d\xf8\x48\x89\x75\xf0\x89\xc7\x89\xce\xe8\xa7\xfe\xff\xff\x48\x8d\x3d\xc0\x00\x00\x00\x89\x45\xec\xb0\x00\xe8\x46\xfd\xff\xff\xbf\x14\x00\x00\x00\xbe\x0a\x00\x00\x00\x89\x45\xe8\xe8\xa4\xfe\xff\xff\x48\x83\xc4\x20\x5d\xc3\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x40\x00\x41\x57\x41\x56\x49\x89\xd7\x41\x55\x41\x54\x4c\x8d\x25\xee\x06\x20\x00\x55\x48\x8d\x2d\xee\x06\x20\x00\x53\x41\x89\xfd\x49\x89\xf6\x4c\x29\xe5\x48\x83\xec\x08\x48\xc1\xfd\x03\xe8\xc7\xfc\xff\xff\x48\x85\xed\x74\x20\x31\xdb\x0f\x1f\x84\x00\x00\x00\x00\x00\x4c\x89\xfa\x4c\x89\xf6\x44\x89\xef\x41\xff\x14\xdc\x48\x83\xc3\x01\x48\x39\xdd\x75\xea\x48\x83\xc4\x08\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\x41\x5f\xc3\x90\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00\xf3\xc3" +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +JMP_S_T* iter_next(JMP_S_T* arg) {return arg->next;} +JMP_S_T* iter_next_y(JMP_S_T* arg) {return arg->next_y;} +JMP_S_T* iter_next_n(JMP_S_T* arg) {return arg->next_n;} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ /**********************************************************************************************************************/ /**********************************************************************************************************************/ uint32_t get_textsection_length(void) {return &edata-&etext;} /**********************************************************************************************************************/ /**********************************************************************************************************************/ -uintptr_t get_symbol_rt_address(const char* symbol_name) {} +uintptr_t get_symbol_rt_address(const char* symbol_name) {return NULL;} /**********************************************************************************************************************/ /**********************************************************************************************************************/ void int2byte(int value, uint8_t* ret_value, size_t size) { @@ -95,7 +106,7 @@ int ks_write(ks_arch arch, int mode, const char* assembly, int syntax, unsigned if (syntax) ks_option(ks, KS_OPT_SYNTAX, syntax); if (ks_asm(ks, assembly, 0, &encode, &size, &count)) {printf("errored out\n"); return -1;} -#if 0 +#if 1 else { printf("%s =", assembly); for (size_t i = 0; i < size; ++i) { @@ -119,14 +130,17 @@ int global_rewriter(int offset, size_t size, uint8_t* asm_code, const char* obj) unsigned char *encode; if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) return -1; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-sign" count = cs_disasm(handle, obj, size, 0x0, 0, &insn); - printf("number of instructions: %d.\n\n", count); +#pragma GCC diagnostic pop + printf("number of instructions: %zu.\n\n", count); cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); if (count > 0) { size_t j; for (j = 0; j < count; ++j) { - printf(CYAN"%d.\t"NORMAL, j); + printf(CYAN"%zu.\t"NORMAL, j); printf(GREEN"0x%"PRIx64":\t%s\t\t%s\t"NORMAL, insn[j].address, insn[j].mnemonic, insn[j].op_str); printf(BLUE"insn size: %d\n"NORMAL, insn[j].size); //for (int i = 0; i < 16; ++i) {code[i] = insn[j].bytes[i]; printf("%02x ", code[i]);} @@ -159,14 +173,17 @@ int call_rewriter(int offset, size_t size, uint8_t* asm_code, const char* obj) { size_t size_counter = 0; if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) return -1; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-sign" count = cs_disasm(handle, obj, size, 0x0, 0, &insn); - printf("number of instructions: %d.\n\n", count); +#pragma GCC diagnostic pop + printf("number of instructions: %zu.\n\n", count); cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); if (count > 0) { size_t j; for (j = 0; j < count; ++j) { - printf(CYAN"%d.\t"NORMAL, j); + printf(CYAN"%zu.\t"NORMAL, j); printf(GREEN"0x%"PRIx64":\t%s""\t\t%s\t"NORMAL, insn[j].address, insn[j].mnemonic, insn[j].op_str); for (int i = 0; i < 16; ++i) {code[i] = insn[j].bytes[i]; printf(BLUE"%02x "NORMAL, code[i]);} printf("\n"); @@ -198,6 +215,141 @@ int call_rewriter(int offset, size_t size, uint8_t* asm_code, const char* obj) { } /**********************************************************************************************************************/ /**********************************************************************************************************************/ +JMP_S_T* makejmptable(size_t size, uint8_t* obj) { + csh handle; + cs_insn* insn; + size_t count; + uint8_t rewritten[16]; + uint8_t code[16]; + size_t size_counter = 0; + + head = malloc(sizeof(JMP_S_T)); + tail = malloc(sizeof(JMP_S_T)); + head->type = NONE; + head->next = NULL; + tail = head; + + 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" + count = cs_disasm(handle, obj, size, 0x0, 0, &insn); +#pragma GCC diagnostic pop + printf("number of instructions: %zu.\n\n", count); + cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); + + intmax_t address; + if (count > 0) { + size_t j; + for (j = 0; j < count; ++j) { + printf(CYAN"%zu.\t"NORMAL, j); + printf(GREEN"0x%"PRIx64":\t%s""\t\t%s\t"NORMAL, insn[j].address, insn[j].mnemonic, insn[j].op_str); + for (int i = 0; i < 16; ++i) {code[i] = insn[j].bytes[i]; printf(BLUE"%02x "NORMAL, code[i]);} + printf("\n"); + + if (strcmp(insn[j].mnemonic, "jmp") == 0) { + char* endptr; + address = strtoumax(insn[j].op_str, &endptr, 0); +#if 1 + printf(RED"found a jmp\n"); + for (int i = 0; i < 16; ++i) {code[i] = insn[j].bytes[i]; printf(RED"%02x "NORMAL, code[i]);} + printf("\n"); + printf(RED"%jx\n", address); + printf(RED"%d\n", insn[j].size); +#endif + JMP_S_T* dummy = malloc(sizeof(JMP_S_T)); + dummy->location = insn[j].address; + dummy->type = JMP; + dummy->address = address; + dummy->size = insn[j].size; + dummy->next = NULL; + tail->next = dummy; + tail = dummy; + } + + if (strcmp(insn[j].mnemonic, "je") == 0) { + char* endptr; + address = strtoimax(insn[j].op_str, &endptr, 0); +#if 1 + printf(RED"found a je\n"); + for (int i = 0; i < 16; ++i) {code[i] = insn[j].bytes[i]; printf(RED"%02x "NORMAL, code[i]);} + printf("\n"); + printf(RED"%jx\n", address); + printf(RED"%d\n", insn[j].size); +#endif + JMP_S_T* dummy = malloc(sizeof(JMP_S_T)); + dummy->location = insn[j].address; + dummy->type = JE; + dummy->address_y = address; + dummy->size = insn[j].size; + dummy->next = NULL; + tail->next = dummy; + tail = dummy; + } + + if (strcmp(insn[j].mnemonic, "jne") == 0) { + char* endptr; + address = strtoimax(insn[j].op_str, &endptr, 0); +#if 1 + printf(RED"found a jne\n"); + for (int i = 0; i < 16; ++i) {code[i] = insn[j].bytes[i]; printf(RED"%02x "NORMAL, code[i]);} + printf("\n"); + printf(RED"%lx\n", address); + printf(RED"%d\n", insn[j].size); +#endif + JMP_S_T* dummy = malloc(sizeof(JMP_S_T)); + dummy->location = insn[j].address; + dummy->type = JNE; + dummy->address_y = address; + dummy->size = insn[j].size; + dummy->next = NULL; + tail->next = dummy; + tail = dummy; + } + +#if 0 + for (int i = 0; i < insn[j].size; ++i) { + asm_code[size_counter] = insn[j].bytes[i]; + size_counter++; + } +#endif + } + + cs_free(insn, count); + } else { + printf("ERROR!!!\n"); + } + cs_close(&handle); + return head; +} +/**********************************************************************************************************************/ +int freejmptable(JMP_S_T* _head) { + JMP_S_T* previous = _head; + JMP_S_T* current = _head; + while (current != NULL) { + previous = current; + current = current->next; + free(previous); + } + return 0; +} +/**********************************************************************************************************************/ +int dumpjmptable(JMP_S_T* current) { + while (current != NULL) { + printf("jump location: %lx", current->location); + printf("\tjump address: %lu", current->address); + printf("\tjump type: %d", current->type); + printf("\tinstruction size: %d\n", current->size); + current = current->next; + } +} +/**********************************************************************************************************************/ +void jmprewriter_j(JMP_S_T* jmp, uint8_t* code, JMP_T type, uint8_t* rewritten) { + +} +void jmprewriter_jne(JMP_S_T* jmp, uint8_t* code, JMP_T type, uint8_t* rewritten) {}; +void jmprewriter_je(JMP_S_T* jmp, uint8_t* code, JMP_T type, uint8_t* rewritten) {} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ // @DEVI-the following lines are only meant for testing. #pragma weak main int main(int argc, char** argv) { @@ -223,6 +375,7 @@ int main(int argc, char** argv) { printf("end: %10p\n", &end); printf("text section length: %d\n", get_textsection_length()); +#if 1 printf("----------------------------------------------------------\n"); uint8_t value[4]; int2byte(-528, value, 4); @@ -235,11 +388,34 @@ int main(int argc, char** argv) { for (int i = 0; i < 4; ++i) {printf("%02x ", value[i]);} printf("\n"); printf("----------------------------------------------------------\n"); +#endif unsigned char* encode; ks_write(KS_ARCH_X86, KS_MODE_64, "add rax, rcx", 0, encode); ks_free(encode); +#if 0 + head = malloc(sizeof(JMP_S_T)); + tail = malloc(sizeof(JMP_S_T)); + head->type = NONE; + head->next = NULL; + tail = head; +#endif + uint8_t asm_code3[834]; + JMP_S_T* current = makejmptable(834, CODE_3); + +#if 0 + while (current != NULL) { + printf("jump location: %lx", current->location); + printf("\tjump address: %lu", current->address); + printf("\tjump type: %d", current->type); + printf("\tinstruction size: %d\n", current->size); + current = current->next; + } +#endif + dumpjmptable(current); + freejmptable(current); + return 0; } /**********************************************************************************************************************/ diff --git a/bruiser/bruisercapstone.h b/bruiser/bruisercapstone.h index 054eb19..d10db70 100644 --- a/bruiser/bruisercapstone.h +++ b/bruiser/bruisercapstone.h @@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* #include <capstone/capstone.h> #include <keystone/keystone.h> #include <stdint.h> +#include <inttypes.h> /**********************************************************************************************************************/ #ifndef BRUISER_CAPSTONE_H #define BRUISER_CAPSTONE_H @@ -29,6 +30,30 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* extern "C" { #endif +enum jmp_type {NONE=0, JMP=1, JNE=2, JE=3}; +#define JMP_T enum jmp_type + +struct jmp_s_t { + JMP_T type; + uint64_t location; + uint8_t size; + struct jmp_s_t* next; + struct jmp_s_t* next_y; + struct jmp_s_t* next_n; + uint64_t address; + uint64_t address_y; + uint64_t address_n; + bool y; + bool n; + bool z; +}; +#define JMP_S_T struct jmp_s_t +JMP_S_T* iter_next(JMP_S_T* arg); +JMP_S_T* iter_next_y(JMP_S_T* arg); +JMP_S_T* iter_next_n(JMP_S_T* arg); +extern JMP_S_T* head; +extern JMP_S_T* tail; + uint32_t get_textsection_length(void); uintptr_t get_symbol_rt_address(const char* symbol_name); void int2byte(int value, uint8_t* ret_value, size_t size); @@ -39,6 +64,12 @@ void leb128_decode_u(uint32_t value, uint8_t* ret_value, size_t size); int ks_write(ks_arch arch, int mode, const char* assembly, int syntax, unsigned char* encode); int global_rewriter(int offset, size_t size, uint8_t* asm_code, const char* obj); int call_rewriter(int offset, size_t size, uint8_t* asm_code, const char* obj); +JMP_S_T* makejmptable(size_t size, uint8_t* obj); +int freejmptable(JMP_S_T* _head); +int dumpjmptable(JMP_S_T* head); +void jmprewriter_j(JMP_S_T* jmp, uint8_t* code, JMP_T type, uint8_t* rewritten); +void jmprewriter_jne(JMP_S_T* jmp, uint8_t* code, JMP_T type, uint8_t* rewritten); +void jmprewriter_je(JMP_S_T* jmp, uint8_t* code, JMP_T type, uint8_t* rewritten); #ifdef __cplusplus } diff --git a/bruiser/bruiserffi.c b/bruiser/bruiserffi.c index fee9dfe..24ebe0d 100644 --- a/bruiser/bruiserffi.c +++ b/bruiser/bruiserffi.c @@ -32,8 +32,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* /**********************************************************************************************************************/ #define VOIDIFY(X) (void*)X /**********************************************************************************************************************/ -#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" #pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" #define REINTERPRET_GENERATOR(X) \ X ffi_reinterpret_##X(void* result) {return (X)result;} @@ -53,6 +53,7 @@ X_LIST_GEN #undef X #undef X_LIST_GEN #undef REINTERPRET_GENERATOR +#pragma GCC diagnostic pop float ffi_reinterpret_float(void* result) {return *(float*)&result;} double ffi_reinterpret_double(void* result) {return *(double*)&result;} char* ffi_reinterpret_string(void* result) {return (char*)result;} diff --git a/bruiser/lua-scripts/demo2.lua b/bruiser/lua-scripts/demo2.lua index 3b6007a..c8de8aa 100644 --- a/bruiser/lua-scripts/demo2.lua +++ b/bruiser/lua-scripts/demo2.lua @@ -25,11 +25,37 @@ function main() xobjregister(passthrough_code, "passthrough") end +function pretty_dump() + count = 0 + local text_section = xobj.getTextSection() + 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 test() + local text_section = xobj.getTextSection() + dummy = xobj.CSDump(text_section) + print(dummy) +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") + local head = getjmptable(#text_section, text_section) + print("head value is",head) + dumpjmptable(head) + freejmptable(haed) end --main() +--pretty_dump() +--test() asm_rewriter() diff --git a/bruiser/lua-scripts/xobj.lua b/bruiser/lua-scripts/xobj.lua index 880730a..81d0bc0 100644 --- a/bruiser/lua-scripts/xobj.lua +++ b/bruiser/lua-scripts/xobj.lua @@ -133,6 +133,14 @@ function xobj.getTextSection() return objload("elf_get_text_section", elf_exe, "bytes") end +function xobj.CSDump(code) + ret = "" + for k,v in pairs(code) do + ret = ret.."\\x"..string.format("%02x",v) + end + return ret +end + --end of xobj module return xobj -------------------------------------------------------------------------------------------------------------- diff --git a/bruiser/makefile b/bruiser/makefile index d306a4b..a50faf4 100644 --- a/bruiser/makefile +++ b/bruiser/makefile @@ -13,7 +13,7 @@ SRCS=$(wildcard *.cpp) C_SRCS=$(wildcard *.c) #for some reason without ld the build fails on ubuntu trusty on travis #EXTRA_LD_FLAGS+=-lpthread -ldl -lutil -lm -Xlinker -lpython3 -EXTRA_LD_FLAGS+=$(shell $(PY_CONF) --ldflags) -lffi #-lcapstone +EXTRA_LD_FLAGS+=$(shell $(PY_CONF) --ldflags) -lffi -lcapstone -lkeystone ######################################RULES#################################### .DEFAULT: all @@ -50,7 +50,7 @@ $(LIB_LUA_JIT): $(MAKE) -C LuaJIT @echo "building with jit" -$(BRUISER): $(BRUISER).o ../mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o $(LIB_LUA) +$(BRUISER): $(BRUISER).o ../mutator_aux.o ../tinyxml2/tinyxml2.o linenoise.o CompletionHints.o mutagen.o ORCmutation.o bruiserffi.o bruisercapstone.o $(LIB_LUA) $(CXX) $^ $(LD_FLAGS) -o $@ clean: |