简体   繁体   中英

C getting functions address

In my project i am implementing a JNI agent which would rebind all java native methods to my customized methods in my custom ".c" file. So since JNI agent binds native methods in runtime, i will be only talking about runtime solution.

When JNI binds native methods, following function gets called:

void JNICALL NativeMethodBind(jvmtiEnv *jvmti_env,
    JNIEnv* jni_env,
    jthread thread,
    jmethodID method,
    void* address,
    void** new_address_ptr)

At this point a java method gets bound to address in void* address unless you put something into void** new_address_ptr . Thus, in order to rebind a curtain method , i just need to overwrite the new_address_ptr - variable.

Now, i want to rebind the functions to function-addresses in my custom .c file which contains several hundreds of different methods. And this is where i am stuck. While having the .c file and the string names of the functions, how do i get the addresses of the correspondin functions in my .c file?

I am running the project on windows64 machine with gcc 4.9.1

What you are trying to achieve can be done using a structure if you can edit your custom *.c file then you can have a structure with two members like:

struct func_details{
     char func_name[20];
     void (*custom_func)(void);
};

Then declare an array of structure:

struct func_details my_functions[] = {
         {"function1 name as string", respective_func1}
         {"function2 name as string", respective_func2}
         {"function3 name as string", respective_func3}
};

Now you can do a strcmp() in a loop like

for(i=0; i<3; i++)
{
   if(strcmp(function_string, my_functions[i].func_name) == 0)
   {
      if(my_functions[i].custom_func != NULL)
          /*Call you method to update the address with my_functions[i].custom_func*/
   }
}

Hope, I have answered your question.

Is this what you need?

#include <stdio.h>

#define MAX_FN 1024
#define SYMBOL_ENTRY(i, name) do { \
        _fn_table[i].fn_name = #name; \
        _fn_table[i].fn_addr = &name; \
} while(0)

struct fn_table {
        const char *fn_name;
        void *fn_addr;
};

static struct fn_table _fn_table[MAX_FN] = { };

static void test0(void) {
        printf("%s [%d]\n", __func__, __LINE__);
}

static void test1(int a) {
        printf("%s [%d] %d\n", __func__, __LINE__, a);
}

static struct fn_table _fn_table_statically_initialization[] = {
        { "test0", &test0 },
        { "test1", &test1 }
};


int main(int argc, char *argv[]) {
        // build table
        SYMBOL_ENTRY(0, test0);
        SYMBOL_ENTRY(1, test1);

        // let's print out
        printf("%p\n", _fn_table[0].fn_addr);
        printf("%p\n", _fn_table[1].fn_addr);
        printf("%p\n", _fn_table_statically_initialization[0].fn_addr);

        // try to call
        if (_fn_table[0].fn_addr) {
                void (*fn)(void) = _fn_table[0].fn_addr;

                fn();
        }

        if (_fn_table[1].fn_addr) {
                void (*fn)(int) = _fn_table[1].fn_addr;

                fn(12);
        }

        return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM