The CodeTraverser provides a simple functionality for traversing Action lists by stepping through action lists and following branches. In opposite to SwfDotNet.IO.ByteCode.CodeWalker each index is only visited once. Action objects are handled by the IActionExaminer that is passed to the Traverse method. CodeTraverser provides a unified base functionality for code-flow analysis.
Example #1
0
        /// <summary>
        /// decompile byte code to action objects
        /// </summary>
        public ArrayList Decompile(byte[] codeblock)
        {
            LabelId = 1;
            ArrayList actionRec = ReadActions(codeblock);
            ExplodePushLists(actionRec);

            // find argument count on stack
            // e.g. for actions likecallFunction or initArray
            CodeTraverser trav = new CodeTraverser(actionRec);
            trav.Traverse(new InvocationExaminer());

            return actionRec;
        }
Example #2
0
        /// <summary>
        /// decompile byte code to action objects
        /// </summary>
        public ArrayList Decompile(byte[] codeblock)
        {
            LabelId = 1;
            ArrayList actionRec = ReadActions(codeblock);

            ExplodePushLists(actionRec);

            // find argument count on stack
            // e.g. for actions likecallFunction or initArray
            CodeTraverser trav = new CodeTraverser(actionRec);

            trav.Traverse(new InvocationExaminer());

            return(actionRec);
        }
        /// <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;
            }
        }
Example #4
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;
            }
        }