public JavaInstruction(int offset, JavaOpCode opcode, JavaOperandData operands) { _offset = offset; _opcode = opcode; _operands = operands; }
public static DisassembledMethod Disassemble(byte[] bytecode) { Contract.Requires<ArgumentNullException>(bytecode != null, "bytecode"); List<JavaInstruction> instructions = new List<JavaInstruction>(); List<SwitchData> switchData = new List<SwitchData>(); for (int i = 0; i < bytecode.Length; /*increment in loop*/) { int instructionStart = i; JavaOpCode opcode = JavaOpCode.InstructionLookup[bytecode[instructionStart]]; if (opcode.Name == null) throw new FormatException(string.Format("Encountered unrecognized opcode {0} at offset {1}.", bytecode[instructionStart], instructionStart)); int instructionLength = opcode.Size; JavaOperandData operands = default(JavaOperandData); switch (opcode.OperandType) { case JavaOperandType.InlineNone: break; case JavaOperandType.InlineI1: operands = new JavaOperandData(ReadSByte(bytecode, instructionStart + 1)); break; case JavaOperandType.InlineI2: case JavaOperandType.InlineShortBranchTarget: operands = new JavaOperandData(ReadInt16(bytecode, instructionStart + 1)); break; case JavaOperandType.InlineBranchTarget: operands = new JavaOperandData(ReadInt32(bytecode, instructionStart + 1)); break; case JavaOperandType.InlineLookupSwitch: { int defaultStart = (instructionStart + 4) & (~3); int defaultValue = ReadInt32(bytecode, defaultStart); int pairsCount = ReadInt32(bytecode, defaultStart + sizeof(int)); if (pairsCount < 0) throw new FormatException(); List<KeyValuePair<int, int>> pairs = new List<KeyValuePair<int, int>>(); for (int j = 0; j < pairsCount; j++) { int pairStart = defaultStart + (sizeof(int) * (2 + 2 * j)); pairs.Add(new KeyValuePair<int, int>(ReadInt32(bytecode, pairStart), ReadInt32(bytecode, pairStart + sizeof(int)))); } switchData.Add(new LookupSwitchData(defaultValue, pairs)); int instructionSize = (defaultStart - instructionStart) + (sizeof(int) * (2 + 2 * pairsCount)); operands = new JavaOperandData((ushort)(switchData.Count - 1), instructionSize); break; } case JavaOperandType.InlineTableSwitch: { int defaultStart = (instructionStart + 4) & (~3); int defaultValue = ReadInt32(bytecode, defaultStart); int lowValue = ReadInt32(bytecode, defaultStart + 4); int highValue = ReadInt32(bytecode, defaultStart + 8); if (highValue < lowValue) throw new FormatException(); List<int> offsets = new List<int>(); for (int j = 0; j < highValue - lowValue + 1; j++) { int valueStart = defaultStart + (sizeof(int) * (3 + j)); offsets.Add(ReadInt32(bytecode, valueStart)); } switchData.Add(new TableSwitchData(defaultValue, lowValue, highValue, offsets)); int instructionSize = (defaultStart - instructionStart) + (sizeof(int) * (3 + offsets.Count)); operands = new JavaOperandData((ushort)(switchData.Count - 1), instructionSize); break; } case JavaOperandType.InlineShortConst: case JavaOperandType.InlineVar: case JavaOperandType.InlineArrayType: operands = new JavaOperandData(ReadByte(bytecode, instructionStart + 1)); break; case JavaOperandType.InlineConst: case JavaOperandType.InlineField: case JavaOperandType.InlineMethod: case JavaOperandType.InlineType: operands = new JavaOperandData(ReadUInt16(bytecode, instructionStart + 1)); break; case JavaOperandType.InlineVar_I1: operands = new JavaOperandData(ReadByte(bytecode, instructionStart + 1), ReadSByte(bytecode, instructionStart + 2)); break; case JavaOperandType.InlineMethod_U1_0: case JavaOperandType.InlineType_U1: operands = new JavaOperandData(ReadUInt16(bytecode, instructionStart + 1), ReadByte(bytecode, instructionStart + 3)); break; default: throw new FormatException(); } instructions.Add(new JavaInstruction(instructionStart, opcode, operands)); if (opcode.Size > 0) { i += opcode.Size; } else { switch (opcode.OpCode) { case JavaOpCodeTag.Tableswitch: case JavaOpCodeTag.Lookupswitch: i += operands.SwitchInstructionSize; break; case JavaOpCodeTag.Wide: throw new NotImplementedException(); default: throw new FormatException(); } } } return new DisassembledMethod(instructions, switchData); }
public static DisassembledMethod Disassemble(byte[] bytecode) { Contract.Requires <ArgumentNullException>(bytecode != null, "bytecode"); List <JavaInstruction> instructions = new List <JavaInstruction>(); List <SwitchData> switchData = new List <SwitchData>(); for (int i = 0; i < bytecode.Length; /*increment in loop*/) { int instructionStart = i; JavaOpCode opcode = JavaOpCode.InstructionLookup[bytecode[instructionStart]]; if (opcode.Name == null) { throw new FormatException(string.Format("Encountered unrecognized opcode {0} at offset {1}.", bytecode[instructionStart], instructionStart)); } int instructionLength = opcode.Size; JavaOperandData operands = default(JavaOperandData); switch (opcode.OperandType) { case JavaOperandType.InlineNone: break; case JavaOperandType.InlineI1: operands = new JavaOperandData(ReadSByte(bytecode, instructionStart + 1)); break; case JavaOperandType.InlineI2: case JavaOperandType.InlineShortBranchTarget: operands = new JavaOperandData(ReadInt16(bytecode, instructionStart + 1)); break; case JavaOperandType.InlineBranchTarget: operands = new JavaOperandData(ReadInt32(bytecode, instructionStart + 1)); break; case JavaOperandType.InlineLookupSwitch: { int defaultStart = (instructionStart + 4) & (~3); int defaultValue = ReadInt32(bytecode, defaultStart); int pairsCount = ReadInt32(bytecode, defaultStart + sizeof(int)); if (pairsCount < 0) { throw new FormatException(); } List <KeyValuePair <int, int> > pairs = new List <KeyValuePair <int, int> >(); for (int j = 0; j < pairsCount; j++) { int pairStart = defaultStart + (sizeof(int) * (2 + 2 * j)); pairs.Add(new KeyValuePair <int, int>(ReadInt32(bytecode, pairStart), ReadInt32(bytecode, pairStart + sizeof(int)))); } switchData.Add(new LookupSwitchData(defaultValue, pairs)); int instructionSize = (defaultStart - instructionStart) + (sizeof(int) * (2 + 2 * pairsCount)); operands = new JavaOperandData((ushort)(switchData.Count - 1), instructionSize); break; } case JavaOperandType.InlineTableSwitch: { int defaultStart = (instructionStart + 4) & (~3); int defaultValue = ReadInt32(bytecode, defaultStart); int lowValue = ReadInt32(bytecode, defaultStart + 4); int highValue = ReadInt32(bytecode, defaultStart + 8); if (highValue < lowValue) { throw new FormatException(); } List <int> offsets = new List <int>(); for (int j = 0; j < highValue - lowValue + 1; j++) { int valueStart = defaultStart + (sizeof(int) * (3 + j)); offsets.Add(ReadInt32(bytecode, valueStart)); } switchData.Add(new TableSwitchData(defaultValue, lowValue, highValue, offsets)); int instructionSize = (defaultStart - instructionStart) + (sizeof(int) * (3 + offsets.Count)); operands = new JavaOperandData((ushort)(switchData.Count - 1), instructionSize); break; } case JavaOperandType.InlineShortConst: case JavaOperandType.InlineVar: case JavaOperandType.InlineArrayType: operands = new JavaOperandData(ReadByte(bytecode, instructionStart + 1)); break; case JavaOperandType.InlineConst: case JavaOperandType.InlineField: case JavaOperandType.InlineMethod: case JavaOperandType.InlineType: operands = new JavaOperandData(ReadUInt16(bytecode, instructionStart + 1)); break; case JavaOperandType.InlineVar_I1: operands = new JavaOperandData(ReadByte(bytecode, instructionStart + 1), ReadSByte(bytecode, instructionStart + 2)); break; case JavaOperandType.InlineMethod_U1_0: case JavaOperandType.InlineType_U1: operands = new JavaOperandData(ReadUInt16(bytecode, instructionStart + 1), ReadByte(bytecode, instructionStart + 3)); break; default: throw new FormatException(); } instructions.Add(new JavaInstruction(instructionStart, opcode, operands)); if (opcode.Size > 0) { i += opcode.Size; } else { switch (opcode.OpCode) { case JavaOpCodeTag.Tableswitch: case JavaOpCodeTag.Lookupswitch: i += operands.SwitchInstructionSize; break; case JavaOpCodeTag.Wide: throw new NotImplementedException(); default: throw new FormatException(); } } } return(new DisassembledMethod(instructions, switchData)); }