diff options
Diffstat (limited to 'subhook_x86.c')
-rw-r--r-- | subhook_x86.c | 639 |
1 files changed, 326 insertions, 313 deletions
diff --git a/subhook_x86.c b/subhook_x86.c index 8e37655..c908c63 100644 --- a/subhook_x86.c +++ b/subhook_x86.c @@ -33,20 +33,22 @@ #include "subhook_private.h" #ifdef SUBHOOK_WINDOWS - typedef unsigned __int8 uint8_t; - typedef __int32 int32_t; - typedef unsigned __int32 uint32_t; - #if SUBHOOK_BITS == 32 - typedef __int32 intptr_t; - typedef unsigned __int32 uintptr_t; - #else - typedef __int64 intptr_t; - typedef unsigned __int64 uintptr_t; - #endif + typedef unsigned __int8 uint8_t; + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + #if SUBHOOK_BITS == 32 + typedef __int32 intptr_t; + typedef unsigned __int32 uintptr_t; + #else + typedef __int64 intptr_t; + typedef unsigned __int64 uintptr_t; + #endif #else - #include <stdint.h> + #include <stdint.h> #endif +#define MAX_INSN_LEN 15 /* maximum length of x86 instruction */ + #define JMP_OPCODE 0xE9 #define PUSH_OPCODE 0x68 #define MOV_OPCODE 0xC7 @@ -59,368 +61,379 @@ #pragma pack(push, 1) struct subhook_jmp32 { - uint8_t opcode; - int32_t offset; + uint8_t opcode; + int32_t offset; }; /* Since AMD64 doesn't support 64-bit direct jumps, we'll push the address * onto the stack, then call RET. */ struct subhook_jmp64 { - uint8_t push_opcode; - uint32_t push_addr; /* lower 32-bits of the address to jump to */ - uint8_t mov_opcode; - uint8_t mov_modrm; - uint8_t mov_sib; - uint8_t mov_offset; - uint32_t mov_addr; /* upper 32-bits of the address to jump to */ - uint8_t ret_opcode; + uint8_t push_opcode; + uint32_t push_addr; /* lower 32-bits of the address to jump to */ + uint8_t mov_opcode; + uint8_t mov_modrm; + uint8_t mov_sib; + uint8_t mov_offset; + uint32_t mov_addr; /* upper 32-bits of the address to jump to */ + uint8_t ret_opcode; }; #pragma pack(pop) -#define MAX_INSN_LEN 15 - static size_t subhook_disasm(void *src, int32_t *reloc_op_offset) { - enum flags { - MODRM = 1, - PLUS_R = 1 << 1, - REG_OPCODE = 1 << 2, - IMM8 = 1 << 3, - IMM16 = 1 << 4, - IMM32 = 1 << 5, - RELOC = 1 << 6 - }; - - static uint8_t prefixes[] = { - 0xF0, 0xF2, 0xF3, - 0x2E, 0x36, 0x3E, 0x26, 0x64, 0x65, - 0x66, /* operand size override */ - 0x67 /* address size override */ - }; - - struct opcode_info { - uint8_t opcode; - uint8_t reg_opcode; - unsigned int flags; - }; - - /* - * Refer to the Intel Developer Manual volumes 2a and 2b for more - * information about instruction formats and encoding: - * - * https://www-ssl.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html - */ - static struct opcode_info opcodes[] = { - /* CALL rel32 */ {0xE8, 0, IMM32 | RELOC}, - /* CALL r/m32 */ {0xFF, 2, MODRM | REG_OPCODE}, - /* JMP rel32 */ {0xE9, 0, IMM32 | RELOC}, - /* JMP r/m32 */ {0xFF, 4, MODRM | REG_OPCODE}, - /* LEA r16,m */ {0x8D, 0, MODRM}, - /* MOV r/m8,r8 */ {0x88, 0, MODRM}, - /* MOV r/m32,r32 */ {0x89, 0, MODRM}, - /* MOV r8,r/m8 */ {0x8A, 0, MODRM}, - /* MOV r32,r/m32 */ {0x8B, 0, MODRM}, - /* MOV r/m16,Sreg */ {0x8C, 0, MODRM}, - /* MOV Sreg,r/m16 */ {0x8E, 0, MODRM}, - /* MOV AL,moffs8 */ {0xA0, 0, IMM8}, - /* MOV EAX,moffs32 */ {0xA1, 0, IMM32}, - /* MOV moffs8,AL */ {0xA2, 0, IMM8}, - /* MOV moffs32,EAX */ {0xA3, 0, IMM32}, - /* MOV r8, imm8 */ {0xB0, 0, PLUS_R | IMM8}, - /* MOV r32, imm32 */ {0xB8, 0, PLUS_R | IMM32}, - /* MOV r/m8, imm8 */ {0xC6, 0, MODRM | REG_OPCODE | IMM8}, - /* MOV r/m32, imm32 */ {0xC7, 0, MODRM | REG_OPCODE | IMM32}, - /* POP r/m32 */ {0x8F, 0, MODRM | REG_OPCODE}, - /* POP r32 */ {0x58, 0, PLUS_R}, - /* PUSH r/m32 */ {0xFF, 6, MODRM | REG_OPCODE}, - /* PUSH r32 */ {0x50, 0, PLUS_R}, - /* PUSH imm8 */ {0x6A, 0, IMM8}, - /* PUSH imm32 */ {0x68, 0, IMM32}, - /* RET */ {0xC3, 0, 0}, - /* RET imm16 */ {0xC2, 0, IMM16}, - /* SUB AL, imm8 */ {0x2C, 0, IMM8}, - /* SUB EAX, imm32 */ {0x2D, 0, IMM32}, - /* SUB r/m8, imm8 */ {0x80, 5, MODRM | REG_OPCODE | IMM8}, - /* SUB r/m32, imm32 */ {0x81, 5, MODRM | REG_OPCODE | IMM8}, - /* SUB r/m32, imm8 */ {0x83, 5, MODRM | REG_OPCODE | IMM8}, - /* SUB r/m32, r32 */ {0x29, 0, MODRM}, - /* SUB r32, r/m32 */ {0x2B, 0, MODRM}, - /* TEST AL, imm8 */ {0xA8, 0, IMM8}, - /* TEST EAX, imm32 */ {0xA9, 0, IMM32}, - /* TEST r/m8, imm8 */ {0xF6, 0, MODRM | REG_OPCODE | IMM8}, - /* TEST r/m32, imm32 */ {0xF7, 0, MODRM | REG_OPCODE | IMM32}, - /* TEST r/m8, r8 */ {0x84, 0, MODRM}, - /* TEST r/m32, r32 */ {0x85, 0, MODRM} - }; - - uint8_t *code = src; - size_t i; - size_t len = 0; - size_t operand_size = 4; - size_t address_size = 4; - uint8_t opcode = 0; - - for (i = 0; i < sizeof(prefixes) / sizeof(*prefixes); i++) { - if (code[len] == prefixes[i]) { - len++; - if (prefixes[i] == 0x66) - operand_size = 2; - if (prefixes[i] == 0x67) - address_size = SUBHOOK_BITS / 8 / 2; - } - } - - for (i = 0; i < sizeof(opcodes) / sizeof(*opcodes); i++) { - int found = 0; - - if (code[len] == opcodes[i].opcode) - found = !(opcodes[i].flags & REG_OPCODE) - || ((code[len + 1] >> 3) & 7) == opcodes[i].reg_opcode; - - if ((opcodes[i].flags & PLUS_R) - && (code[len] & 0xF8) == opcodes[i].opcode) - found = 1; - - if (found) { - opcode = code[len++]; - break; - } - } - - if (opcode == 0) - return 0; - - if (reloc_op_offset != NULL && opcodes[i].flags & RELOC) - *reloc_op_offset = (int32_t)len; /* relative call or jump */ - - if (opcodes[i].flags & MODRM) { - uint8_t modrm = code[len++]; - uint8_t mod = modrm >> 6; - uint8_t rm = modrm & 7; - - if (mod != 3 && rm == 4) - len++; /* for SIB */ + enum flags { + MODRM = 1, + PLUS_R = 1 << 1, + REG_OPCODE = 1 << 2, + IMM8 = 1 << 3, + IMM16 = 1 << 4, + IMM32 = 1 << 5, + RELOC = 1 << 6 + }; + + static uint8_t prefixes[] = { + 0xF0, 0xF2, 0xF3, + 0x2E, 0x36, 0x3E, 0x26, 0x64, 0x65, + 0x66, /* operand size override */ + 0x67 /* address size override */ + }; + + struct opcode_info { + uint8_t opcode; + uint8_t reg_opcode; + unsigned int flags; + }; + + /* + * See the Intel Developer Manual volumes 2a and 2b for more information + * about instruction format and encoding: + * + * https://www-ssl.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html + */ + static struct opcode_info opcodes[] = { + /* CALL rel32 */ {0xE8, 0, IMM32 | RELOC}, + /* CALL r/m32 */ {0xFF, 2, MODRM | REG_OPCODE}, + /* JMP rel32 */ {0xE9, 0, IMM32 | RELOC}, + /* JMP r/m32 */ {0xFF, 4, MODRM | REG_OPCODE}, + /* LEA r16,m */ {0x8D, 0, MODRM}, + /* MOV r/m8,r8 */ {0x88, 0, MODRM}, + /* MOV r/m32,r32 */ {0x89, 0, MODRM}, + /* MOV r8,r/m8 */ {0x8A, 0, MODRM}, + /* MOV r32,r/m32 */ {0x8B, 0, MODRM}, + /* MOV r/m16,Sreg */ {0x8C, 0, MODRM}, + /* MOV Sreg,r/m16 */ {0x8E, 0, MODRM}, + /* MOV AL,moffs8 */ {0xA0, 0, IMM8}, + /* MOV EAX,moffs32 */ {0xA1, 0, IMM32}, + /* MOV moffs8,AL */ {0xA2, 0, IMM8}, + /* MOV moffs32,EAX */ {0xA3, 0, IMM32}, + /* MOV r8, imm8 */ {0xB0, 0, PLUS_R | IMM8}, + /* MOV r32, imm32 */ {0xB8, 0, PLUS_R | IMM32}, + /* MOV r/m8, imm8 */ {0xC6, 0, MODRM | REG_OPCODE | IMM8}, + /* MOV r/m32, imm32 */ {0xC7, 0, MODRM | REG_OPCODE | IMM32}, + /* POP r/m32 */ {0x8F, 0, MODRM | REG_OPCODE}, + /* POP r32 */ {0x58, 0, PLUS_R}, + /* PUSH r/m32 */ {0xFF, 6, MODRM | REG_OPCODE}, + /* PUSH r32 */ {0x50, 0, PLUS_R}, + /* PUSH imm8 */ {0x6A, 0, IMM8}, + /* PUSH imm32 */ {0x68, 0, IMM32}, + /* RET */ {0xC3, 0, 0}, + /* RET imm16 */ {0xC2, 0, IMM16}, + /* SUB AL, imm8 */ {0x2C, 0, IMM8}, + /* SUB EAX, imm32 */ {0x2D, 0, IMM32}, + /* SUB r/m8, imm8 */ {0x80, 5, MODRM | REG_OPCODE | IMM8}, + /* SUB r/m32, imm32 */ {0x81, 5, MODRM | REG_OPCODE | IMM8}, + /* SUB r/m32, imm8 */ {0x83, 5, MODRM | REG_OPCODE | IMM8}, + /* SUB r/m32, r32 */ {0x29, 0, MODRM}, + /* SUB r32, r/m32 */ {0x2B, 0, MODRM}, + /* TEST AL, imm8 */ {0xA8, 0, IMM8}, + /* TEST EAX, imm32 */ {0xA9, 0, IMM32}, + /* TEST r/m8, imm8 */ {0xF6, 0, MODRM | REG_OPCODE | IMM8}, + /* TEST r/m32, imm32 */ {0xF7, 0, MODRM | REG_OPCODE | IMM32}, + /* TEST r/m8, r8 */ {0x84, 0, MODRM}, + /* TEST r/m32, r32 */ {0x85, 0, MODRM} + }; + + uint8_t *code = src; + size_t i; + size_t len = 0; + size_t operand_size = 4; + size_t address_size = 4; + uint8_t opcode = 0; + + for (i = 0; i < sizeof(prefixes) / sizeof(*prefixes); i++) { + if (code[len] == prefixes[i]) { + len++; + if (prefixes[i] == 0x66) { + operand_size = 2; + } + if (prefixes[i] == 0x67) { + address_size = SUBHOOK_BITS / 8 / 2; + } + } + } + + for (i = 0; i < sizeof(opcodes) / sizeof(*opcodes); i++) { + int found = 0; + + if (code[len] == opcodes[i].opcode) { + found = !(opcodes[i].flags & REG_OPCODE) + || ((code[len + 1] >> 3) & 7) == opcodes[i].reg_opcode; + } + + if ((opcodes[i].flags & PLUS_R) + && (code[len] & 0xF8) == opcodes[i].opcode) { + found = 1; + } + + if (found) { + opcode = code[len++]; + break; + } + } + + if (opcode == 0) { + return 0; + } + + if (reloc_op_offset != NULL && opcodes[i].flags & RELOC) { + *reloc_op_offset = (int32_t)len; /* relative call or jump */ + } + + if (opcodes[i].flags & MODRM) { + uint8_t modrm = code[len++]; + uint8_t mod = modrm >> 6; + uint8_t rm = modrm & 7; + + if (mod != 3 && rm == 4) { + len++; /* for SIB */ + } #if SUBHOOK_BITS == 64 - if (reloc_op_offset != NULL && rm == 5) - *reloc_op_offset = (int32_t)len; /* RIP-relative addressing */ + if (reloc_op_offset != NULL && rm == 5) { + *reloc_op_offset = (int32_t)len; /* RIP-relative addressing */ + } #endif - if (mod == 1) - len += 1; /* for disp8 */ - if (mod == 2 || (mod == 0 && rm == 5)) - len += 4; /* for disp32 */ - } - - if (opcodes[i].flags & IMM8) - len += 1; - if (opcodes[i].flags & IMM16) - len += 2; - if (opcodes[i].flags & IMM32) - len += operand_size; - - return len; + if (mod == 1) { + len += 1; /* for disp8 */ + } + if (mod == 2 || (mod == 0 && rm == 5)) { + len += 4; /* for disp32 */ + } + } + + if (opcodes[i].flags & IMM8) { + len += 1; + } + if (opcodes[i].flags & IMM16) { + len += 2; + } + if (opcodes[i].flags & IMM32) { + len += operand_size; + } + + return len; } static size_t subhook_get_jmp_size(subhook_t hook) { #if SUBHOOK_BITS == 64 - if ((hook->options & SUBHOOK_OPTION_64BIT_OFFSET) != 0) - return sizeof(struct subhook_jmp64); + if ((hook->options & SUBHOOK_OPTION_64BIT_OFFSET) != 0) { + return sizeof(struct subhook_jmp64); + } #endif - return sizeof(struct subhook_jmp32); + return sizeof(struct subhook_jmp32); } static void subhook_make_jmp32(void *src, void *dst) { - struct subhook_jmp32 *jmp = (struct subhook_jmp32 *)src; + struct subhook_jmp32 *jmp = (struct subhook_jmp32 *)src; - jmp->opcode = JMP_OPCODE; - jmp->offset = (int32_t)( - (intptr_t)dst - ((intptr_t)src + sizeof(*jmp))); + jmp->opcode = JMP_OPCODE; + jmp->offset = (int32_t)((intptr_t)dst - ((intptr_t)src + sizeof(*jmp))); } #if SUBHOOK_BITS == 64 static void subhook_make_jmp64(void *src, void *dst) { - struct subhook_jmp64 *jmp = (struct subhook_jmp64 *)src; - - jmp->push_opcode = PUSH_OPCODE; - jmp->push_addr = (uint32_t)(uintptr_t)dst; /* truncate */ - jmp->mov_opcode = MOV_OPCODE; - jmp->mov_modrm = MOV_MODRM_BYTE; - jmp->mov_sib = MOV_SIB_BYTE; - jmp->mov_offset = MOV_OFFSET; - jmp->mov_addr = (uint32_t)(((uintptr_t)dst) >> 32); - jmp->ret_opcode = RET_OPCODE; + struct subhook_jmp64 *jmp = (struct subhook_jmp64 *)src; + + jmp->push_opcode = PUSH_OPCODE; + jmp->push_addr = (uint32_t)(uintptr_t)dst; /* truncate */ + jmp->mov_opcode = MOV_OPCODE; + jmp->mov_modrm = MOV_MODRM_BYTE; + jmp->mov_sib = MOV_SIB_BYTE; + jmp->mov_offset = MOV_OFFSET; + jmp->mov_addr = (uint32_t)(((uintptr_t)dst) >> 32); + jmp->ret_opcode = RET_OPCODE; } #endif -static void subhook_make_jmp( - void *src, - void *dst, - subhook_options_t options) -{ +static void subhook_make_jmp(void *src, + void *dst, + subhook_options_t options) { #if SUBHOOK_BITS == 64 - if ((options & SUBHOOK_OPTION_64BIT_OFFSET) != 0) - subhook_make_jmp64(src, dst); + if ((options & SUBHOOK_OPTION_64BIT_OFFSET) != 0) { + subhook_make_jmp64(src, dst); + } #endif - subhook_make_jmp32(src, dst); + subhook_make_jmp32(src, dst); } -static void subhook_make_trampoline( - void *trampoline, - void *src, - size_t jmp_size, - size_t *trampoline_len, - subhook_options_t options) -{ - size_t orig_size = 0; - size_t insn_len; - intptr_t trampoline_addr = (intptr_t)trampoline; - intptr_t src_addr = (intptr_t)src; - - assert(trampoline_len != NULL); - - /* Determine how many bytes of original code needs to be copied over - * to the trampoline. - */ - while (orig_size < jmp_size) { - int32_t reloc_op_offset = 0; - - insn_len = - subhook_disasm((void *)(src_addr + orig_size), &reloc_op_offset); - - if (insn_len == 0) - return; - - /* If the operand is a relative address, such as found in calls or - * jumps, it needs to be relocated because the original code and the - * trampoline reside at different locations in memory. - */ - if (reloc_op_offset > 0) { - /* Calculate how far our trampoline is from the source and change - * the address accordingly. - */ - int32_t moved_by = (int32_t)(trampoline_addr - src_addr); - int32_t *op = (int32_t *)( - trampoline_addr + orig_size + reloc_op_offset); - *op -= moved_by; - } - - orig_size += insn_len; - } - - *trampoline_len = orig_size + jmp_size; - - /* Now build the trampoline. It consists of orig_size bytes of original - * code + jmp_size bytes for a jump back. - */ - memcpy(trampoline, src, orig_size); - subhook_make_jmp(trampoline, (void *)(src_addr + orig_size), options); +static void subhook_make_trampoline(void *trampoline, + void *src, + size_t jmp_size, + size_t *trampoline_len, + subhook_options_t options) { + size_t orig_size = 0; + size_t insn_len; + intptr_t trampoline_addr = (intptr_t)trampoline; + intptr_t src_addr = (intptr_t)src; + + assert(trampoline_len != NULL); + + /* Determine how many bytes of original code needs to be copied over + * to the trampoline. + */ + while (orig_size < jmp_size) { + int32_t reloc_op_offset = 0; + + insn_len = + subhook_disasm((void *)(src_addr + orig_size), &reloc_op_offset); + + if (insn_len == 0) { + return; + } + + /* If the operand is a relative address, such as found in calls or + * jumps, it needs to be relocated because the original code and the + * trampoline reside at different locations in memory. + */ + if (reloc_op_offset > 0) { + /* Calculate how far our trampoline is from the source and change + * the address accordingly. + */ + int32_t moved_by = (int32_t)(trampoline_addr - src_addr); + int32_t *op = (int32_t *)(trampoline_addr + orig_size + reloc_op_offset); + *op -= moved_by; + } + + orig_size += insn_len; + } + + *trampoline_len = orig_size + jmp_size; + + /* Now build the trampoline. It consists of orig_size bytes of original + * code + jmp_size bytes for a jump back. + */ + memcpy(trampoline, src, orig_size); + subhook_make_jmp(trampoline, (void *)(src_addr + orig_size), options); } -SUBHOOK_EXPORT subhook_t SUBHOOK_API subhook_new( - void *src, - void *dst, - subhook_options_t options) -{ - subhook_t hook; - - if ((hook = malloc(sizeof(*hook))) == NULL) - return NULL; - - hook->installed = 0; - hook->src = src; - hook->dst = dst; - hook->options = options; - hook->jmp_size = subhook_get_jmp_size(hook); - hook->trampoline_size = hook->jmp_size + MAX_INSN_LEN - 1; - hook->trampoline_len = 0; - - if ((hook->code = malloc(hook->jmp_size)) == NULL) { - free(hook); - return NULL; - } - - memcpy(hook->code, hook->src, hook->jmp_size); - - if ((hook->trampoline = calloc(1, hook->trampoline_size)) == NULL) { - free(hook->code); - free(hook); - return NULL; - } - - if (subhook_unprotect(hook->src, hook->jmp_size) == NULL - || subhook_unprotect(hook->trampoline, hook->trampoline_size) == NULL) - { - free(hook->trampoline); - free(hook->code); - free(hook); - return NULL; - } - - subhook_make_trampoline( - hook->trampoline, - hook->src, - hook->jmp_size, - &hook->trampoline_len, - hook->options); - - if (hook->trampoline_len == 0) { - free(hook->trampoline); - hook->trampoline = NULL; - } - - return hook; +SUBHOOK_EXPORT subhook_t SUBHOOK_API subhook_new(void *src, + void *dst, + subhook_options_t options) { + subhook_t hook; + + if ((hook = malloc(sizeof(*hook))) == NULL) { + return NULL; + } + + hook->installed = 0; + hook->src = src; + hook->dst = dst; + hook->options = options; + hook->jmp_size = subhook_get_jmp_size(hook); + hook->trampoline_size = hook->jmp_size + MAX_INSN_LEN - 1; + hook->trampoline_len = 0; + + if ((hook->code = malloc(hook->jmp_size)) == NULL) { + free(hook); + return NULL; + } + + memcpy(hook->code, hook->src, hook->jmp_size); + + if ((hook->trampoline = calloc(1, hook->trampoline_size)) == NULL) { + free(hook->code); + free(hook); + return NULL; + } + + if (subhook_unprotect(hook->src, hook->jmp_size) == NULL + || subhook_unprotect(hook->trampoline, hook->trampoline_size) == NULL) + { + free(hook->trampoline); + free(hook->code); + free(hook); + return NULL; + } + + subhook_make_trampoline( + hook->trampoline, + hook->src, + hook->jmp_size, + &hook->trampoline_len, + hook->options); + + if (hook->trampoline_len == 0) { + free(hook->trampoline); + hook->trampoline = NULL; + } + + return hook; } SUBHOOK_EXPORT void SUBHOOK_API subhook_free(subhook_t hook) { - free(hook->trampoline); - free(hook->code); - free(hook); + free(hook->trampoline); + free(hook->code); + free(hook); } SUBHOOK_EXPORT int SUBHOOK_API subhook_install(subhook_t hook) { - if (hook->installed) - return -EINVAL; + if (hook->installed) { + return -EINVAL; + } - subhook_make_jmp(hook->src, hook->dst, hook->options); - hook->installed = 1; + subhook_make_jmp(hook->src, hook->dst, hook->options); + hook->installed = 1; - return 0; + return 0; } SUBHOOK_EXPORT int SUBHOOK_API subhook_remove(subhook_t hook) { - if (!hook->installed) - return -EINVAL; + if (!hook->installed) { + return -EINVAL; + } - memcpy(hook->src, hook->code, hook->jmp_size); - hook->installed = 0; + memcpy(hook->src, hook->code, hook->jmp_size); + hook->installed = 0; - return 0; + return 0; } SUBHOOK_EXPORT void *SUBHOOK_API subhook_read_dst(void *src) { - struct subhook_jmp32 *maybe_jmp32 = (struct subhook_jmp32 *)src; + struct subhook_jmp32 *maybe_jmp32 = (struct subhook_jmp32 *)src; #if SUBHOOK_BITS == 64 - struct subhook_jmp64 *maybe_jmp64 = (struct subhook_jmp64 *)src; + struct subhook_jmp64 *maybe_jmp64 = (struct subhook_jmp64 *)src; #endif - if (maybe_jmp32->opcode == JMP_OPCODE) - return (void *)( - maybe_jmp32->offset + (uintptr_t)src + sizeof(*maybe_jmp32)); + if (maybe_jmp32->opcode == JMP_OPCODE) { + return (void *)( + maybe_jmp32->offset + (uintptr_t)src + sizeof(*maybe_jmp32)); + } #if SUBHOOK_BITS == 64 - if (maybe_jmp64->push_opcode == PUSH_OPCODE - && maybe_jmp64->mov_opcode == MOV_OPCODE - && maybe_jmp64->mov_modrm == MOV_MODRM_BYTE - && maybe_jmp64->mov_sib == MOV_SIB_BYTE - && maybe_jmp64->mov_offset == MOV_OFFSET - && maybe_jmp64->ret_opcode == RET_OPCODE) - return (void *)( - maybe_jmp64->push_addr & ((uintptr_t)maybe_jmp64->mov_addr << 32)); + if (maybe_jmp64->push_opcode == PUSH_OPCODE + && maybe_jmp64->mov_opcode == MOV_OPCODE + && maybe_jmp64->mov_modrm == MOV_MODRM_BYTE + && maybe_jmp64->mov_sib == MOV_SIB_BYTE + && maybe_jmp64->mov_offset == MOV_OFFSET + && maybe_jmp64->ret_opcode == RET_OPCODE) { + return (void *)( + maybe_jmp64->push_addr & ((uintptr_t)maybe_jmp64->mov_addr << 32)); + } #endif - return NULL; + return NULL; } |