diff options
author | Zeex <zeex@rocketmail.com> | 2016-08-28 12:14:10 +0600 |
---|---|---|
committer | Zeex <zeex@rocketmail.com> | 2016-08-28 12:48:21 +0600 |
commit | cd97522462d473831f08a29b102ec7a7aeb473da (patch) | |
tree | 0c263858e63ede80b11012ed0e070027330c1b58 | |
parent | c86c12aff818236c29cab72d2f568253a74944c3 (diff) | |
download | subhook-cd97522462d473831f08a29b102ec7a7aeb473da.zip subhook-cd97522462d473831f08a29b102ec7a7aeb473da.tar.gz subhook-cd97522462d473831f08a29b102ec7a7aeb473da.tar.bz2 |
Fix relocation bug
It was introduced during latest refactoring (along with like 10 other bugs).
-rw-r--r-- | subhook_x86.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/subhook_x86.c b/subhook_x86.c index 7b38a25..b8cf81d 100644 --- a/subhook_x86.c +++ b/subhook_x86.c @@ -335,6 +335,12 @@ static int subhook_make_trampoline(void *trampoline, return -EINVAL; } + /* Copy this instruction to the trampoline. + */ + memcpy((void *)(trampoline_addr + orig_size), + (void *)(src_addr + orig_size), + insn_len); + /* 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. @@ -343,9 +349,9 @@ static int subhook_make_trampoline(void *trampoline, /* 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 offset = (int32_t)(trampoline_addr - src_addr); int32_t *op = (int32_t *)(trampoline_addr + orig_size + reloc_op_offset); - *op -= moved_by; + *op -= offset; } orig_size += insn_len; @@ -353,10 +359,9 @@ static int subhook_make_trampoline(void *trampoline, *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. + /* Insert the final jump. It goes back to the original code at + * src + orig_size. */ - memcpy(trampoline, src, orig_size); return subhook_make_jmp((void *)(trampoline_addr + orig_size), (void *)(src_addr + orig_size), options); |