📄 dismantlebytecode.java
字号:
switchOffsets[o] = byteStream.readInt(); i += 4; } sortByOffset(switchOffsets, switchLabels); } else if (opcode == WIDE) { opcodeIsWide = true; opcode = byteStream.readUnsignedByte(); i++; switch (opcode) { case ILOAD: case FLOAD: case ALOAD: case LLOAD: case DLOAD: case ISTORE: case FSTORE: case ASTORE: case LSTORE: case DSTORE: case RET: registerOperand = byteStream.readUnsignedShort(); i += 2; break; case IINC: registerOperand = byteStream.readUnsignedShort(); i += 2; intConstant = byteStream.readShort(); i += 2; break; default: throw new IllegalStateException("bad wide bytecode: " + OPCODE_NAMES[opcode]); } } else throw new IllegalStateException("bad unpredicatable bytecode: " + OPCODE_NAMES[opcode]); } else { if (byteStreamArgCount < 0) throw new IllegalStateException("bad length for bytecode: " + OPCODE_NAMES[opcode]); for (int k = 0; k < TYPE_OF_OPERANDS[opcode].length; k++) { int v; int t = TYPE_OF_OPERANDS[opcode][k]; int m = MEANING_OF_OPERANDS[opcode][k]; boolean unsigned = (m == M_CP || m == M_R || m == M_UINT); switch (t) { case T_BYTE: if (unsigned) v = byteStream.readUnsignedByte(); else v = byteStream.readByte(); /* System.out.print("Read byte " + v); System.out.println(" with meaning" + m); */ i++; break; case T_SHORT: if (unsigned) v = byteStream.readUnsignedShort(); else v = byteStream.readShort(); i += 2; break; case T_INT: v = byteStream.readInt(); i += 4; break; default: throw new IllegalStateException(); } switch (m) { case M_BR: branchOffset = v; branchTarget = v + PC; branchFallThrough = i; break; case M_CP: constantRefOperand = getConstantPool().getConstant(v); if (constantRefOperand instanceof ConstantClass) { ConstantClass clazz = (ConstantClass) constantRefOperand; classConstantOperand = getStringFromIndex(clazz.getNameIndex()); dottedClassConstantOperand = replaceSlashesWithDots(classConstantOperand); } if (constantRefOperand instanceof ConstantInteger) intConstant = ((ConstantInteger) constantRefOperand).getBytes(); else if (constantRefOperand instanceof ConstantLong) longConstant = ((ConstantLong) constantRefOperand).getBytes(); else if (constantRefOperand instanceof ConstantFloat) floatConstant = ((ConstantFloat) constantRefOperand).getBytes(); else if (constantRefOperand instanceof ConstantDouble) doubleConstant = ((ConstantDouble) constantRefOperand).getBytes(); else if (constantRefOperand instanceof ConstantString) { int s = ((ConstantString) constantRefOperand).getStringIndex(); stringConstantOperand = getStringFromIndex(s); } else if (constantRefOperand instanceof ConstantCP) { ConstantCP cp = (ConstantCP) constantRefOperand; ConstantClass clazz = (ConstantClass) getConstantPool().getConstant(cp.getClassIndex()); classConstantOperand = getStringFromIndex(clazz.getNameIndex()); dottedClassConstantOperand = replaceSlashesWithDots(classConstantOperand); ConstantNameAndType sig = (ConstantNameAndType) getConstantPool().getConstant(cp.getNameAndTypeIndex()); nameConstantOperand = getStringFromIndex(sig.getNameIndex()); sigConstantOperand = getStringFromIndex(sig.getSignatureIndex()); dottedSigConstantOperand = replaceSlashesWithDots(sigConstantOperand); refConstantOperand = null; } break; case M_R: registerOperand = v; break; case M_UINT: case M_INT: intConstant = v; } } } switch (opcode) { case IINC: isRegisterLoad = true; isRegisterStore = true; break; case ILOAD_0: case ILOAD_1: case ILOAD_2: case ILOAD_3: registerOperand = opcode - ILOAD_0; isRegisterLoad = true; break; case ALOAD_0: case ALOAD_1: case ALOAD_2: case ALOAD_3: registerOperand = opcode - ALOAD_0; isRegisterLoad = true; break; case FLOAD_0: case FLOAD_1: case FLOAD_2: case FLOAD_3: registerOperand = opcode - FLOAD_0; isRegisterLoad = true; break; case DLOAD_0: case DLOAD_1: case DLOAD_2: case DLOAD_3: registerOperand = opcode - DLOAD_0; isRegisterLoad = true; break; case LLOAD_0: case LLOAD_1: case LLOAD_2: case LLOAD_3: registerOperand = opcode - LLOAD_0; isRegisterLoad = true; break; case ILOAD: case FLOAD: case ALOAD: case LLOAD: case DLOAD: isRegisterLoad = true; break; case ISTORE_0: case ISTORE_1: case ISTORE_2: case ISTORE_3: registerOperand = opcode - ISTORE_0; isRegisterStore = true; break; case ASTORE_0: case ASTORE_1: case ASTORE_2: case ASTORE_3: registerOperand = opcode - ASTORE_0; isRegisterStore = true; break; case FSTORE_0: case FSTORE_1: case FSTORE_2: case FSTORE_3: registerOperand = opcode - FSTORE_0; isRegisterStore = true; break; case DSTORE_0: case DSTORE_1: case DSTORE_2: case DSTORE_3: registerOperand = opcode - DSTORE_0; isRegisterStore = true; break; case LSTORE_0: case LSTORE_1: case LSTORE_2: case LSTORE_3: registerOperand = opcode - LSTORE_0; isRegisterStore = true; break; case ISTORE: case FSTORE: case ASTORE: case LSTORE: case DSTORE: isRegisterStore = true; break; } switch (opcode) { case ILOAD: case FLOAD: case ALOAD: case LLOAD: case DLOAD: // registerKind = opcode - ILOAD; break; case ISTORE: case FSTORE: case ASTORE: case LSTORE: case DSTORE: // registerKind = opcode - ISTORE; break; case RET: // registerKind = R_REF; break; case GETSTATIC: case PUTSTATIC: refFieldIsStatic = true; break; case GETFIELD: case PUTFIELD: refFieldIsStatic = false; break; } nextPC = i; beforeOpcode(opcode); sawOpcode(opcode); afterOpcode(opcode); if (opcode == TABLESWITCH) { sawInt(switchLow); sawInt(switchHigh); int prevOffset = i - PC; for (int o = 0; o <= switchHigh - switchLow; o++) { sawBranchTo(switchOffsets[o] + PC); sawOffset(switchOffsets[o] - prevOffset); prevOffset = switchOffsets[o]; } sawOffset(defaultSwitchOffset - prevOffset); sawBranchTo(defaultSwitchOffset + PC); } else if (opcode == LOOKUPSWITCH) { sawInt(switchOffsets.length); int prevOffset = i - PC; for (int o = 0; o < switchOffsets.length; o++) { sawBranchTo(switchOffsets[o] + PC); prevOffset = switchOffsets[o]; sawInt(switchLabels[o]); } sawOffset(defaultSwitchOffset - prevOffset); sawBranchTo(defaultSwitchOffset + PC); } else for (int k = 0; k < TYPE_OF_OPERANDS[opcode].length; k++) { int m = MEANING_OF_OPERANDS[opcode][k]; switch (m) { case M_BR: sawBranchTo(branchOffset + PC); if (branchOffset > 0) sawOffset(branchOffset - (i - PC)); else sawOffset(branchOffset); break; case M_CP: if (constantRefOperand instanceof ConstantInteger) sawInt(intConstant); else if (constantRefOperand instanceof ConstantLong) sawLong(longConstant); else if (constantRefOperand instanceof ConstantFloat) sawFloat(floatConstant); else if (constantRefOperand instanceof ConstantDouble) sawDouble(doubleConstant); else if (constantRefOperand instanceof ConstantString) sawString(stringConstantOperand); else if (constantRefOperand instanceof ConstantFieldref) sawField(); else if (constantRefOperand instanceof ConstantMethodref) sawMethod(); else if (constantRefOperand instanceof ConstantInterfaceMethodref) sawIMethod(); else if (constantRefOperand instanceof ConstantClass) sawClass(); break; case M_R: sawRegister(registerOperand); break; case M_INT: sawInt(intConstant); break; } } } } catch (IOException e) { System.out.println("Got IO Exception:"); e.printStackTrace(); } try { byteStream.close(); } catch (IOException e) { assert false; } } public void sawDouble(double seen) { } public void sawFloat(float seen) { } public void sawRegister(int r) { } public void sawInt(int seen) { } public void sawLong(long seen) { } public void sawBranchTo(int seen) { } public void sawOffset(int seen) { } public void beforeOpcode(int seen) {} public void afterOpcode(int seen) {} public void sawOpcode(int seen) { } public void sawString(String seen) { } public void sawField() { } public void sawMethod() { } public void sawIMethod() { } public void sawClass() { } static private NumberFormat formatter = NumberFormat.getIntegerInstance(); static { formatter.setMinimumIntegerDigits(4); formatter.setGroupingUsed(false); } public void printOpCode( int seen) { System.out.print(" TestingGround: [" + formatter.format(getPC()) + "] " + OPCODE_NAMES[seen]); if ((seen == INVOKEVIRTUAL) || (seen == INVOKESPECIAL) || (seen == INVOKEINTERFACE) || (seen == INVOKESTATIC)) System.out.print(" " + getClassConstantOperand() + "." + getNameConstantOperand() + " " + getSigConstantOperand()); else if (seen == LDC || seen == LDC_W || seen == LDC2_W) { Constant c = getConstantRefOperand(); if (c instanceof ConstantString) System.out.print(" \"" + getStringConstantOperand() + "\""); else if (c instanceof ConstantClass) System.out.print(" " + getClassConstantOperand()); else System.out.print(" " + c); } else if ((seen == ALOAD) || (seen == ASTORE)) System.out.print(" " + getRegisterOperand()); else if ((seen == GOTO) || (seen == GOTO_W) || (seen == IF_ACMPEQ) || (seen == IF_ACMPNE) || (seen == IF_ICMPEQ) || (seen == IF_ICMPGE) || (seen == IF_ICMPGT) || (seen == IF_ICMPLE) || (seen == IF_ICMPLT) || (seen == IF_ICMPNE) || (seen == IFEQ) || (seen == IFGE) || (seen == IFGT) || (seen == IFLE) || (seen == IFLT) || (seen == IFNE) || (seen == IFNONNULL) || (seen == IFNULL)) System.out.print(" " + getBranchTarget()); else if ((seen == NEW) || (seen == INSTANCEOF)) System.out.print(" " + getClassConstantOperand()); else if ((seen == TABLESWITCH) || (seen == LOOKUPSWITCH)) { System.out.print(" ["); int switchPC = getPC(); int[] offsets = getSwitchOffsets(); for (int offset : offsets) { System.out.print((switchPC + offset) + ","); } System.out.print((switchPC + getDefaultSwitchOffset()) + "]"); } System.out.println(); } /** * @return Returns the nextPC. */ public int getNextPC() { return nextPC; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -