예제 #1
0
 public JavaInstruction(int offset, JavaOpCode opcode, JavaOperandData operands)
 {
     _offset   = offset;
     _opcode   = opcode;
     _operands = operands;
 }
예제 #2
0
        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);
        }
예제 #3
0
        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));
        }
예제 #4
0
 public JavaInstruction(int offset, JavaOpCode opcode, JavaOperandData operands)
 {
     _offset = offset;
     _opcode = opcode;
     _operands = operands;
 }