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