Reputation: 229
I have some functions I'm hooking on windows (around 200), and I want to add some generic functionality to all of them. Based on a flag I'm giving my application, to either hook or not to hook some predefined functions.
What I had in mind would be something like this:
#define SHOULD_CHECK_STOP_MONITOR (1 == Configuration.dwShouldMonitor)
#define MY_CHECK_MACRO(f) (if(SHOULD_CHECK_STOP_MONITOR && /* What do I do here? */))
void MyHookedFunctionName_A(...)
{
if(!MY_CHECK_MACRO(__FUNCTION__))
goto lbl_Cleanup;
/* rest of code logic */
lbl_Cleanup:
return ...;
}
void MyHookedFunctionName_B(...)
{
if(!MY_CHECK_MACRO(__FUNCTION__))
goto lbl_Cleanup;
/* rest of code logic */
lbl_Cleanup:
return ...;
}
The result I want to achieve is a precompiled logic, not to be executed on dynamic runtime, but on compilation. where if 1 == Configuration.dwShouldMonitor
is configured to be True
, it will check the rest of the logic, where I would have some sort of predefined list of function names ["MyHookedFunctionName_A", "MyHookedFunctionName_C", "MyHookedFunctionName_D"]
and the Macro would know whether to return False
or True
based on function name. So in this example, MyHookedFunctionName_B
would execute, while MyHookedFunctionName_A
would not due to the predefined list on compilation.
Is something like that even possible? for a "Sophisticated" logic based on function name and compare it to predefined strings function names?
edit 2019.09.15: I'm adding here what I'd like the result to be after precompilation logic
void MyHookedFunctionName_A(...)
{
if(!(1 == Configuration.dwShouldMonitor && False))
goto lbl_Cleanup;
...
}
void MyHookedFunctionName_B(...)
{
if(!(1 == Configuration.dwShouldMonitor && True))
goto lbl_Cleanup;
...
}
Where True
or False
were generated at compile time based on the function string names
Upvotes: 0
Views: 150
Reputation: 120079
Many compilers should be able to optimise your "runtime" check away completely.
Here is a simple program to illustrate the point.
#include <string.h>
#include <stdio.h>
static const char* func_list[] = { "foo", "bar" };
static inline int is_in_list(const char* f) {
for (int i = 0; i < sizeof(func_list)/sizeof(func_list[0]); ++i)
if (strcmp(f, func_list[i]) == 0)
return 1;
return 0;
}
#define HOOKME if (SHOULD_HOOK && is_in_list(__func__)) return;
void foo() {
HOOKME;
printf("foo\n");
}
void bar() {
HOOKME;
printf("bar\n");
}
void baz() {
HOOKME;
printf("baz\n");
}
int main()
{
foo();
bar();
baz();
}
Compile it with -DSHOULD_HOOK=1 and -O2, and a good compiler probably will make foo
and bar
disappear.
foo:
ret
bar:
ret
.LC0:
.string "baz"
baz:
mov edi, OFFSET FLAT:.LC0
jmp puts
main:
sub rsp, 8
xor eax, eax
call baz
xor eax, eax
add rsp, 8
ret
Not all compilers are able to do that. Choose your tools wisely. Demo.
Upvotes: 1