From 8bff748dd325ff45375e6f5948368e1ee024d411 Mon Sep 17 00:00:00 2001 From: bloodstalker Date: Sat, 17 Feb 2018 11:43:27 +0330 Subject: trying to implement the nested call and global object rewriters --- bruiser/bruiser.cpp | 4 +- bruiser/bruisercapstone.c | 247 ++++++++++++++++++++++++++++++++++++++++++ bruiser/bruisercapstone.h | 49 +++++++++ bruiser/bruiserffi.c | 33 ------ bruiser/bruiserffi.h | 19 ++-- bruiser/devi_extra.h | 33 ++++++ bruiser/lua-scripts/demo1.lua | 3 + 7 files changed, 343 insertions(+), 45 deletions(-) create mode 100644 bruiser/bruisercapstone.c create mode 100644 bruiser/bruisercapstone.h create mode 100644 bruiser/devi_extra.h (limited to 'bruiser') diff --git a/bruiser/bruiser.cpp b/bruiser/bruiser.cpp index 053bffc..936bd83 100644 --- a/bruiser/bruiser.cpp +++ b/bruiser/bruiser.cpp @@ -1392,9 +1392,9 @@ class LuaWrapper PRINT_WITH_COLOR_LB(RED, "cant grow lua stack. current size is too small."); } for (auto& iter : xlist) { - std::cout << CYAN << iter.second << NORMAL; + if (Verbose) std::cout << CYAN << iter.second << NORMAL; lua_pushstring(__ls, iter.second.c_str()); - std::cout << " " << MAGENTA << (long int)iter.first << NORMAL <<"\n"; + if (Verbose) std::cout << " " << MAGENTA << (long int)iter.first << NORMAL <<"\n"; lua_pushinteger(__ls, (long int)iter.first); lua_settable(__ls, -3); } diff --git a/bruiser/bruisercapstone.c b/bruiser/bruisercapstone.c new file mode 100644 index 0000000..e65be3b --- /dev/null +++ b/bruiser/bruisercapstone.c @@ -0,0 +1,247 @@ + +/***************************************************Project Mutator****************************************************/ +/*first line intentionally left blank.*/ +/*bruiser's capstone side for rewriting xobjects*/ +/*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 "./bruisercapstone.h" +#include "./devi_extra.h" +#include +#include +#include +#include +#include +#include +#include +#include +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +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" +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +uint32_t get_textsection_length(void) {return &edata-&etext;} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +uintptr_t get_symbol_rt_address(const char* symbol_name) {} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +void int2byte(int value, uint8_t* ret_value, size_t size) { + for (int i = 0; i < size; ++i) { + ret_value[i] = (value & (0xff << (8*i))) >> (8*i); + } +} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +void leb128_encode_s(int32_t value, uint8_t* ret_value, size_t size) { + uint8_t dummy; + if (value == 0) {for (int i = 0; i < size; ++i) ret_value[i] = 0;} + for (int i = 0; i < size; ++i) { + dummy = value & 0x7f; + ret_value[i] = dummy | 0x80; + value >>=7; + if (((value == 0) && ((dummy & 0x40) == 0)) || ((value == -1) && (dummy & 0x40))) { + ret_value[size - 1] ^= 0x80; + break; + } + } +} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +void leb128_encode_u(uint32_t value, uint8_t* ret_value, size_t size) { + uint8_t dummy; + if (value == 0) {for (int i = 0; i < size; ++i) ret_value[i] = 0;} + for (int i = 0; i < size; ++i) { + dummy = value & 0x7f; + ret_value[i] = dummy | 0x80; + value >>=7; + } + ret_value[size - 1] ^= 0x80; +} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +void leb128_decode_s(int32_t value, uint8_t* ret_value, size_t size) {} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +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) { + ks_engine* ks; + ks_err err = KS_ERR_ARCH; + size_t count; + size_t size; + + err = ks_open(arch, mode, &ks); + if (err != KS_ERR_OK) {printf("failed on ks_open().\n"); return -1;} + 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 + else { + printf("%s =", assembly); + for (size_t i = 0; i < size; ++i) { + printf("%02x ", encode[i]); + } + printf("\n"); + } +#endif + + ks_close(ks); + return size; +} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +int global_rewriter(int offset, size_t size, uint8_t* asm_code, const char* obj) { + csh handle; + cs_insn* insn; + size_t count; + uint8_t code[16]; + size_t size_counter = 0; + unsigned char *encode; + + if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) return -1; + count = cs_disasm(handle, obj, size, 0x0, 0, &insn); + printf("number of instructions: %d.\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(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]);} + //printf("\n"); + + if (strcmp(insn[j].mnemonic, "mov") == 0) { + } + + for (int i = 0; i < insn[j].size; ++i) { + asm_code[size_counter] = insn[j].bytes[i]; + size_counter++; + } + } + + cs_free(insn, count); + } else { + printf("ERROR!!!\n"); + } + cs_close(&handle); + return size_counter; +} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +int call_rewriter(int offset, size_t size, uint8_t* asm_code, const char* obj) { + csh handle; + cs_insn* insn; + size_t count; + uint8_t rewritten[16]; + uint8_t code[16]; + size_t size_counter = 0; + + if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) return -1; + count = cs_disasm(handle, obj, size, 0x0, 0, &insn); + printf("number of instructions: %d.\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(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, "call") == 0) { + char* endptr; + intmax_t address = strtoimax(insn[j].op_str, &endptr, 0); + uintmax_t uaddress = strtoumax(insn[j].op_str, &endptr, 0); + // rewriting + asm_code[size_counter] = 0xe8, size_counter++; + uint8_t temp[4]; + //@DEVI-call cant be the last instructino in a function + int2byte(offset + insn[j].address, temp, 4); + for (int i = 0; i < 4; ++i) {asm_code[size_counter] = temp[i]; size_counter++;} + continue; + } + for (int i = 0; i < insn[j].size; ++i) { + asm_code[size_counter] = insn[j].bytes[i]; + size_counter++; + } + } + + cs_free(insn, count); + } else { + printf("ERROR!!!\n"); + } + cs_close(&handle); + return size_counter; +} +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ +// @DEVI-the following lines are only meant for testing. +#pragma weak main +int main(int argc, char** argv) { + uint8_t asm_code[58]; + uint8_t asm_code2[44]; + printf("----------------------------------------------------------\n"); + printf("call_rewriter:\n"); + int new_size = call_rewriter(-528, 58, asm_code, CODE_1); + printf("new size is %d.\n", new_size); + for (int i = new_size; i < 58; ++i) {asm_code[i] = 0;} + for (int i = 0; i < 58; ++i) {printf("%02x ", asm_code[i]);} + + printf("\n----------------------------------------------------------\n"); + printf("global_rewriter:\n"); + new_size = global_rewriter(-528, 44, asm_code2, CODE_2); + printf("new size is %d.\n", new_size); + for (int i = new_size; i < 44; ++i) {asm_code2[i] = 0;} + for (int i = 0; i < 44; ++i) {printf("%02x ", asm_code2[i]);} + + printf("\n----------------------------------------------------------\n"); + printf("etext: %10p\n", &etext); + printf("edata: %10p\n", &edata); + printf("end: %10p\n", &end); + printf("text section length: %d\n", get_textsection_length()); + + printf("----------------------------------------------------------\n"); + uint8_t value[4]; + int2byte(-528, value, 4); + for (int i = 0; i < 4; ++i) {printf("%02x ", value[i]);} + printf("\n"); + leb128_encode_u(528, value, 4); + for (int i = 0; i < 4; ++i) {printf("%02x ", value[i]);} + printf("\n"); + leb128_encode_s(-528, value, 4); + for (int i = 0; i < 4; ++i) {printf("%02x ", value[i]);} + printf("\n"); + printf("----------------------------------------------------------\n"); + + unsigned char* encode; + ks_write(KS_ARCH_X86, KS_MODE_64, "add rax, rcx", 0, encode); + ks_free(encode); + + return 0; +} +/**********************************************************************************************************************/ +/*last line intentionally left blank.*/ + diff --git a/bruiser/bruisercapstone.h b/bruiser/bruisercapstone.h new file mode 100644 index 0000000..054eb19 --- /dev/null +++ b/bruiser/bruisercapstone.h @@ -0,0 +1,49 @@ + +/***************************************************Project Mutator****************************************************/ +/*first line intentionally left blank.*/ +/*bruiser's capstone side for rewriting xobjects*/ +/*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 +#include +#include +/**********************************************************************************************************************/ +#ifndef BRUISER_CAPSTONE_H +#define BRUISER_CAPSTONE_H + +#ifdef __cplusplus +extern "C" { +#endif + +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); +void leb128_encode_s(int32_t value, uint8_t* ret_value, size_t size); +void leb128_encode_u(uint32_t value, uint8_t* ret_value, size_t size); +void leb128_decode_s(int32_t value, uint8_t* ret_value, size_t size); +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); + +#ifdef __cplusplus +} +#endif +#endif +/**********************************************************************************************************************/ +/*last line intentionally left blank.*/ + diff --git a/bruiser/bruiserffi.c b/bruiser/bruiserffi.c index c847d10..fee9dfe 100644 --- a/bruiser/bruiserffi.c +++ b/bruiser/bruiserffi.c @@ -22,7 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.* // @TODO-vararg xobjs are not supported /**********************************************************************************************************************/ #include "bruiserffi.h" -//#include #include #include #include @@ -169,34 +168,6 @@ void* ffi_callX(int argc, const char** arg_string, ffi_type rtype, void* x_ptr, void* ffi_callX_var(int argc, const char** arg_string, ffi_type rtype, void* x_ptr, void** values) {return NULL;} /**********************************************************************************************************************/ -#if 0 -#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" -int capstone_test(void) { - csh handle; - cs_insn* insn; - size_t count; - if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) return -1; - count = cs_disasm(handle, CODE_1, sizeof(CODE_1) - 1, 0x0, 0, &insn); - if (count > 0) { - size_t j; - for (j = 0; j #include #include /**********************************************************************************************************************/ @@ -33,15 +32,15 @@ extern "C" { X ffi_reinterpret_##X(void* result); #define X_LIST_GEN \ - X(uint8_t, "uint8_t")\ - X(uint16_t, "uint8_t")\ - X(uint32_t, "uint8_t")\ - X(uint64_t, "uint8_t")\ - X(int8_t, "uint8_t")\ - X(int16_t, "uint8_t")\ - X(int32_t, "uint8_t")\ - X(int64_t, "uint8_t")\ - X(uintptr_t, "uint8_t")\ + X(uint8_t, "for uint8_t")\ + X(uint16_t, "for uint16_t")\ + X(uint32_t, "for uint32_t")\ + X(uint64_t, "for uint64_t")\ + X(int8_t, "for int8_t")\ + X(int16_t, "for int16_t")\ + X(int32_t, "for int32_t")\ + X(int64_t, "for int64_t")\ + X(uintptr_t, "for pointers")\ #define X(X1,X2) REINTERPRET_GENERATOR(X1) X_LIST_GEN diff --git a/bruiser/devi_extra.h b/bruiser/devi_extra.h new file mode 100644 index 0000000..9ef66b3 --- /dev/null +++ b/bruiser/devi_extra.h @@ -0,0 +1,33 @@ + +/*first line intentionally left blank.*/ +/**********************************************************************************************************************/ +#include +#include +/**********************************************************************************************************************/ +#ifndef DEVI_EXTRA_H +#define DEVI_EXTRA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define RED "\033[1;31m" +#define CYAN "\033[1;36m" +#define GREEN "\033[1;32m" +#define BLUE "\033[1;34m" +#define BLACK "\033[1;30m" +#define BROWN "\033[1;33m" +#define MAGENTA "\033[1;35m" +#define GRAY "\033[1;37m" +#define DARKGRAY "\033[1;30m" +#define YELLOW "\033[1;33m" +#define NORMAL "\033[0m" +#define CLEAR "\033[2J" + +#ifdef __cplusplus +} +#endif +#endif +/**********************************************************************************************************************/ +/*last line intentionally left blank.*/ + diff --git a/bruiser/lua-scripts/demo1.lua b/bruiser/lua-scripts/demo1.lua index 6645098..efbc7c5 100644 --- a/bruiser/lua-scripts/demo1.lua +++ b/bruiser/lua-scripts/demo1.lua @@ -192,6 +192,9 @@ function main() --print("xcall returned:",a) --if a ~= 100 then print("test failed") end + a = xobjlist() + print("the offset of quad and add2 is : ", a["quad"] - a["add2"]) + end main() -- cgit v1.2.3