JVMTI使用方案-C++

来源:互联网 发布:远程木马监控软件 编辑:程序博客网 时间:2024/05/20 07:20

参考网址:

http://download.oracle.com/javase/1.5.0/docs/guide/jvmti/jvmti.html#onload

http://192.9.162.55/developer/technicalArticles/J2SE/jvm_ti/

http://kenwublog.com/jvmti-tutorial-a-simple-agent

 

JDK安装文件:jdk-6u26-windows-i586.exe。


1、Java端调用

启动方式:随java进程启动时,自动载入共享库。

参数设置:

java-agentlib:<agent-lib-name>=<options> Sample

java-agentpath:<path-to-agent>=<options> Sample

 

本例使用:-agentlib:F:\jars\MCEncrypt


2、C++Dll生成

dll名称:MCEncrypt.dll。

dll类型:MFC extension DLL。

 

头文件目录:

D:\Program files\Java\jdk1.6.0_26\include\win32

D:\Program files\Java\jdk1.6.0_26\include\

 

DLL导出接口为:

①    启动加载接口:Agent_OnLoad。

②    退出卸载接口:Agent_OnUnload。

 

Agent_OnLoad中注册ClassFileLoadHook(class文件加载)响应事件。

实现接口为cbClassFileLoadHook。


实现代码如下:

#include <jvmti.h>

 

void JNICALL cbClassFileLoadHook(jvmtiEnv*jvmti_env,

                                 JNIEnv*jni_env,

                                 jclassclass_being_redefined,

                                 jobjectloader,

                                 const char*name,

                                 jobjectprotection_domain,

                                 jintclass_data_len,

                                 const unsignedchar* class_data,

                                 jint*new_class_data_len,

                                 unsignedchar** new_class_data)

{

   printf("class name=%s\n", name);

}

 

JNIEXPORT jint JNICALL

Agent_OnLoad(JavaVM *vm, char *options,void *reserved)

{

   jvmtiEnv              *jvmti;

   jvmtiError             error;

   // Create the JVM TI environment (jvmti).

   jint result = vm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);

   if (result != JNI_OK) {

       printf("ERROR: Unable to access JVMTI!\n");

       return 1;

    }

 

   jvmtiCapabilities capabilities;

   // Clear the capabilities structure and set the ones you need.

   (void)memset(&capabilities,0, sizeof(capabilities));

   capabilities.can_generate_all_class_hook_events  = 1;

   capabilities.can_tag_objects                     = 1;

   capabilities.can_generate_object_free_events     = 1;

   capabilities.can_get_source_file_name            = 1;

   capabilities.can_get_line_numbers                = 1;

   capabilities.can_generate_vm_object_alloc_events = 1;

 

   // Request these capabilities for this JVM TI environment.

   error = jvmti->AddCapabilities(&capabilities);

   if (error != JVMTI_ERROR_NONE) {

       printf("ERROR: Unable to AddCapabilities JVMTI!\n");

       return error;

    }

 

   jvmtiEventCallbacks callbacks;

   // Clear the callbacks structure and set the ones you want.

   (void)memset(&callbacks,0, sizeof(callbacks));

   callbacks.ClassFileLoadHook = &cbClassFileLoadHook;

 

   error = jvmti->SetEventCallbacks(&callbacks,(jint)sizeof(callbacks));

   if (error!=JVMTI_ERROR_NONE)

    {

       printf("ERROR: Unable to SetEventCallbacks JVMTI!\n");

       return error;

    }

 

   // For each of the above callbacks, enable this event.

   error = jvmti->SetEventNotificationMode(JVMTI_ENABLE,

       JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,

       (jthread)NULL);

   if (error!=JVMTI_ERROR_NONE)

    {

       printf("ERROR: Unable to SetEventNotificationMode JVMTI!\n");

       return error;

    }

 

   return JNI_OK; // Indicates to the VM that the agent loaded OK.

}

 

JNIEXPORT void JNICALL Agent_OnUnload(JavaVM*vm)

{

 

}

 

注意:C++分配空间时,需采用JVM提供接口,这样分配的空间与平台无关。

封装分配空间方法:

jvmtiEnv* m_pJvmTI;//JVM环境指针,在Agent_OnLoad中调用vm->GetEnv获取

void MCAllocate(int nSize, unsigned char** mem_ptr)
{
    if (m_pJvmTI != NULL)
    {
        jvmtiError eFlag = m_pJvmTI->Allocate(nSize, mem_ptr);
    }
    else
    {
        *mem_ptr = new unsigned char[nSize];        
    }

    memset(*mem_ptr, 0, nSize);
}

原创粉丝点击