diff options
author | Willian Henrique <wsimanbrazil@yahoo.com.br> | 2022-02-12 23:25:04 -0300 |
---|---|---|
committer | Michael Smith <mikesmiffy128@gmail.com> | 2022-03-19 04:57:00 +0000 |
commit | e2b8151f6eca6c91b45e0d715b1533cde274eaa5 (patch) | |
tree | 2f337bcf9e2f8f2392c5869f05f4a8bc551dc11f | |
parent | dc317d53ccf74257c12c1d73c4265ec2a9b25d24 (diff) |
Fix hook_inline() breaking after a single call
Committer note: I, mike, am a big dumb idiot. Thanks, Bill.
-rw-r--r-- | src/hook.c | 6 | ||||
-rw-r--r-- | test/hook.test.c | 16 |
2 files changed, 20 insertions, 2 deletions
@@ -1,5 +1,6 @@ /* * Copyright © 2021 Michael Smith <mikesmiffy128@gmail.com> + * Copyright © 2022 Willian Henrique <wsimanbrazil@yahoo.com.br> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -58,10 +59,11 @@ void *hook_inline(void *func_, void *target) { len += ud_insn_len(&udis); } // for simplicity, just bump alloc the trampoline. no need to free anyway - if (nexttrampoline - trampolines > len + 6) goto nospc; + if (nexttrampoline - trampolines > sizeof(trampolines) - len - 6) goto nospc; uchar *trampoline = (uchar *)InterlockedExchangeAdd( (volatile long *)&nexttrampoline, len + 6); - if (trampoline - trampolines > len + 6) { // avoid TOCTOU + // avoid TOCTOU + if (trampoline - trampolines > sizeof(trampolines) - len - 6) { nospc: con_warn("hook_inline: out of trampoline space\n"); return 0; } diff --git a/test/hook.test.c b/test/hook.test.c index 831fbf6..50e07a8 100644 --- a/test/hook.test.c +++ b/test/hook.test.c @@ -25,6 +25,12 @@ static int (*orig_some_function)(int, int); static int some_hook(int a, int b) { return orig_some_function(a, b) + 5; } +__attribute__((noinline)) +static int other_function(int a, int b) { return a - b; } +static int (*orig_other_function)(int, int); +static int other_hook(int a, int b) { + return orig_other_function(a, b) + 5; +} TEST("Inline hooks should be able to wrap the original function", 0) { orig_some_function = hook_inline(&some_function, &some_hook); @@ -39,6 +45,16 @@ TEST("Inline hooks should be removable again", 0) { return some_function(5, 5) == 10; } +TEST("Multiple functions should be able to be inline hooked at once", 0) { + orig_some_function = hook_inline(&some_function, &some_hook); + if (!orig_some_function) return false; + + orig_other_function = hook_inline(&other_function, &other_hook); + if (!orig_other_function) return false; + + return other_function(5, 5) == 5; +} + #endif // vi: sw=4 ts=4 noet tw=80 cc=80 |