📄 java_crw_demo.c
字号:
case JVM_OPC_jsr: case JVM_OPC_goto: case JVM_OPC_ifeq: case JVM_OPC_ifge: case JVM_OPC_ifgt: case JVM_OPC_ifle: case JVM_OPC_iflt: case JVM_OPC_ifne: case JVM_OPC_if_icmpeq: case JVM_OPC_if_icmpne: case JVM_OPC_if_icmpge: case JVM_OPC_if_icmpgt: case JVM_OPC_if_icmple: case JVM_OPC_if_icmplt: case JVM_OPC_if_acmpeq: case JVM_OPC_if_acmpne: case JVM_OPC_ifnull: case JVM_OPC_ifnonnull: widened = mi->widening[pos]; delta = readS2(ci); if (widened == 0) { new_delta = method_code_map(mi,pos+delta) - new_pos; if ((new_delta < -32768) || (new_delta > 32767)) { switch (opcode) { case JVM_OPC_jsr: case JVM_OPC_goto: widen(mi, pos, 2); break; default: widen(mi, pos, 5); break; } return 0; } } break; case JVM_OPC_jsr_w: case JVM_OPC_goto_w: (void)readU4(ci); break; default: instr_len = opcode_length(ci, opcode); skip(ci, instr_len-1); break; } } return 1;}static void write_instruction(MethodImage *mi) { CrwClassImage * ci; ClassOpcode opcode; ByteOffset new_code_len; int pos; int new_pos; CRW_ASSERT_MI(mi); ci = mi->ci; pos = input_code_offset(mi); new_pos = method_code_map(mi,pos); new_code_len = mi->injections[pos].len; if (new_code_len > 0) { write_bytes(ci, (void*)mi->injections[pos].code, new_code_len); } opcode = readU1(ci); if (opcode == JVM_OPC_wide) { ClassOpcode wopcode; writeU1(ci, opcode); wopcode = copyU1(ci); /* lvIndex not used */ (void)copyU2(ci); verify_opc_wide(ci, wopcode); if ( wopcode==JVM_OPC_iinc ) { (void)copyU1(ci); (void)copyU1(ci); } } else { ClassOpcode new_opcode; int header; int newHeader; int low; int high; int i; int npairs; int widened; int instr_len; int delta; int new_delta; switch (opcode) { case JVM_OPC_tableswitch: header = NEXT_4BYTE_BOUNDARY(pos); newHeader = NEXT_4BYTE_BOUNDARY(new_pos); skip(ci, header - (pos+1)); delta = readU4(ci); new_delta = method_code_map(mi,pos+delta) - new_pos; low = readU4(ci); high = readU4(ci); writeU1(ci, opcode); for (i = new_pos+1; i < newHeader; ++i) { writeU1(ci, 0); } writeU4(ci, new_delta); writeU4(ci, low); writeU4(ci, high); for (i = low; i <= high; ++i) { delta = readU4(ci); new_delta = method_code_map(mi,pos+delta) - new_pos; writeU4(ci, new_delta); } break; case JVM_OPC_lookupswitch: header = NEXT_4BYTE_BOUNDARY(pos); newHeader = NEXT_4BYTE_BOUNDARY(new_pos); skip(ci, header - (pos+1)); delta = readU4(ci); new_delta = method_code_map(mi,pos+delta) - new_pos; npairs = readU4(ci); writeU1(ci, opcode); for (i = new_pos+1; i < newHeader; ++i) { writeU1(ci, 0); } writeU4(ci, new_delta); writeU4(ci, npairs); for (i = 0; i< npairs; ++i) { unsigned match = readU4(ci); delta = readU4(ci); new_delta = method_code_map(mi,pos+delta) - new_pos; writeU4(ci, match); writeU4(ci, new_delta); } break; case JVM_OPC_jsr: case JVM_OPC_goto: case JVM_OPC_ifeq: case JVM_OPC_ifge: case JVM_OPC_ifgt: case JVM_OPC_ifle: case JVM_OPC_iflt: case JVM_OPC_ifne: case JVM_OPC_if_icmpeq: case JVM_OPC_if_icmpne: case JVM_OPC_if_icmpge: case JVM_OPC_if_icmpgt: case JVM_OPC_if_icmple: case JVM_OPC_if_icmplt: case JVM_OPC_if_acmpeq: case JVM_OPC_if_acmpne: case JVM_OPC_ifnull: case JVM_OPC_ifnonnull: widened = mi->widening[pos]; delta = readS2(ci); new_delta = method_code_map(mi,pos+delta) - new_pos; new_opcode = opcode; if (widened == 0) { writeU1(ci, opcode); writeU2(ci, new_delta); } else if (widened == 2) { switch (opcode) { case JVM_OPC_jsr: new_opcode = JVM_OPC_jsr_w; break; case JVM_OPC_goto: new_opcode = JVM_OPC_goto_w; break; default: CRW_FATAL(ci, "unexpected opcode"); break; } writeU1(ci, new_opcode); writeU4(ci, new_delta); } else if (widened == 5) { switch (opcode) { case JVM_OPC_ifeq: new_opcode = JVM_OPC_ifne; break; case JVM_OPC_ifge: new_opcode = JVM_OPC_iflt; break; case JVM_OPC_ifgt: new_opcode = JVM_OPC_ifle; break; case JVM_OPC_ifle: new_opcode = JVM_OPC_ifgt; break; case JVM_OPC_iflt: new_opcode = JVM_OPC_ifge; break; case JVM_OPC_ifne: new_opcode = JVM_OPC_ifeq; break; case JVM_OPC_if_icmpeq: new_opcode = JVM_OPC_if_icmpne; break; case JVM_OPC_if_icmpne: new_opcode = JVM_OPC_if_icmpeq; break; case JVM_OPC_if_icmpge: new_opcode = JVM_OPC_if_icmplt; break; case JVM_OPC_if_icmpgt: new_opcode = JVM_OPC_if_icmple; break; case JVM_OPC_if_icmple: new_opcode = JVM_OPC_if_icmpgt; break; case JVM_OPC_if_icmplt: new_opcode = JVM_OPC_if_icmpge; break; case JVM_OPC_if_acmpeq: new_opcode = JVM_OPC_if_acmpne; break; case JVM_OPC_if_acmpne: new_opcode = JVM_OPC_if_acmpeq; break; case JVM_OPC_ifnull: new_opcode = JVM_OPC_ifnonnull; break; case JVM_OPC_ifnonnull: new_opcode = JVM_OPC_ifnull; break; default: CRW_FATAL(ci, "Unexpected opcode"); break; } writeU1(ci, new_opcode); /* write inverse branch */ writeU2(ci, 3 + 5); /* beyond if and goto_w */ writeU1(ci, JVM_OPC_goto_w); /* add a goto_w */ writeU4(ci, new_delta-3); /* write new and wide delta */ } else { CRW_FATAL(ci, "Unexpected widening"); } break; case JVM_OPC_jsr_w: case JVM_OPC_goto_w: delta = readU4(ci); new_delta = method_code_map(mi,pos+delta) - new_pos; writeU1(ci, opcode); writeU4(ci, new_delta); break; default: instr_len = opcode_length(ci, opcode); writeU1(ci, opcode); copy(ci, instr_len-1); break; } }}static void method_inject_and_write_code(MethodImage *mi) { ByteCode bytecodes[LARGEST_INJECTION+1]; ByteOffset len; CRW_ASSERT_MI(mi); /* Do injections */ rewind_to_beginning_of_input_bytecodes(mi); len = entry_injection_code(mi, bytecodes, (int)sizeof(bytecodes)); if ( len > 0 ) { int pos; pos = 0; inject_bytecodes(mi, pos, bytecodes, len); /* Adjust pos 0 to map to new pos 0, you never want to * jump into this entry code injection. So the new pos 0 * will be past this entry_injection_code(). */ adjust_map(mi, pos, len); /* Inject before behavior */ } while (input_code_offset(mi) < mi->code_len) { inject_for_opcode(mi); } /* Adjust instructions */ rewind_to_beginning_of_input_bytecodes(mi); while (input_code_offset(mi) < mi->code_len) { if (!adjust_instruction(mi)) { rewind_to_beginning_of_input_bytecodes(mi); } } /* Write new instructions */ rewind_to_beginning_of_input_bytecodes(mi); while (input_code_offset(mi) < mi->code_len) { write_instruction(mi); }}static void copy_attribute(CrwClassImage *ci) { int len; (void)copyU2(ci); len = copyU4(ci); copy(ci, len);}static void copy_attributes(CrwClassImage *ci) { unsigned i; unsigned count; count = copyU2(ci); for (i = 0; i < count; ++i) { copy_attribute(ci); }}static void copy_all_fields(CrwClassImage *ci){ unsigned i; unsigned count; count = copyU2(ci); for (i = 0; i < count; ++i) { /* access, name, descriptor */ copy(ci, 6); copy_attributes(ci); }}static voidwrite_line_table(MethodImage *mi){ unsigned i; unsigned count; CrwClassImage * ci; CRW_ASSERT_MI(mi); ci = mi->ci; (void)copyU4(ci); count = copyU2(ci); for(i=0; i<count; i++) { ByteOffset start_pc; ByteOffset new_start_pc; start_pc = readU2(ci); if ( start_pc == 0 ) { new_start_pc = 0; /* Don't skip entry injection code. */ } else { new_start_pc = method_code_map(mi, start_pc); } writeU2(ci, new_start_pc); (void)copyU2(ci); }}/* Used for LocalVariableTable and LocalVariableTypeTable attributes */static voidwrite_var_table(MethodImage *mi){ unsigned i; unsigned count; CrwClassImage * ci; CRW_ASSERT_MI(mi); ci = mi->ci; (void)copyU4(ci); count = copyU2(ci); for(i=0; i<count; i++) { ByteOffset start_pc; ByteOffset new_start_pc; ByteOffset length; ByteOffset new_length; ByteOffset end_pc; ByteOffset new_end_pc; start_pc = readU2(ci); length = readU2(ci); if ( start_pc == 0 ) { new_start_pc = 0; /* Don't skip entry injection code. */ } else { new_start_pc = method_code_map(mi, start_pc); } end_pc = start_pc + length; new_end_pc = method_code_map(mi, end_pc); new_length = new_end_pc - new_start_pc; writeU2(ci, new_start_pc); writeU2(ci, new_length); (void)copyU2(ci); (void)copyU2(ci); (void)copyU2(ci); }}/* The uoffset field is u2 or u4 depending on the code_len. * Note that the code_len is likely changing, so be careful here. */static unsignedreadUoffset(MethodImage *mi){ if ( mi->code_len > 65535 ) { return readU4(mi->ci); } return readU2(mi->ci);}static voidwriteUoffset(MethodImage *mi, unsigned val){ if ( mi->new_code_len > 65535 ) { writeU4(mi->ci, val); } writeU2(mi->ci, val);}static unsignedcopyUoffset(MethodImage *mi){ unsigned uoffset; uoffset = readUoffset(mi); writeUoffset(mi, uoffset); return uoffset;}/* Copy over verification_type_info structure */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -