Exemplo n.º 1
0
        /// <summary>
        /// Convenience method for creating an opcode from a position in a byte array.
        /// Returns an opcode object with references resolved and advances the position
        /// to the next place in the byte array.
        /// </summary>
        /// <param name="reader">Where to read the next opcode from</param>
        /// <param name="abc">The code within which we're reading</param>
        /// <returns>A new Opcode object, or null if there was no more data to be read</returns>
        public static Opcode BuildOpcode(ABCDataTypeReader reader, AbcCode abc)
        {
            Opcode op = new Opcode(abc);

            int code;

            code = reader.ReadUI8();
            if (code == -1)
            {
                return(null);
            }
            op.Instruction = (uint)code;

            if (OpcodeTable[code] == null)
            {
                throw new SWFModellerException(
                          SWFModellerError.Internal,
                          "Bad opcode 0x" + code.ToString("X") + " at @" + (reader.Offset - 1));
            }
            OpcodeDef info = (OpcodeDef)OpcodeTable[code];

            List <object> args = new List <object>();

            if (info.Mnemonic == Mnemonics.LookupSwitch)
            {
                /* Special case: Has a variable arg */
                args.Add(reader.ReadSI24()); /* default offset */
                uint caseCount = reader.ReadU30();
                args.Add(caseCount);

                for (int i = 0; i < caseCount + 1; i++)
                {
                    args.Add(reader.ReadSI24());
                }
            }
            else
            {
                if (info.Args != null)
                {
                    foreach (ArgType type in info.Args)
                    {
                        switch (type)
                        {
                        case ArgType.MultinameU30:
                            args.Add(abc.GetMultiname((int)reader.ReadU30()));
                            break;

                        case ArgType.OffsetS24:
                            args.Add(reader.ReadSI24());
                            break;

                        case ArgType.StringU30:
                            args.Add(abc.StringConsts[reader.ReadU30()]);
                            break;

                        case ArgType.RegisterU30:
                        case ArgType.ObjectRegisterU30:
                        case ArgType.PropertyRegisterU30:
                            args.Add(reader.ReadU30());
                            break;

                        case ArgType.ByteU8:
                            args.Add((byte)reader.ReadUI8());
                            break;

                        case ArgType.ShortU30:
                        case ArgType.IntU30:
                        case ArgType.UintU30:
                        case ArgType.DoubleU30:
                            args.Add(reader.ReadU30());
                            break;

                        case ArgType.ShortS30:
                            args.Add((int)reader.ReadU30());
                            break;

                        case ArgType.ByteS8:
                            args.Add(reader.ReadSI8());
                            break;

                        case ArgType.NamespaceU30:
                            args.Add(abc.GetNamespace((int)reader.ReadU30()));
                            break;

                        case ArgType.MethodU30:
                            args.Add(abc.GetMethod((int)reader.ReadU30()));
                            break;

                        case ArgType.CountU30:
                            args.Add(reader.ReadU30());
                            break;

                        case ArgType.ClassU30:
                            args.Add(abc.GetClass((int)reader.ReadU30()));
                            break;

                        case ArgType.ExceptionU30:
                            args.Add(reader.ReadU30());
                            break;

                        case ArgType.StackU8:
                            args.Add((byte)reader.ReadUI8());
                            break;

                        case ArgType.SlotU30:
                            args.Add(reader.ReadU30());
                            break;

                        case ArgType.DebugU8:
                            args.Add((byte)reader.ReadUI8());
                            break;

                        case ArgType.DebugTypeU30:
                            args.Add(reader.ReadU30());
                            break;

                        case ArgType.StringU8:
                            args.Add(abc.StringConsts[reader.ReadUI8()]);
                            break;

                        case ArgType.LineNumberU30:
                            args.Add(reader.ReadU30());
                            break;

                        default:
                            /* ISSUE 73 */
                            throw new SWFModellerException(
                                      SWFModellerError.UnimplementedFeature,
                                      "Oops. Not done " + type.ToString());
                        }
                    }
                }
            }

            op.Args = args.ToArray();

            return(op);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Convenience method for creating an opcode from a position in a byte array.
        /// Returns an opcode object with references resolved and advances the position
        /// to the next place in the byte array.
        /// </summary>
        /// <param name="reader">Where to read the next opcode from</param>
        /// <param name="abc">The code within which we're reading</param>
        /// <returns>A new Opcode object, or null if there was no more data to be read</returns>
        public static Opcode BuildOpcode(ABCDataTypeReader reader, AbcCode abc)
        {
            Opcode op = new Opcode(abc);

            int code;
            code = reader.ReadUI8();
            if (code == -1)
            {
                return null;
            }
            op.Instruction = (uint)code;

            if (OpcodeTable[code] == null)
            {
                throw new SWFModellerException(
                        SWFModellerError.Internal,
                        "Bad opcode 0x" + code.ToString("X") + " at @" + (reader.Offset - 1));
            }
            OpcodeDef info = (OpcodeDef)OpcodeTable[code];

            List<object> args = new List<object>();

            if (info.Mnemonic == Mnemonics.LookupSwitch)
            {
                /* Special case: Has a variable arg */
                args.Add(reader.ReadSI24()); /* default offset */
                uint caseCount = reader.ReadU30();
                args.Add(caseCount);

                for (int i = 0; i < caseCount + 1; i++)
                {
                    args.Add(reader.ReadSI24());
                }
            }
            else
            {
                if (info.Args != null)
                {
                    foreach (ArgType type in info.Args)
                    {
                        switch (type)
                        {
                            case ArgType.MultinameU30:
                                args.Add(abc.GetMultiname((int)reader.ReadU30()));
                                break;

                            case ArgType.OffsetS24:
                                args.Add(reader.ReadSI24());
                                break;

                            case ArgType.StringU30:
                                args.Add(abc.StringConsts[reader.ReadU30()]);
                                break;

                            case ArgType.RegisterU30:
                            case ArgType.ObjectRegisterU30:
                            case ArgType.PropertyRegisterU30:
                                args.Add(reader.ReadU30());
                                break;

                            case ArgType.ByteU8:
                                args.Add((byte)reader.ReadUI8());
                                break;

                            case ArgType.ShortU30:
                            case ArgType.IntU30:
                            case ArgType.UintU30:
                            case ArgType.DoubleU30:
                                args.Add(reader.ReadU30());
                                break;

                            case ArgType.ShortS30:
                                args.Add((int)reader.ReadU30());
                                break;

                            case ArgType.ByteS8:
                                args.Add(reader.ReadSI8());
                                break;

                            case ArgType.NamespaceU30:
                                args.Add(abc.GetNamespace((int)reader.ReadU30()));
                                break;

                            case ArgType.MethodU30:
                                args.Add(abc.GetMethod((int)reader.ReadU30()));
                                break;

                            case ArgType.CountU30:
                                args.Add(reader.ReadU30());
                                break;

                            case ArgType.ClassU30:
                                args.Add(abc.GetClass((int)reader.ReadU30()));
                                break;

                            case ArgType.ExceptionU30:
                                args.Add(reader.ReadU30());
                                break;

                            case ArgType.StackU8:
                                args.Add((byte)reader.ReadUI8());
                                break;

                            case ArgType.SlotU30:
                                args.Add(reader.ReadU30());
                                break;

                            case ArgType.DebugU8:
                                args.Add((byte)reader.ReadUI8());
                                break;

                            case ArgType.DebugTypeU30:
                                args.Add(reader.ReadU30());
                                break;

                            case ArgType.StringU8:
                                args.Add(abc.StringConsts[reader.ReadUI8()]);
                                break;

                            case ArgType.LineNumberU30:
                                args.Add(reader.ReadU30());
                                break;

                            default:
                                /* ISSUE 73 */
                                throw new SWFModellerException(
                                        SWFModellerError.UnimplementedFeature,
                                        "Oops. Not done " + type.ToString());
                        }
                    }
                }
            }

            op.Args = args.ToArray();

            return op;
        }