aboutsummaryrefslogtreecommitdiffstats
path: root/bruiser
diff options
context:
space:
mode:
Diffstat (limited to 'bruiser')
-rw-r--r--bruiser/README.md3
-rw-r--r--bruiser/asmrewriter.c149
-rw-r--r--bruiser/asmrewriter.h89
-rw-r--r--bruiser/bruiser-extra.h3
-rw-r--r--bruiser/bruiser.cpp175
-rw-r--r--bruiser/bruiser.h5
-rw-r--r--bruiser/bruisercapstone.c188
-rw-r--r--bruiser/bruisercapstone.h31
-rw-r--r--bruiser/bruiserffi.c3
-rw-r--r--bruiser/lua-scripts/demo2.lua30
-rw-r--r--bruiser/lua-scripts/xobj.lua8
-rw-r--r--bruiser/makefile4
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: