コード例 #1
0
/* Callback for JVMTI_EVENT_CLASS_FILE_LOAD_HOOK */
static void JNICALL
cbClassFileLoadHook(jvmtiEnv *jvmti, JNIEnv* env,
                    jclass class_being_redefined, jobject loader,
                    const char* name, jobject protection_domain,
                    jint class_data_len, const unsigned char* class_data,
                    jint* new_class_data_len, unsigned char** new_class_data)
{
    enter_critical_section(jvmti);
    {
        /* It's possible we get here right after VmDeath event, be careful */
        if ( !gdata->vm_is_dead ) {

            *new_class_data_len = 0;
            *new_class_data     = NULL;

            /* The tracker class itself? */
            if ( interested((char*)name, "", gdata->include, gdata->exclude)
                    &&  strcmp(name, STRING(MTRACE_class)) != 0 ) {
                jint           cnum;
                int            system_class;
                unsigned char *new_image;
                long           new_length;
                ClassInfo     *cp;

                /* Get unique number for every class file image loaded */
                cnum = gdata->ccount++;

                /* Save away class information */
                if ( gdata->classes == NULL ) {
                    gdata->classes = (ClassInfo*)malloc(
                                         gdata->ccount*sizeof(ClassInfo));
                } else {
                    gdata->classes = (ClassInfo*)
                                     realloc((void*)gdata->classes,
                                             gdata->ccount*sizeof(ClassInfo));
                }
                if ( gdata->classes == NULL ) {
                    fatal_error("ERROR: Out of malloc memory\n");
                }
                cp           = gdata->classes + cnum;
                cp->name     = (const char *)strdup(name);
                cp->calls    = 0;
                cp->mcount   = 0;
                cp->methods  = NULL;

                /* Is it a system class? If the class load is before VmStart
                *   then we will consider it a system class that should
                	 *   be treated carefully. (See java_crw_demo)
                	 */
                system_class = 0;
                if ( !gdata->vm_is_started ) {
                    system_class = 1;
                }

                new_image = NULL;
                new_length = 0;

                /* Call the class file reader/write demo code */
                java_crw_demo(cnum,
                              name,
                              class_data,
                              class_data_len,
                              system_class,
                              STRING(MTRACE_class), "L" STRING(MTRACE_class) ";",
                              STRING(MTRACE_entry), "(II)V",
                              STRING(MTRACE_exit), "(II)V",
                              NULL, NULL,
                              NULL, NULL,
                              &new_image,
                              &new_length,
                              NULL,
                              &mnum_callbacks);

                /* If we got back a new class image, return it back as "the"
                 *   new class image. This must be JVMTI Allocate space.
                 */
                if ( new_length > 0 ) {
                    unsigned char *jvmti_space;

                    jvmti_space = (unsigned char *)allocate(jvmti, (jint)new_length);
                    (void)memcpy((void*)jvmti_space, (void*)new_image, (int)new_length);
                    *new_class_data_len = (jint)new_length;
                    *new_class_data     = jvmti_space; /* VM will deallocate */
                }

                /* Always free up the space we get from java_crw_demo() */
                if ( new_image != NULL ) {
                    (void)free((void*)new_image); /* Free malloc() space with free() */
                }
            }
        }
    }
    exit_critical_section(jvmti);
}
コード例 #2
0
/* Callback for JVMTI_EVENT_CLASS_FILE_LOAD_HOOK */
static void JNICALL
cbClassFileLoadHook(jvmtiEnv *jvmti, JNIEnv* env,
                jclass class_being_redefined, jobject loader,
                const char* name, jobject protection_domain,
                jint class_data_len, const unsigned char* class_data,
                jint* new_class_data_len, unsigned char** new_class_data)
{
    enterCriticalSection(jvmti); {
        /* It's possible we get here right after VmDeath event, be careful */
        if ( !gdata->vmDead ) {

            const char * classname;

            /* Name can be NULL, make sure we avoid SEGV's */
            if ( name == NULL ) {
                classname = java_crw_demo_classname(class_data, class_data_len,
                                NULL);
                if ( classname == NULL ) {
                    fatal_error("ERROR: No classname in classfile\n");
                }
            } else {
                classname = strdup(name);
                if ( classname == NULL ) {
                    fatal_error("ERROR: Ran out of malloc() space\n");
                }
            }

            *new_class_data_len = 0;
            *new_class_data     = NULL;

            /* The tracker class itself? */
            if ( strcmp(classname, STRING(HEAP_TRACKER_class)) != 0 ) {
                jint           cnum;
                int            systemClass;
                unsigned char *newImage;
                long           newLength;

                /* Get number for every class file image loaded */
                cnum = gdata->ccount++;

                /* Is it a system class? If the class load is before VmStart
                 *   then we will consider it a system class that should
                 *   be treated carefully. (See java_crw_demo)
                 */
                systemClass = 0;
                if ( !gdata->vmStarted ) {
                    systemClass = 1;
                }

                newImage = NULL;
                newLength = 0;

                /* Call the class file reader/write demo code */
                java_crw_demo(cnum,
                    classname,
                    class_data,
                    class_data_len,
                    systemClass,
                    STRING(HEAP_TRACKER_class),
                    "L" STRING(HEAP_TRACKER_class) ";",
                    NULL, NULL,
                    NULL, NULL,
                    STRING(HEAP_TRACKER_newobj), "(Ljava/lang/Object;)V",
                    STRING(HEAP_TRACKER_newarr), "(Ljava/lang/Object;)V",
                    &newImage,
                    &newLength,
                    NULL,
                    NULL);

                /* If we got back a new class image, return it back as "the"
                 *   new class image. This must be JVMTI Allocate space.
                 */
                if ( newLength > 0 ) {
                    unsigned char *jvmti_space;

                    jvmti_space = (unsigned char *)allocate(jvmti, (jint)newLength);
                    (void)memcpy((void*)jvmti_space, (void*)newImage, (int)newLength);
                    *new_class_data_len = (jint)newLength;
                    *new_class_data     = jvmti_space; /* VM will deallocate */
                }

                /* Always free up the space we get from java_crw_demo() */
                if ( newImage != NULL ) {
                    (void)free((void*)newImage); /* Free malloc() space with free() */
                }
            }
        
            (void)free((void*)classname);
        }
    } exitCriticalSection(jvmti);
}
コード例 #3
0
int
main(int argc, char **argv)
{
    int i;
    unsigned class_number = 0x0FEED000;
    int obj_watch;
    int call_sites;
    int ret_sites;

    obj_watch = 0;
    call_sites = 0;
    ret_sites = 0;

    if ( argc < 3 ) {
        char buf[256];
        (void)snprintf(buf, sizeof(buf), "Usage: %s input_file output_file", argv[0]);
        ERROR(buf);
    }
    
    for(i=1; i<argc; i++) {
        FILE *fin;
        FILE *fout;
        const unsigned char *file_image;
        int file_len;
        unsigned char *new_file_image;
        long new_file_len;
        
	if ( strcmp(argv[i],"-n")==0 ) {
	    obj_watch = 1;
            continue;
        } else if ( strcmp(argv[i], "-c")==0 ) {
	    call_sites = 1;
            continue;
        } else if ( strcmp(argv[i], "-r")==0 ) {
	    ret_sites = 1;
            continue;
        }

        fin = fopen(argv[i], "r");
        if ( fin == NULL ) {
            file_error(argv[i], "Cannot open file");
        }
        (void)fseek(fin, 0, SEEK_END);
        file_len = ftell(fin);
        if ( file_len<=0 ) {
            file_error(argv[i], "File has 0 size");
        }
        (void)fseek(fin, 0, SEEK_SET);
        file_image = (const unsigned char *)malloc((size_t)file_len);
        assert(file_image!=NULL);
        if ( fread((void*)file_image, 1, (size_t)file_len, fin)!=(size_t)file_len) {
            file_error(argv[i], "File read failed");
        }
        
        java_crw_demo(class_number++, 
	    NULL, 
	    file_image, 
	    file_len, 
	    0,
            "sun/tools/hprof/Tracker",
            "Lsun/tools/hprof/Tracker;",
            call_sites?"CallSite":NULL,
            call_sites?"(II)V":NULL,
            ret_sites?"ReturnSite":NULL,
            ret_sites?"(II)V":NULL,
            obj_watch?"ObjectInit":NULL,
            obj_watch?"(Ljava/lang/Object;)V":NULL,
            obj_watch?"NewArray":NULL,
            obj_watch?"(Ljava/lang/Object;)V":NULL,
	    &new_file_image,
	    &new_file_len,
            &error, 
	    &mnums);
        
        fout = fopen(argv[i+1], "w");
        if ( fout == NULL ) {
            file_error(argv[i+1], "Cannot create file");
        }
        if ( new_file_len > 0 ) {
            if ( fwrite(new_file_image, 1, (size_t)new_file_len, fout)!=(size_t)new_file_len ) {
                file_error(argv[i+1], "File write failed");
            }
            (void)printf("Processed file %s to %s\n", argv[i], argv[i+1]);
        } else {
            if ( fwrite(file_image, 1, file_len, fout)!=(size_t)file_len ) {
                file_error(argv[i+1], "File write failed");
            }
            (void)printf("Duplicated file %s to %s (no injections)\n", argv[i], argv[i+1]);
        }

        (void)fclose(fout);

        free((void*)file_image);
	if ( new_file_image != NULL ) {
	    free(new_file_image);
	}

        i++;
    }
    return error_code;
}
コード例 #4
0
ファイル: instrumentation.cpp プロジェクト: dkrikun/eraser
        /*
         * Instrument classfile to invoke new object & array creation hooks in <cinit> of java.lang.Object
         */
        void instrument_classfile( jvmtiEnv* jvmti, JNIEnv* jni
                                 , jclass class_being_redefined, jobject loader
                                 , const char* name, jobject protection_domain
                                 , jint class_data_len, const unsigned char* class_data
                                 , jint* new_class_data_len, unsigned char** new_class_data )
        {
                static size_t classfile_index;

                // determine classname
                const char* classname = get_classname( name, class_data, class_data_len );

                std::string internal_classname("L");
                internal_classname += classname;
                internal_classname += ";";
                xpr::sregex thread_filter = xpr::sregex::compile( eraser::agent::instance()->thread_filter_regex_ );
                bool is_thread = xpr::regex_match( internal_classname, thread_filter );
                bool obj_match = strcmp(classname, "java/lang/Object") == 0;

                if( !( is_thread || obj_match )  )
                {
                	free((void*)classname);
                	return;
                }


                logger::instance()->level(200) << classname
                		<< std::boolalpha << " is_thread= " << is_thread
                		<< " obj_match= " << obj_match
                		<< std::endl;

                // prevent self-instrumentation
                if( strcmp(classname, PROXY_CLASS) == 0 )
                { 
                        free((void*)classname);
                        return;
                }
                
                unsigned char* new_image = 0;
                long new_length = 0;
                *new_class_data_len = 0;
                *new_class_data = 0;
                
                classfile_index++;

                bool is_system_class = ( agent::instance()->phase() < JVMTI_PHASE_START );
                
                // go instrument
                if( obj_match )
					java_crw_demo( classfile_index, classname
								 , class_data, class_data_len
								 , is_system_class
								 , PROXY_CLASS
								 , "L" PROXY_CLASS ";"
								 , 0, 0
								 , 0, 0
								 , NEW_OBJ_METHOD, "(Ljava/lang/Object;)V"
								 , NEW_ARR_METHOD, "(Ljava/lang/Object;)V"
								 , &new_image
								 , &new_length
								 , 0, 0 );
                else if( is_thread )
					java_crw_demo( classfile_index, classname
								 , class_data, class_data_len
								 , is_system_class
								 , PROXY_CLASS
								 , "L" PROXY_CLASS ";"
								 , MONITOR_ENTER, "(Ljava/lang/Object;)V"
								 , MONITOR_EXIT, "(Ljava/lang/Object;)V"
								 , 0, 0
								 , 0, 0
								 , &new_image
								 , &new_length
								 , 0, 0 );
                else
                	BOOST_ASSERT( false );
                
                // memcpy transformed classfile to jvmti allocated memory
                if( new_length > 0 )
                {
#					if defined( ERASER_DEBUG )
                	std::ofstream class_dump( "dump", std::ofstream::binary );
                    class_dump.write( (const char*)new_image, (std::streamsize)new_length );
                    class_dump.close();
#					endif

                    unsigned char *jvmtispace = (unsigned char *)allocate( jvmti, (jint)new_length );
                    memcpy( (void*)jvmtispace, (void*)new_image, new_length );
                
                    *new_class_data_len = new_length;
                    *new_class_data = jvmtispace;
                }
                

                if( new_image != 0 )
                    free(new_image); 
                free((void*)classname);
        }