📄 java_crw_demo.c
字号:
writeU2(ci, value); return value;}static unsigned copyU4(CrwClassImage *ci) { unsigned value; value = readU4(ci); writeU4(ci, value); return value;}static void copy(CrwClassImage *ci, unsigned count) { CRW_ASSERT_CI(ci); if ( ci->output != NULL ) { (void)memcpy(ci->output+ci->output_position, ci->input+ci->input_position, count); ci->output_position += count; } ci->input_position += count; CRW_ASSERT_CI(ci);}static void skip(CrwClassImage *ci, unsigned count) { CRW_ASSERT_CI(ci); ci->input_position += count;}static voidread_bytes(CrwClassImage *ci, void *bytes, unsigned count) { CRW_ASSERT_CI(ci); CRW_ASSERT(ci, bytes!=NULL); (void)memcpy(bytes, ci->input+ci->input_position, count); ci->input_position += count;}static void write_bytes(CrwClassImage *ci, void *bytes, unsigned count) { CRW_ASSERT_CI(ci); CRW_ASSERT(ci, bytes!=NULL); if ( ci->output != NULL ) { (void)memcpy(ci->output+ci->output_position, bytes, count); ci->output_position += count; }}static void random_writeU2(CrwClassImage *ci, CrwPosition pos, unsigned val) { CrwPosition save_position; CRW_ASSERT_CI(ci); save_position = ci->output_position; ci->output_position = pos; writeU2(ci, val); ci->output_position = save_position;}static void random_writeU4(CrwClassImage *ci, CrwPosition pos, unsigned val) { CrwPosition save_position; CRW_ASSERT_CI(ci); save_position = ci->output_position; ci->output_position = pos; writeU4(ci, val); ci->output_position = save_position;}/* ----------------------------------------------------------------- *//* Constant Pool handling functions. */static voidfillin_cpool_entry(CrwClassImage *ci, CrwCpoolIndex i, ClassConstant tag, unsigned int index1, unsigned int index2, const char *ptr, int len){ CRW_ASSERT_CI(ci); CRW_ASSERT(ci, i > 0 && i < ci->cpool_count_plus_one); ci->cpool[i].tag = tag; ci->cpool[i].index1 = index1; ci->cpool[i].index2 = index2; ci->cpool[i].ptr = ptr; ci->cpool[i].len = (unsigned short)len;}static CrwCpoolIndex add_new_cpool_entry(CrwClassImage *ci, ClassConstant tag, unsigned int index1, unsigned int index2, const char *str, int len){ CrwCpoolIndex i; char *utf8 = NULL; CRW_ASSERT_CI(ci); i = ci->cpool_count_plus_one++; /* NOTE: This implementation does not automatically expand the * constant pool table beyond the expected number needed * to handle this particular CrwTrackerInterface injections. * See MAXIMUM_NEW_CPOOL_ENTRIES */ CRW_ASSERT(ci, ci->cpool_count_plus_one < ci->cpool_max_elements ); writeU1(ci, tag); switch (tag) { case JVM_CONSTANT_Class: writeU2(ci, index1); break; case JVM_CONSTANT_String: writeU2(ci, index1); break; case JVM_CONSTANT_Fieldref: case JVM_CONSTANT_Methodref: case JVM_CONSTANT_InterfaceMethodref: case JVM_CONSTANT_Integer: case JVM_CONSTANT_Float: case JVM_CONSTANT_NameAndType: writeU2(ci, index1); writeU2(ci, index2); break; case JVM_CONSTANT_Long: case JVM_CONSTANT_Double: writeU4(ci, index1); writeU4(ci, index2); ci->cpool_count_plus_one++; CRW_ASSERT(ci, ci->cpool_count_plus_one < ci->cpool_max_elements ); break; case JVM_CONSTANT_Utf8: CRW_ASSERT(ci, len==(len & 0xFFFF)); writeU2(ci, len); write_bytes(ci, (void*)str, len); utf8 = (char*)duplicate(ci, str, len); break; default: CRW_FATAL(ci, "Unknown constant"); break; } fillin_cpool_entry(ci, i, tag, index1, index2, (const char *)utf8, len); CRW_ASSERT(ci, i > 0 && i < ci->cpool_count_plus_one); return i;}static CrwCpoolIndexadd_new_class_cpool_entry(CrwClassImage *ci, const char *class_name) { CrwCpoolIndex name_index; CrwCpoolIndex class_index; int len; CRW_ASSERT_CI(ci); CRW_ASSERT(ci, class_name!=NULL); len = (int)strlen(class_name); name_index = add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, class_name, len); class_index = add_new_cpool_entry(ci, JVM_CONSTANT_Class, name_index, 0, NULL, 0); return class_index;}static CrwCpoolIndexadd_new_method_cpool_entry(CrwClassImage *ci, CrwCpoolIndex class_index, const char *name, const char *descr) { CrwCpoolIndex name_index; CrwCpoolIndex descr_index; CrwCpoolIndex name_type_index; int len; CRW_ASSERT_CI(ci); CRW_ASSERT(ci, name!=NULL); CRW_ASSERT(ci, descr!=NULL); len = (int)strlen(name); name_index = add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, name, len); len = (int)strlen(descr); descr_index = add_new_cpool_entry(ci, JVM_CONSTANT_Utf8, len, 0, descr, len); name_type_index = add_new_cpool_entry(ci, JVM_CONSTANT_NameAndType, name_index, descr_index, NULL, 0); return add_new_cpool_entry(ci, JVM_CONSTANT_Methodref, class_index, name_type_index, NULL, 0);}static CrwConstantPoolEntry cpool_entry(CrwClassImage *ci, CrwCpoolIndex c_index) { CRW_ASSERT_CI(ci); CRW_ASSERT(ci, c_index > 0 && c_index < ci->cpool_count_plus_one); return ci->cpool[c_index];}static void cpool_setup(CrwClassImage *ci){ CrwCpoolIndex i; CrwPosition cpool_output_position; int count_plus_one; CRW_ASSERT_CI(ci); cpool_output_position = ci->output_position; count_plus_one = copyU2(ci); CRW_ASSERT(ci, count_plus_one>1); ci->cpool_max_elements = count_plus_one+MAXIMUM_NEW_CPOOL_ENTRIES; ci->cpool = (CrwConstantPoolEntry*)allocate_clean(ci, (int)((ci->cpool_max_elements)*sizeof(CrwConstantPoolEntry))); ci->cpool_count_plus_one = (CrwCpoolIndex)count_plus_one; /* Index zero not in class file */ for (i = 1; i < count_plus_one; ++i) { CrwCpoolIndex ipos; ClassConstant tag; unsigned int index1; unsigned int index2; unsigned len; char * utf8; ipos = i; index1 = 0; index2 = 0; len = 0; utf8 = NULL; tag = copyU1(ci); switch (tag) { case JVM_CONSTANT_Class: index1 = copyU2(ci); break; case JVM_CONSTANT_String: index1 = copyU2(ci); break; case JVM_CONSTANT_Fieldref: case JVM_CONSTANT_Methodref: case JVM_CONSTANT_InterfaceMethodref: case JVM_CONSTANT_Integer: case JVM_CONSTANT_Float: case JVM_CONSTANT_NameAndType: index1 = copyU2(ci); index2 = copyU2(ci); break; case JVM_CONSTANT_Long: case JVM_CONSTANT_Double: index1 = copyU4(ci); index2 = copyU4(ci); ++i; /* // these take two CP entries - duh! */ break; case JVM_CONSTANT_Utf8: len = copyU2(ci); index1 = (unsigned short)len; utf8 = (char*)allocate(ci, len+1); read_bytes(ci, (void*)utf8, len); utf8[len] = 0; write_bytes(ci, (void*)utf8, len); break; default: CRW_FATAL(ci, "Unknown constant"); break; } fillin_cpool_entry(ci, ipos, tag, index1, index2, (const char *)utf8, len); } if (ci->call_name != NULL || ci->return_name != NULL) { if ( ci->number != (ci->number & 0x7FFF) ) { ci->class_number_index = add_new_cpool_entry(ci, JVM_CONSTANT_Integer, (ci->number>>16) & 0xFFFF, ci->number & 0xFFFF, NULL, 0); } } if ( ci->tclass_name != NULL ) { ci->tracker_class_index = add_new_class_cpool_entry(ci, ci->tclass_name); } if (ci->obj_init_name != NULL) { ci->object_init_tracker_index = add_new_method_cpool_entry(ci, ci->tracker_class_index, ci->obj_init_name, ci->obj_init_sig); } if (ci->newarray_name != NULL) { ci->newarray_tracker_index = add_new_method_cpool_entry(ci, ci->tracker_class_index, ci->newarray_name, ci->newarray_sig); } if (ci->call_name != NULL) { ci->call_tracker_index = add_new_method_cpool_entry(ci, ci->tracker_class_index, ci->call_name, ci->call_sig); } if (ci->return_name != NULL) { ci->return_tracker_index = add_new_method_cpool_entry(ci, ci->tracker_class_index, ci->return_name, ci->return_sig); } random_writeU2(ci, cpool_output_position, ci->cpool_count_plus_one);}/* ----------------------------------------------------------------- *//* Functions that create the bytecodes to inject */static ByteOffsetpush_pool_constant_bytecodes(ByteCode *bytecodes, CrwCpoolIndex index){ ByteOffset nbytes = 0; if ( index == (index&0x7F) ) { bytecodes[nbytes++] = (ByteCode)JVM_OPC_ldc; } else { bytecodes[nbytes++] = (ByteCode)JVM_OPC_ldc_w; bytecodes[nbytes++] = (ByteCode)((index >> 8) & 0xFF); } bytecodes[nbytes++] = (ByteCode)(index & 0xFF); return nbytes;}static ByteOffsetpush_short_constant_bytecodes(ByteCode *bytecodes, unsigned number){ ByteOffset nbytes = 0; if ( number <= 5 ) { bytecodes[nbytes++] = (ByteCode)(JVM_OPC_iconst_0+number); } else if ( number == (number&0x7F) ) { bytecodes[nbytes++] = (ByteCode)JVM_OPC_bipush; bytecodes[nbytes++] = (ByteCode)(number & 0xFF); } else { bytecodes[nbytes++] = (ByteCode)JVM_OPC_sipush; bytecodes[nbytes++] = (ByteCode)((number >> 8) & 0xFF); bytecodes[nbytes++] = (ByteCode)(number & 0xFF); } return nbytes;}static ByteOffsetinjection_template(MethodImage *mi, ByteCode *bytecodes, ByteOffset max_nbytes, CrwCpoolIndex method_index){ CrwClassImage * ci; ByteOffset nbytes = 0; unsigned max_stack; int add_dup; int add_aload; int push_cnum; int push_mnum; ci = mi->ci; CRW_ASSERT(ci, bytecodes!=NULL); if ( method_index == 0 ) { return 0; } if ( method_index == ci->newarray_tracker_index) { max_stack = mi->max_stack + 1; add_dup = JNI_TRUE; add_aload = JNI_FALSE; push_cnum = JNI_FALSE; push_mnum = JNI_FALSE; } else if ( method_index == ci->object_init_tracker_index) { max_stack = mi->max_stack + 1; add_dup = JNI_FALSE; add_aload = JNI_TRUE; push_cnum = JNI_FALSE; push_mnum = JNI_FALSE; } else { max_stack = mi->max_stack + 2; add_dup = JNI_FALSE; add_aload = JNI_FALSE; push_cnum = JNI_TRUE; push_mnum = JNI_TRUE; } if ( add_dup ) { bytecodes[nbytes++] = (ByteCode)JVM_OPC_dup; } if ( add_aload ) { bytecodes[nbytes++] = (ByteCode)JVM_OPC_aload_0; } if ( push_cnum ) { if ( ci->number == (ci->number & 0x7FFF) ) { nbytes += push_short_constant_bytecodes(bytecodes+nbytes, ci->number); } else { CRW_ASSERT(ci, ci->class_number_index!=0); nbytes += push_pool_constant_bytecodes(bytecodes+nbytes, ci->class_number_index); } } if ( push_mnum ) { nbytes += push_short_constant_bytecodes(bytecodes+nbytes, mi->number); } bytecodes[nbytes++] = (ByteCode)JVM_OPC_invokestatic; bytecodes[nbytes++] = (ByteCode)(method_index >> 8); bytecodes[nbytes++] = (ByteCode)method_index; bytecodes[nbytes] = 0; CRW_ASSERT(ci, nbytes<max_nbytes); /* Make sure the new max_stack is appropriate */ if ( max_stack > mi->new_max_stack ) { mi->new_max_stack = max_stack; } return nbytes;}/* Called to create injection code at entry to a method */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -