/// <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; } }
/// <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; } }