示例#1
0
        public static Attribute ReadAttribute(BinaryReader Reader, ConstantPool Pool)
        {
            string Name   = ((Constants.Utf8)Pool[Reader.ReadUInt16BE()]).Value;
            uint   Length = Reader.ReadUInt32BE();
            long   Next   = (long)Reader.BaseStream.Position - (long)(Length - 6);

            Attribute Result = null;

            if (Name == "AnnotationDefault")
            {
                Result = new Attributes.AnnotationDefault();
            }
            else if (Name == "Code")
            {
                Result = new Attributes.Code();
            }
            else if (Name == "ConstantValue")
            {
                Result = new Attributes.ConstantValue();
            }
            else if (Name == "Deprecated")
            {
                Result = new Attributes.Deprecated();
            }
            else if (Name == "Exceptions")
            {
                Result = new Attributes.Exceptions();
            }
            else if (Name == "InnerClasses")
            {
                Result = new Attributes.InnerClasses();
            }
            else if (Name == "LineNumberTable")
            {
                Result = new Attributes.LineNumberTable();
            }
            else if (Name == "LocalVariableTable")
            {
                Result = new Attributes.LocalVariableTable();
            }
            else if (Name == "RuntimeVisibleAnnotations")
            {
                Result = new Attributes.RuntimeVisibleAnnotations();
            }
            else if (Name == "RuntimeInvisibleAnnotations")
            {
                Result = new Attributes.RuntimeInvisibleAnnotations();
            }
            else if (Name == "RuntimeVisibleParameterAnnotations")
            {
                Result = new Attributes.RuntimeVisibleParameterAnnotations(Reader.ReadByte());
            }
            else if (Name == "RuntimeInvisibleParameterAnnotations")
            {
                Result = new Attributes.RuntimeInvisibleParameterAnnotations(Reader.ReadByte());
            }
            else if (Name == "Signature")
            {
                Result = new Attributes.Signature();
            }
            else if (Name == "SourceFile")
            {
                Result = new Attributes.SourceFile();
            }
            else if (Name == "Synthetic")
            {
                Result = new Attributes.Synthetic();
            }
            else
            {
                Result      = new Attributes.RawAttribute();
                Result.Name = Name;
            }

            Result.Read(Length, Reader, Pool);
            return(Result);
        }
示例#2
0
        private static void Disasm(Attributes.Code codeAttr, ConstantPool pool, CountingStreamWriter writer, string[] sourceFile)
        {
            byte[] code = codeAttr.CodeBytes;

            int  i        = 0;
            bool lastWide = false;

            Attributes.LineNumberTable lnt    = codeAttr.Attributes.Where(A => A is Attributes.LineNumberTable).FirstOrDefault() as Attributes.LineNumberTable;
            Attributes.LineNumberTable newLnt = new Attributes.LineNumberTable();
            int lastLine = 0;

            while (i < code.Length)
            {
                if ((lnt != null) && (sourceFile != null))
                {
                    try
                    {
                        var lns = lnt.Table.Where(ln => ln.StartPC <= i);
                        if (lns.Count() > 0)
                        {
                            int currLine = lns.Aggregate((i1, i2) => i1.StartPC > i2.StartPC ? i1 : i2).LineNumberInFile;

                            if (lastLine != currLine)
                            {
                                writer.WriteLine("              ## {0}", sourceFile[currLine]);
                            }
                            lastLine = currLine;
                        }
                    }
                    catch (Exception)
                    {
                    }
                }

                newLnt.Table.Add(new Attributes.LineNumberTable.LineNumber((ushort)i, (ushort)writer.CurrLine));

                OpCodes op = (OpCodes)code[i];

                if (!lastWide)
                {
                    writer.Write("              {0,4:X} : ", i);
                }

                if (op == OpCodes.wide)
                {
                    writer.Write("wide ");
                    i++;
                    lastWide = true;
                    continue;
                }

                string opStr      = op.ToString();
                string operandStr = "";

                if (opStr[0] == '_')
                {
                    opStr = opStr.Substring(1);
                }

                writer.Write(opStr);

                ByteCode.JavaInstructionDescption descr = ByteCode.JavaInstructions[op];
                int operandSize = descr.Size - 1;

                if (lastWide)
                {
                    operandSize *= 2;
                    lastWide     = false;
                }

                switch (descr.OpType)
                {
                case ByteCode.JavaOperandType.ConstPool:
                    ushort index = (ushort)BitConverterBE.ReadAsInt32(code, i + 1, operandSize);
                    operandStr = pool[index].ToString();
                    break;

                case ByteCode.JavaOperandType.ConstValue:
                case ByteCode.JavaOperandType.LocalVar:
                    operandStr = BitConverterBE.ReadAsInt32(code, i + 1, operandSize).ToString();
                    break;

                case ByteCode.JavaOperandType.Offset:
                    short offset = (short)BitConverterBE.ReadAsInt32(code, i + 1, operandSize);
                    operandStr = String.Format("{0,4:X}", (i + offset));
                    break;

                case ByteCode.JavaOperandType.Special:
                    switch (op)
                    {
                    case OpCodes.iinc:
                        int op1 = BitConverterBE.ReadAsInt32(code, i + 1, operandSize / 2);
                        int op2 = BitConverterBE.ReadAsInt32(code, i + 1 + operandSize / 2, operandSize / 2);
                        operandStr = String.Format("{0}, {1}", op1, op2);
                        break;

                    case OpCodes.lookupswitch:
                        int paddingLength = (4 - ((i + 1) % 4)) % 4;
                        int _default      = BitConverterBE.ReadAsInt32(code, i + paddingLength + 1, 4);
                        int npairs        = BitConverterBE.ReadAsInt32(code, i + paddingLength + 5, 4);
                        int pairsStart    = i + paddingLength + 9;
                        operandSize = npairs * 8 + 8 + paddingLength;

                        writer.WriteLine(" default: {0,4:X}, npairs: {1}", _default, npairs);

                        for (int pair = 0; pair < npairs; pair++)
                        {
                            int pairValue  = BitConverterBE.ReadAsInt32(code, pairsStart + (pair * 8), 4);
                            int pairOffset = BitConverterBE.ReadAsInt32(code, pairsStart + (pair * 8) + 4, 4);

                            writer.WriteLine("                     {0,4:X} : {1}", pairOffset, pairValue);
                        }
                        break;

                    case OpCodes.tableswitch:
                        paddingLength = (4 - ((i + 1) % 4)) % 4;
                        _default      = BitConverterBE.ReadAsInt32(code, i + paddingLength + 1, 4);
                        int low   = BitConverterBE.ReadAsInt32(code, i + paddingLength + 5, 4);
                        int hight = BitConverterBE.ReadAsInt32(code, i + paddingLength + 9, 4);

                        writer.WriteLine(" default: {0,4:X}, low: {1}, hight: {2}", _default, low, hight);
                        int jmpCount = hight - low + 1;
                        int jmpStart = i + paddingLength + 13;
                        operandSize = jmpCount * 4 + 13 + paddingLength;

                        for (int jmp = 0; jmp < jmpCount; jmp++)
                        {
                            writer.WriteLine("                     {0,4:X} : {1}", BitConverterBE.ReadAsInt32(code, jmpStart + jmp * 4, 4), low + jmp);
                        }
                        break;

                    case OpCodes.invokeinterface:
                    case OpCodes.invokedynamic:
                        index      = (ushort)BitConverterBE.ReadAsInt32(code, i + 1, 2);
                        operandStr = pool[index].ToString();
                        break;

                    case OpCodes.newarray:
                        operandStr = ArrayTypes[code[i + 1]];
                        break;

                    case OpCodes.multianewarray:
                        index = (ushort)BitConverterBE.ReadAsInt32(code, i + 1, 2);
                        byte dismensions = code[i + 3];
                        operandStr = String.Format("{0}, {1}", dismensions, pool[index].ToString());
                        break;
                    }
                    ;
                    break;
                }

                writer.WriteLine(" {0}", operandStr);
                i += 1 + operandSize;
            }

            if (Program.DebugBytecode)
            {
                if (lnt != null)
                {
                    codeAttr.Attributes.Remove(lnt);
                }
                codeAttr.Attributes.Add(newLnt);
            }
        }