/// <summary>
        /// convert <see cref="SwfOp.ByteCode.Actions.ActionPushList">push list</see> to sequence of single <see cref="SwfOp.ByteCode.Actions.ActionPush" >push</see> actions
        /// </summary>
        private void ExplodePushLists(ArrayList actionRecord)
        {
            for (int i = 0; i < actionRecord.Count; i++)
            {
                BaseAction a = (BaseAction)actionRecord[i];

                // check if action is multiple push
                ActionPushList pl = actionRecord[i] as ActionPushList;
                if (pl != null)
                {
                    // resolve pushs to single push actions
                    for (int j = 0; j < pl.Length; j++)
                    {
                        ActionPush p = pl[j];
                        actionRecord.Insert(i + 1 + j, p);
                    }

                    actionRecord.RemoveAt(i);
                }

                // process inner actionblocks
                if (a as ActionDefineFunction != null)
                {
                    ActionDefineFunction f = (ActionDefineFunction)a;
                    ExplodePushLists(f.ActionRecord);
                }
                if (a as ActionDefineFunction2 != null)
                {
                    ActionDefineFunction2 f = (ActionDefineFunction2)a;
                    ExplodePushLists(f.ActionRecord);
                }
            }
        }
Beispiel #2
0
        public static void AreEqual(ActionDefineFunction2 expected, ActionDefineFunction2 actual, string message)
        {
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.RegisterCount, actual.RegisterCount);
            Assert.AreEqual(expected.PreloadParent, actual.PreloadParent);
            Assert.AreEqual(expected.PreloadRoot, actual.PreloadRoot);
            Assert.AreEqual(expected.SuppressSuper, actual.SuppressSuper);
            Assert.AreEqual(expected.PreloadSuper, actual.PreloadSuper);
            Assert.AreEqual(expected.SuppressArguments, actual.SuppressArguments);
            Assert.AreEqual(expected.PreloadArguments, actual.PreloadArguments);
            Assert.AreEqual(expected.SuppressThis, actual.SuppressThis);
            Assert.AreEqual(expected.PreloadThis, actual.PreloadThis);

            Assert.AreEqual(expected.Reserved, actual.Reserved);
            Assert.AreEqual(expected.PreloadGlobal, actual.PreloadGlobal);

            Assert.AreEqual(expected.Parameters.Count, actual.Parameters.Count, message + ".Parameters.Count");
            for (var i = 0; i < expected.Parameters.Count; i++) {
                AreEqual(expected.Parameters[i], actual.Parameters[i], message + ".Parameters[" + i + "]");
            }

            Assert.AreEqual(expected.Actions.Count, actual.Actions.Count, message + ".Actions.Count");
            for (var i = 0; i < expected.Actions.Count; i++) {
                AreEqual(expected.Actions[i], actual.Actions[i], message + ".Parameters[" + i + "]");
            }
        }
Beispiel #3
0
        public static void AreEqual(ActionDefineFunction2 expected, ActionDefineFunction2 actual, string message)
        {
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.RegisterCount, actual.RegisterCount);
            Assert.AreEqual(expected.PreloadParent, actual.PreloadParent);
            Assert.AreEqual(expected.PreloadRoot, actual.PreloadRoot);
            Assert.AreEqual(expected.SuppressSuper, actual.SuppressSuper);
            Assert.AreEqual(expected.PreloadSuper, actual.PreloadSuper);
            Assert.AreEqual(expected.SuppressArguments, actual.SuppressArguments);
            Assert.AreEqual(expected.PreloadArguments, actual.PreloadArguments);
            Assert.AreEqual(expected.SuppressThis, actual.SuppressThis);
            Assert.AreEqual(expected.PreloadThis, actual.PreloadThis);

            Assert.AreEqual(expected.Reserved, actual.Reserved);
            Assert.AreEqual(expected.PreloadGlobal, actual.PreloadGlobal);

            Assert.AreEqual(expected.Parameters.Count, actual.Parameters.Count, message + ".Parameters.Count");
            for (var i = 0; i < expected.Parameters.Count; i++)
            {
                AreEqual(expected.Parameters[i], actual.Parameters[i], message + ".Parameters[" + i + "]");
            }

            Assert.AreEqual(expected.Actions.Count, actual.Actions.Count, message + ".Actions.Count");
            for (var i = 0; i < expected.Actions.Count; i++)
            {
                AreEqual(expected.Actions[i], actual.Actions[i], message + ".Parameters[" + i + "]");
            }
        }
Beispiel #4
0
        /// <summary>
        /// Collaps sequence of single push actions into one multiple-push action
        /// </summary>
        private void CollapsPushActions(ArrayList actionRecord)
        {
            int  i = 0;
            bool isPush;

            while (i < (actionRecord.Count - 1))
            {
                isPush = actionRecord[i] is ActionPush;
                if (isPush)
                {
                    int j     = i;
                    int count = 1;

                    do
                    {
                        i++;
                        if (i < actionRecord.Count)
                        {
                            isPush = (actionRecord[i] is ActionPush);
                            if (isPush)
                            {
                                count++;
                            }
                        }
                    } while ((isPush) && (i < actionRecord.Count));

                    if (count > 1)
                    {
                        ActionPush[] pushList = new ActionPush[count];
                        actionRecord.CopyTo(j, pushList, 0, count);

                        actionRecord.RemoveRange(j, count);
                        ActionPushList pl = new ActionPushList(pushList);
                        actionRecord.Insert(j, pl);

                        i = j + 1;
                    }
                }
                else
                {
                    // recursively step through functions inner actions
                    ActionDefineFunction f = actionRecord[i] as ActionDefineFunction;
                    if (f != null)
                    {
                        CollapsPushActions(f.ActionRecord);
                    }

                    // and function2 of course
                    ActionDefineFunction2 f2 = actionRecord[i] as ActionDefineFunction2;
                    if (f2 != null)
                    {
                        CollapsPushActions(f2.ActionRecord);
                    }
                    i++;
                }
            }
        }
Beispiel #5
0
        ///<summary>
        /// Calculate branch offsets.
        ///</summary>
        private void CalcBranchOffsets(ArrayList actionRecord)
        {
            if (actionRecord.Count < 1)
            {
                return;
            }

            ArrayList jumpList = new ArrayList();
            Hashtable labelPos = new Hashtable();

            int pos = 0;

            for (int i = 0; i < actionRecord.Count; i++)
            {
                BaseAction  action = (BaseAction)actionRecord[i];
                ActionLabel label  = action as ActionLabel;
                IJump       jump   = action as IJump;

                if (label != null)
                {
                    labelPos[label.LabelId] = pos;
                }

                if (jump != null)
                {
                    jumpList.Add(new JumpPos(pos, jump));
                }

                // recursively step through function blocks
                ActionDefineFunction f = actionRecord[i] as ActionDefineFunction;
                if (f != null)
                {
                    CalcBranchOffsets(f.ActionRecord);
                }

                ActionDefineFunction2 f2 = actionRecord[i] as ActionDefineFunction2;
                if (f2 != null)
                {
                    CalcBranchOffsets(f2.ActionRecord);
                }

                pos += action.ByteCount;
            }

            for (int i = 0; i < jumpList.Count; i++)
            {
                JumpPos j      = (JumpPos)jumpList[i];
                int     offset = (int)labelPos[j.Jump.LabelId] - j.Position - 5;
                j.Jump.Offset = offset;
            }
        }
Beispiel #6
0
        ActionBase IActionVisitor <XElement, ActionBase> .Visit(ActionDefineFunction2 action, XElement xAction)
        {
            var xName              = xAction.Attribute("name");
            var xRegisterCount     = xAction.Attribute("regc");
            var xPreloadParent     = xAction.Attribute("preloadParent");
            var xPreloadRoot       = xAction.Attribute("preloadRoot");
            var xSuppressSuper     = xAction.Attribute("suppressSuper");
            var xPreloadSuper      = xAction.Attribute("preloadSuper");
            var xSuppressArguments = xAction.Attribute("suppressArguments");
            var xPreloadArguments  = xAction.Attribute("preloadArguments");
            var xSuppressThis      = xAction.Attribute("suppressThis");
            var xPreloadThis       = xAction.Attribute("preloadThis");
            var xReserved          = xAction.Attribute("reserved");
            var xPreloadGlobal     = xAction.Attribute("preloadGlobal");

            action.Name              = xName != null ? xName.Value : "";
            action.RegisterCount     = byte.Parse(xRegisterCount.Value);
            action.PreloadParent     = CommonFormatter.ParseBool(xPreloadParent.Value);
            action.PreloadRoot       = CommonFormatter.ParseBool(xPreloadRoot.Value);
            action.SuppressSuper     = CommonFormatter.ParseBool(xSuppressSuper.Value);
            action.PreloadSuper      = CommonFormatter.ParseBool(xPreloadSuper.Value);
            action.SuppressArguments = CommonFormatter.ParseBool(xSuppressArguments.Value);
            action.PreloadArguments  = CommonFormatter.ParseBool(xPreloadArguments.Value);
            action.SuppressThis      = CommonFormatter.ParseBool(xSuppressThis.Value);
            action.PreloadThis       = CommonFormatter.ParseBool(xPreloadThis.Value);
            action.Reserved          = byte.Parse(xReserved.Value);
            action.PreloadGlobal     = CommonFormatter.ParseBool(xPreloadGlobal.Value);

            var xArgs = xAction.Element("args");

            foreach (var xArg in xArgs.Elements())
            {
                var xReg     = xArg.Attribute("reg");
                var xArgName = xArg.Attribute("name");
                action.Parameters.Add(new RegisterParam {
                    Register = byte.Parse(xReg.Value),
                    Name     = xArgName.Value
                });
            }

            var xActions = xAction.Element("actions");

            foreach (var xSubAction in xActions.Elements())
            {
                action.Actions.Add(Deserialize(xSubAction));
            }
            return(action);
        }
        /// <summary>
        /// Read <see cref="SwfOp.ByteCode.Actions.ActionPushList">ActionDefineFunction2</see> from swf.
        /// including inner actions
        /// </summary>
        private ActionDefineFunction2 ReadActionDefineFunction2(BinaryReader br)
        {
            int start = Convert.ToInt32(br.BaseStream.Position);
            // read block length
            int len = Convert.ToInt32(br.ReadUInt16());

            string name      = BinaryStringRW.ReadString(br);
            int    numParams = Convert.ToInt32(br.ReadUInt16());
            int    numRegs   = Convert.ToInt32(br.ReadByte());
            byte   flags1    = br.ReadByte();
            byte   flags2    = br.ReadByte();

            ActionDefineFunction2.VariableFlagSet f
                = new ActionDefineFunction2.VariableFlagSet(
                      (flags1 & 0x80) == 0x80,
                      (flags1 & 0x40) == 0x40,
                      (flags1 & 0x20) == 0x20,
                      (flags1 & 0x10) == 0x10,
                      (flags1 & 0x08) == 0x08,
                      (flags1 & 0x04) == 0x04,
                      (flags1 & 0x02) == 0x02,
                      (flags1 & 0x01) == 0x01,
                      (flags2 & 0x01) == 0x01
                      );

            // read parameters
            ActionDefineFunction2.RegParamPair[] paramList = new ActionDefineFunction2.RegParamPair[numParams];

            for (int i = 0; i < numParams; i++)
            {
                int    r = Convert.ToInt32(br.ReadByte());
                string p = BinaryStringRW.ReadString(br);
                paramList[i] = new ActionDefineFunction2.RegParamPair(r, p);
            }
            int blockSize = Convert.ToInt32(br.ReadUInt16());

            // read function body
            ArrayList             InnerActions = ReadActions(br.ReadBytes(blockSize));
            ActionDefineFunction2 a            = new ActionDefineFunction2(name, paramList, numRegs, f, InnerActions);

            int end = Convert.ToInt32(br.BaseStream.Position);

            ////a.ByteSize = len+3+blockSize;
            //a.ByteSize = end-start+1;

            return(a);
        }
Beispiel #8
0
        XElement IActionVisitor <XElement, XElement> .Visit(ActionDefineFunction2 action, XElement res)
        {
            res.Add(new XAttribute("name", action.Name ?? ""));
            res.Add(new XAttribute("argc", action.Parameters.Count));
            res.Add(new XAttribute("regc", action.RegisterCount));
            res.Add(new XAttribute("preloadParent", CommonFormatter.Format(action.PreloadParent)));
            res.Add(new XAttribute("preloadRoot", CommonFormatter.Format(action.PreloadRoot)));
            res.Add(new XAttribute("suppressSuper", CommonFormatter.Format(action.SuppressSuper)));
            res.Add(new XAttribute("preloadSuper", CommonFormatter.Format(action.PreloadSuper)));
            res.Add(new XAttribute("suppressArguments", CommonFormatter.Format(action.SuppressArguments)));
            res.Add(new XAttribute("preloadArguments", CommonFormatter.Format(action.PreloadArguments)));
            res.Add(new XAttribute("suppressThis", CommonFormatter.Format(action.SuppressThis)));
            res.Add(new XAttribute("preloadThis", CommonFormatter.Format(action.PreloadThis)));
            res.Add(new XAttribute("reserved", action.Reserved));
            res.Add(new XAttribute("preloadGlobal", CommonFormatter.Format(action.PreloadGlobal)));

            var xArgs = new XElement("args");

            foreach (var arg in action.Parameters)
            {
                xArgs.Add(new XElement("Parameter",
                                       new XAttribute("reg", arg.Register),
                                       new XAttribute("name", arg.Name)));
            }
            res.Add(xArgs);

            var xActions = new XElement("actions");

            foreach (var subaction in action.Actions)
            {
                xActions.Add(Serialize(subaction));
            }
            res.Add(xActions);

            return(res);
        }
Beispiel #9
0
        ///<summary>
        /// Calculate size or offset for action blocks.
        ///</summary>
        private void CalcBlockOffsets(ArrayList actionRecord)
        {
            if (actionRecord.Count < 1)
            {
                return;
            }

            for (int i = 0; i < actionRecord.Count; i++)
            {
                BaseAction a = (BaseAction)actionRecord[i];

                // action with
                ActionWith aWith = a as ActionWith;
                if (aWith != null)
                {
                    int j      = i;
                    int offset = 0;
                    do
                    {
                        j++;
                        offset += ((BaseAction)actionRecord[j]).ByteCount;
                    } while ((actionRecord[j] as ActionEndWith) == null);

                    int oldOffset = aWith.BlockLength;

                    aWith.BlockLength = offset;
                }

                // action waitForFrame
                ActionWaitForFrame aWait = a as ActionWaitForFrame;
                if (aWait != null)
                {
                    int        j     = i;
                    int        count = 0;
                    BaseAction ca;
                    do
                    {
                        j++;
                        ca = (BaseAction)actionRecord[j];
                        if ((ca.Code >= 0) || (ca.Code == (int)ActionCode.PushList))
                        {
                            count++;
                        }
                    } while ((ca as ActionEndWait) == null);
                    aWait.SkipCount = count;
                }

                // action waitForFrame2
                ActionWaitForFrame2 aWait2 = a as ActionWaitForFrame2;
                if (aWait2 != null)
                {
                    int        j     = i;
                    int        count = 0;
                    BaseAction ca;
                    do
                    {
                        j++;
                        ca = (BaseAction)actionRecord[j];
                        if ((ca.Code >= 0) || (ca.Code == (int)ActionCode.PushList))
                        {
                            count++;
                        }
                    } while ((ca as ActionEndWait) == null);
                    aWait2.SkipCount = count;
                }

                // action function
                ActionDefineFunction f = actionRecord[i] as ActionDefineFunction;
                if (f != null)
                {
                    CalcBlockOffsets(f.ActionRecord);
                }

                // action function2
                ActionDefineFunction2 f2 = actionRecord[i] as ActionDefineFunction2;
                if (f2 != null)
                {
                    CalcBlockOffsets(f2.ActionRecord);
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Examine byte code action at index in action record.
        /// </summary>
        public void Examine(int index, BaseAction a)
        {
            ActionPush    p;
            int           args;
            CodeTraverser trav;

            switch (a.Code)
            {
            case (int)ActionCode.StackSwap:
                object o1 = stack.Pop();
                object o2 = stack.Pop();
                stack.Push(o1);
                stack.Push(o2);
                break;

            case (int)ActionCode.PushDuplicate:
                stack.Push(stack.Peek());
                break;

            case (int)ActionCode.Push:
                stack.Push(a);
                break;

            // --------------------------------------

            case (int)ActionCode.CallMethod:

                ActionCallMethod cm = a as ActionCallMethod;

                stack.Pop();     // name
                stack.Pop();     // script object

                p    = stack.Pop() as ActionPush;
                args = p.GetIntValue();
                for (int i = 0; i < args; i++)
                {
                    stack.Pop();
                }
                if (args > -1)
                {
                    cm.NumArgs = args;
                }
                stack.Push(null);
                break;

            case (int)ActionCode.CallFunction:

                ActionCallFunction cf = a as ActionCallFunction;
                stack.Pop();     // name
                p    = stack.Pop() as ActionPush;
                args = p.GetIntValue();
                for (int i = 0; i < args; i++)
                {
                    stack.Pop();
                }
                if (args > -1)
                {
                    cf.NumArgs = args;
                }
                stack.Push(null);
                break;

            // --------------------------------------

            case (int)ActionCode.InitArray:

                ActionInitArray ia = a as ActionInitArray;
                p    = stack.Pop() as ActionPush;
                args = p.GetIntValue();
                for (int i = 0; i < args; i++)
                {
                    stack.Pop();
                }

                ia.NumValues = args;
                stack.Push(null);
                break;

            case (int)ActionCode.InitObject:

                ActionInitObject io = a as ActionInitObject;
                p    = stack.Pop() as ActionPush;
                args = p.GetIntValue();
                for (int i = 0; i < args; i++)
                {
                    stack.Pop();
                    stack.Pop();
                }
                io.NumProps = args;
                stack.Push(null);
                break;

            case (int)ActionCode.NewObject:

                ActionNewObject n = a as ActionNewObject;
                stack.Pop();
                p    = stack.Pop() as ActionPush;
                args = p.GetIntValue();
                for (int i = 0; i < args; i++)
                {
                    stack.Pop();
                }
                n.NumArgs = args;
                stack.Push(null);
                break;

            case (int)ActionCode.NewMethod:
                ActionNewMethod nm = a as ActionNewMethod;
                stack.Pop();
                stack.Pop();
                p    = stack.Pop() as ActionPush;
                args = p.GetIntValue();
                for (int i = 0; i < args; i++)
                {
                    stack.Pop();
                }
                nm.NumArgs = args;
                stack.Push(null);
                break;

            case (int)ActionCode.Implements:

                ActionImplements aimpl = a as ActionImplements;
                stack.Pop();     // constructor function

                // interface count
                p    = stack.Pop() as ActionPush;
                args = p.GetIntValue();

                // pop interfaces
                for (int i = 0; i < args; i++)
                {
                    stack.Pop();
                }
                aimpl.NumInterfaces = args;
                break;

            // --------------------------------------

            case (int)ActionCode.DefineFunction:
                ActionDefineFunction f = a as ActionDefineFunction;
                trav = new CodeTraverser(f.ActionRecord);
                trav.Traverse(new InvocationExaminer());
                stack.Push(null);
                break;

            case (int)ActionCode.DefineFunction2:
                ActionDefineFunction2 f2 = a as ActionDefineFunction2;
                trav = new CodeTraverser(f2.ActionRecord);
                trav.Traverse(new InvocationExaminer());
                stack.Push(null);
                break;

            // --------------------------------------

            default:
                try {
                    for (int i = 0; i < a.PopCount; i++)
                    {
                        stack.Pop();
                    }
                    for (int i = 0; i < a.PushCount; i++)
                    {
                        stack.Push(null);
                    }
                }
                // stack empty
                catch (InvalidOperationException e) {
                    if (e != null)
                    {
                    }
                    stack.Clear();
                }
                break;
            }
        }