JNI: intercepting native methods outputs

╄→гoц情女王★ 提交于 2020-01-15 07:06:27

问题


currently i am working on a project where i need to intercept the results of java native method calls for further analysis.

There are multiple ways to achieve that but the way of my choice is: at native binding time, re-bind the addresses of java native methods to the address of my own wrapper-function, which would call the initial native function by itself and then return its result while intercepting the returned variable. The wrapper function should be generic, meaning it would handle the return-type and parameters in a right manner.

In the code below, nativeIntInterceptor is wrapping int returning functions:

typedef jint (JNICALL * intNativeCall) (JNIEnv *env, jclass clazz, jobject obj);

struct binding{

public:
    jmethodID methId;
    intNativeCall initialMethodAddress;
    void* newMethodAddress;
    char* name;
    char* sig;

binding(jmethodID methId, void* methodAddress, char* name, char* sig){
    printf("creating binding for %s ith signature %s \n", name , sig);
    this->methId = methId;
    this->name = name;
    this->sig=sig;
    this->initialMethodAddress = (intNativeCall) methodAddress;
    this->newMethodAddress =(void*) &nativeIntInterceptor;
}

jint JNICALL nativeIntInterceptor(JNIEnv *env, jclass clazz, jobject obj)
{
    printf("EXECUTING %s WITH SIGNATURE %s \n",name,sig);
    jint  returnVal = initialMethodAddress(env, clazz, obj);
    printf("RESULT WAS %d ...\n",returnVal);
    return returnVal;
}

};

Now, in my agent, at native binding time, I need to initialize the binding objects in order to bind native functions to the wrapper functions in those objects. Here is the code:

void JNICALL
NativeMethodBind(jvmtiEnv *jvmti_env,
    JNIEnv* jni_env,
    jthread thread,
    jmethodID method,
    void* address,
    void** new_address_ptr)
{
char* name_ptr;
char* signature_ptr;
char* generic_ptr;
jvmti_env->GetMethodName(method, &name_ptr, &signature_ptr, &generic_ptr);


if (strstr(signature_ptr, ")V") != NULL) {
    //      printf("VOID RETURNING METHOD\n");

}else if(strstr(signature_ptr, ")I") != NULL){
    // binding jint returning method

    binding* b = new binding(method, address, name_ptr, signature_ptr);
    bindings.push_back(*b);

    *new_address_ptr = b->newMethodAddress;
}
}

At this point when I the native method is called, the wrapper function ( nativeIntInterceptor ) gets called correctly. However, it doesnt have access to all these local variables and just prints me

EXECUTING (null) WITH SIGNATURE (null)

Basically my wrapper function, when called through a pointer, cannot see the object's local variables and thus cannot call the original native function... Is there a way to resolve this? How can i provide my wrapper function with all the required infos?

来源:https://stackoverflow.com/questions/43089692/jni-intercepting-native-methods-outputs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!