diff --git a/hook.c b/hook.c index 1127fb3..d905814 100644 --- a/hook.c +++ b/hook.c @@ -1,21 +1,22 @@ -/* -\todo: -What if there's a loop in the function which loops back to an overwritten instruction? -start: - jmp hook_function - bla - jXX start+3 - -*/ - +// todo: on weird jump: stop the disassembling there or treat as normal instruction? #include #include #include #include -#include +#include + +#ifdef WINDOWS +#include +#else +#include +#include + +#endif + #include "udis86.h" #include "list.h" #include "hook.h" +#include "misc.h" #define MINIMUM_REQUIRED_FUNCTION_LENGTH_SHORT_HOOK 5 #define MINIMUM_REQUIRED_FUNCTION_LENGTH_LONG_HOOK 16 @@ -93,6 +94,9 @@ int hook(void* function, size_t functionLength, void* replacement, void** trampo return (int)*trampoline; printf("Needed for trampoline %p: %d (Found %d)\n", *trampoline, trampolineSizeNeeded, functionLength); +#ifdef WINDOWS + FlushInstructionCache(GetCurrentProcess(), function, needed); +#endif return SUCCESS; } @@ -111,7 +115,7 @@ static void* build_trampoline(void* function, size_t functionSize, size_t* tramp *trampolineSize = 0; - if(!(trampoline = VirtualAlloc(NULL, PAGE_BOUNDARY, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE))) + if(!(trampoline = alloc_rwx(PAGE_BOUNDARY))) return (void*)CANT_ALLOC; printf("trampoline @ %p\n", trampoline); @@ -136,7 +140,7 @@ static void* build_trampoline(void* function, size_t functionSize, size_t* tramp // Check for XXX [rip + ?] const struct ud_operand* op = NULL; - for(int i = 0; op = ud_insn_opr(&ud, i); i++) + for(int i = 0; ; i++, op = ud_insn_opr(&ud, i)) { if((op->type & UD_OP_REG) == UD_OP_REG) { @@ -226,7 +230,7 @@ static int32_t get_rip_delta(ud_t* ud) const struct ud_operand* op = NULL; int32_t ret = 0; - for(int i = 0; op = ud_insn_opr(ud, i); i++) + for(int i = 0; ; i++, op = ud_insn_opr(ud, i)) { // Only the RIP offset is interesting if((op->type & UD_OP_REG) != UD_OP_REG || op->base != UD_R_RIP) @@ -271,7 +275,7 @@ static size_t write_jcc_jump(const uint8_t* instruction, void* whereToWrite, voi static size_t get_jump_offset(ud_t* ud, size_t offsetOfInstr) { const struct ud_operand* op = NULL; - for(int i = 0; op = ud_insn_opr(ud, i); i++) + for(int i = 0; ; i++, op = ud_insn_opr(ud, i)) { if(op->type == UD_OP_JIMM) { @@ -360,8 +364,3 @@ static size_t write_x64_jump(unsigned char* where, void* toWhere) return sizeof(jmpMemTemplate)+sizeof(toWhere); } -//! fixme: -static bool loops_into_overwritten_code(void* function) -{ - return false; -} diff --git a/hook.h b/hook.h index 49630ac..40b4d1e 100644 --- a/hook.h +++ b/hook.h @@ -15,7 +15,8 @@ typedef enum HOOK_STATUS /** \brief - \param functionLength Length of the function you want to hook. If the length isn't known, pass 0 and the library will try to figure it out + \param functionLength Length of the function you want to hook. + If the length isn't known, pass 0 and the library will try to figure it out */ int hook(void* function, size_t functionLength, void* replacement, void* trampoline); diff --git a/main.c b/main.c index 633f91d..df5b694 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,4 @@ #include -#include #include "misc.h" #include "hook.h" @@ -47,8 +46,9 @@ int main(int argc, char** argv) original(3, 1, 1, 1, 1); //original(5, 1, 1, 1, 1); +#if WINDOWS VirtualFree(original, 0, MEM_RELEASE); - +#endif (void)getc(stdin); } diff --git a/misc.c b/misc.c index d03849b..bd30fb1 100644 --- a/misc.c +++ b/misc.c @@ -1,15 +1,43 @@ #include #include +#include +#include + +#ifdef WINDOWS +#include +#else +#include +#endif + #include "udis86.h" #include "misc.h" +void* alloc_rwx(size_t size) { +#ifdef WINDOWS + return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWIRTE); +#else + return mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +#endif +} + +bool set_rwx(void* addr, size_t size) { +#ifdef WINDOWS + DWORD tmp; + return VirtualProtect(addr, size, PAGE_EXECUTE_READWIRTE, &tmp) == TRUE; +#else + return mprotect(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC) == 0; +#endif +} + void disassemble_func(void* function, size_t numberOfInstr) { unsigned char* p = function; ud_t ud; ud_init(&ud); - ud_set_input_buffer(&ud, function, (size_t)function | (0x1000 - 1)); // Can't read further than page boundary - there be dragons + ud_set_input_buffer(&ud, function, + (size_t)function | (0x1000 - 1) // Can't read further than page boundary - there be dragons + ); ud_set_pc(&ud, (uint64_t)function); ud_set_mode(&ud, 64); ud_set_syntax(&ud, UD_SYN_INTEL); @@ -24,8 +52,15 @@ void disassemble_func(void* function, size_t numberOfInstr) printf("%p %s\n", ud_insn_off(&ud), ud_insn_asm(&ud)); - // ugly, ugly hack todo: make it work + /* jmp qword [rip] is used by the hooking engine + * x64 relative jumps don't exists so this way is used: + * jmp qword [rip] + * address where to tjump to + * other code + * Disassembling the address fucks up the dissassembling + * todo: Follow all jump targets? + */ if(strcmp(ud_insn_asm(&ud), "jmp qword [rip]") == 0) p += 8; } -} \ No newline at end of file +} diff --git a/misc.h b/misc.h index c38a176..a86e04b 100644 --- a/misc.h +++ b/misc.h @@ -2,5 +2,7 @@ #define MISC_H void disassemble_func(void* func, size_t numberOfInstr); +bool set_rwx(void* addr, size_t size); -#endif MISC_H \ No newline at end of file +void* alloc_rwx(size_t size); +#endif MISC_H