/// <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);
                }
            }
        }
Exemple #2
0
        XElement IActionVisitor <XElement, XElement> .Visit(ActionDefineFunction action, XElement param)
        {
            var res = new XElement(XActionNames.FromAction(action));

            res.Add(new XAttribute("name", action.Name),
                    new XAttribute("argc", action.Args.Count)
                    );
            var args = new XElement("args");

            foreach (var arg in action.Args)
            {
                args.Add(new XElement("String", new XAttribute("value", arg)));
            }
            res.Add(args);

            if (action.Actions.Count > 0)
            {
                var xActions = new XElement("actions");
                foreach (var subaction in action.Actions)
                {
                    xActions.Add(XAction.ToXml(subaction));
                }
                res.Add(xActions);
            }
            return(res);
        }
        /// <summary>
        /// Read <see cref="SwfOp.ByteCode.Actions.ActionPushList">ActionDefineFunction</see> from swf.
        /// including inner actions
        /// </summary>
        private ActionDefineFunction ReadActionDefineFunction(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());

            string[] parameterList = new string[numParams];
            for (int i = 0; i < numParams; i++)
            {
                parameterList[i] = BinaryStringRW.ReadString(br);
            }

            int blockSize = Convert.ToInt32(br.ReadUInt16());

            // read function body
            ArrayList            InnerActions = ReadActions(br.ReadBytes(blockSize));
            ActionDefineFunction a            = new ActionDefineFunction(name, parameterList, InnerActions);

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

            //a.ByteSize = end-start +1;

            return(a);
        }
Exemple #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++;
                }
            }
        }
Exemple #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;
            }
        }
Exemple #6
0
        ActionBase IActionVisitor <XElement, ActionBase> .Visit(ActionDefineFunction action, XElement xAction)
        {
            var xArgs    = xAction.RequiredElement("args");
            var xActions = xAction.Element("actions");

            action.Name = xAction.RequiredStringAttribute("name");
            foreach (var xArg in xArgs.Elements())
            {
                action.Args.Add(xArg.RequiredStringAttribute("value"));
            }

            if (xActions != null)
            {
                XAction.FromXml(xActions, action.Actions);
            }
            return(action);
        }
Exemple #7
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);
                }
            }
        }
Exemple #8
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;
            }
        }