0xAK
0xAK

Reputation: 229

C MACRO to compare function names against predefined list of names

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

Answers (1)

n. m. could be an AI
n. m. could be an AI

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

Related Questions