Пример #1
0
        public void SetValue(As3Instruction ins, ConstantPoolInfo cPool = null)
        {
            switch (ins.Opcode)
            {
            case Opcode.PushTrue:
                ValueKind  = Types.ValueKind.True;
                ValueIndex = 0;
                break;

            case Opcode.PushFalse:
                ValueKind  = Types.ValueKind.False;
                ValueIndex = 0;
                break;

            case Opcode.PushString:
                ValueKind  = Types.ValueKind.Utf8;
                ValueIndex = (ins as As3PushString).String.Index;
                break;

            case Opcode.PushShort:
                ValueKind = Types.ValueKind.Int;
                int  pushShortValue = (ins as As3PushShort).Short;
                uint intIndex       = cPool.IndexOfInt(pushShortValue);
                if (intIndex == 0)
                {
                    ValueIndex = cPool.AddIntAtEnd(pushShortValue);
                }
                else
                {
                    ValueIndex = intIndex;
                }
                break;

            case Opcode.PushByte:
                ValueKind = Types.ValueKind.Int;
                sbyte pushByte  = (ins as As3PushByte).Byte;
                uint  byteIndex = cPool.IndexOfInt(pushByte);
                if (byteIndex == 0)
                {
                    ValueIndex = cPool.AddIntAtEnd(pushByte);
                }
                else
                {
                    ValueIndex = byteIndex;
                }
                break;

            case Opcode.PushDouble:
                ValueKind  = Types.ValueKind.Double;
                ValueIndex = (ins as As3PushDouble).DoubleIndex;
                break;

            default:
                throw new Exception();
            }
        }
Пример #2
0
        public void MoveInstruction(int index, int newIndex)
        {
            if (index == newIndex)
            {
                return;
            }

            As3Instruction ins = _instructions[index];
            int            pos = _instructionPositions[ins];

            RemoveInstructionAt(index);
            AddInstructionAt(ins, newIndex);
            if (ins is IJump)
            {
                int targetJump = pos + (ins as IJump).Offset;
                int newPos     = _instructionPositions[ins];
                (ins as IJump).Offset = targetJump - newPos;
            }
        }
Пример #3
0
        public void RemoveInstructionsByOpcodes(params Opcode[] opcodes)
        {
            int i = 0;

            while (i < _instructions.Count)
            {
                As3Instruction ins = _instructions[i];
                if (Array.IndexOf(opcodes, ins.Opcode) != -1)
                {
                    if (ins is IJump)
                    {
                        RemoveJumpAt(i);
                    }
                    else
                    {
                        RemoveInstructionAt(i);
                    }
                }
                i++;
            }
        }
Пример #4
0
        public void RemoveJumpAt(int index)
        {
            As3Instruction ins        = _instructions[index];
            int            offset     = (ins as IJump).Offset;
            int            currOffset = 0;

            if (offset > 0)
            {
                while (currOffset < offset)
                {
                    currOffset += _instructions[index].Length;
                    RemoveInstructionAt(index);
                }

                return;
            }

            if (offset < 0)
            {
                throw new Exception();
            }
        }
Пример #5
0
        public void RemoveInstructionAt(int index)
        {
            As3Instruction ins    = _instructions[index];
            int            insLen = ins.Length;
            int            pos    = _instructionPositions[ins];

            foreach (var jumpInstruction in _jumpInstructions)
            {
                int jumpInsPos = _instructionPositions[jumpInstruction as As3Instruction];
                int jumpOffset = jumpInstruction.Offset;
                int jumpInsLen = (jumpInstruction as As3Instruction).Length;
                int target     = jumpInsPos + jumpInsLen + jumpOffset;

                if (jumpOffset > 0)
                {
                    if (target > pos && pos > jumpInsPos)
                    {
                        jumpInstruction.Offset -= ins.Length;
                    }
                }
                if (jumpOffset < 0)
                {
                    if (target <= pos && pos < jumpInsPos)
                    {
                        jumpInstruction.Offset += insLen;
                    }
                }
            }

            foreach (var switchInstruction in _switchInstructions)
            {
                var   caseIns = switchInstruction as As3Instruction;
                int   casePos = _instructionPositions[caseIns];
                int[] indexes = new int[switchInstruction.CaseOffsets.Length + 1];
                for (int i = 0; i < switchInstruction.CaseOffsets.Length; i++)
                {
                    indexes[i + 1] = switchInstruction.CaseOffsets[i];
                }
                indexes[0] = switchInstruction.DefaultOffset;

                for (int i = 0; i < indexes.Length; i++)
                {
                    if (indexes[i] >= 0)
                    {
                        return;
                    }

                    if (casePos + indexes[i] <= pos && pos > casePos)
                    {
                        indexes[i] -= insLen;
                    }
                }

                switchInstruction.DefaultOffset = indexes[0];
                for (int i = 0; i < indexes.Length - 1; i++)
                {
                    switchInstruction.CaseOffsets[i] = indexes[i + 1];
                }
            }

            if (ins is IJump)
            {
                _jumpInstructions.Remove(ins as IJump);
            }

            if (ins is ICaseSwitch)
            {
                _switchInstructions.Remove(ins as ICaseSwitch);
            }

            _instructions.Remove(ins);
            _instructionPositions.Remove(ins);
            for (int j = index; j < _instructions.Count; j++)
            {
                _instructionPositions[_instructions[j]] -= insLen;
            }
        }
Пример #6
0
        public void AddInstructionAt(As3Instruction instruction, int index)
        {
            if (index >= _instructions.Count)
            {
                As3Instruction lastIns = _instructions[_instructions.Count - 1];
                _instructions.Add(instruction);

                _instructionPositions.Add(instruction, _instructionPositions[lastIns] + lastIns.Length);
                if (instruction is IJump)
                {
                    _jumpInstructions.Add(instruction as IJump);
                }


                if (instruction is ICaseSwitch)
                {
                    _switchInstructions.Add(instruction as ICaseSwitch);
                }
                return;
            }

            int pos = _instructionPositions[_instructions[index]];

            foreach (var jumpInstruction in _jumpInstructions)
            {
                int jumpInsPos = _instructionPositions[jumpInstruction as As3Instruction];
                int jumpOffset = jumpInstruction.Offset;
                int jumpInsLen = (jumpInstruction as As3Instruction).Length;
                int target     = jumpInsPos + jumpInsLen + jumpOffset;
                if (jumpOffset > 0)
                {
                    if (target > pos && pos > jumpInsPos)
                    {
                        jumpInstruction.Offset += instruction.Length;
                    }
                }
                if (jumpOffset < 0)
                {
                    if (target < pos && pos < jumpInsPos)
                    {
                        jumpInstruction.Offset -= instruction.Length;
                    }
                }

                foreach (var switchInstruction in _switchInstructions)
                {
                    var   caseIns = switchInstruction as As3Instruction;
                    int   casePos = _instructionPositions[caseIns];
                    int[] indexes = new int[switchInstruction.CaseOffsets.Length + 1];
                    for (int i = 0; i < switchInstruction.CaseOffsets.Length; i++)
                    {
                        indexes[i + 1] = switchInstruction.CaseOffsets[i];
                    }
                    indexes[0] = switchInstruction.DefaultOffset;

                    for (int i = 0; i < indexes.Length; i++)
                    {
                        if (indexes[i] >= 0)
                        {
                            throw new Exception();
                        }

                        if (casePos + indexes[i] <= pos && pos > casePos)
                        {
                            indexes[i] += instruction.Length;
                        }
                    }

                    switchInstruction.DefaultOffset = indexes[0];
                    for (int i = 0; i < indexes.Length - 1; i++)
                    {
                        switchInstruction.CaseOffsets[i] = indexes[i + 1];
                    }
                }
            }

            if (instruction is IJump)
            {
                _jumpInstructions.Add(instruction as IJump);
            }

            if (instruction is ICaseSwitch)
            {
                _switchInstructions.Add(instruction as ICaseSwitch);
            }

            _instructions.Insert(index, instruction);
            _instructionPositions.Add(instruction, pos);
            for (int j = index + 1; j < _instructions.Count; j++)
            {
                _instructionPositions[_instructions[j]] += instruction.Length;
            }
        }
Пример #7
0
        public ByteCode(byte[] byteCode, Abc abc)
        {
            _abc = abc;

            _instructions = new List <As3Instruction>();
            AbcStream stream = byteCode;

            stream.Position = 0;

            _jumpInstructions     = new List <IJump>();
            _switchInstructions   = new List <ICaseSwitch>();
            _instructionPositions = new Dictionary <As3Instruction, int>();
            while (stream.Position < stream.Length)
            {
                int pos = stream.Position;
                #region Switch

                As3Instruction instruction = null;
                Opcode         o           = (Opcode)stream.ReadByte();

                switch (o)
                {
                case Opcode.Add:
                    instruction = new As3Add();
                    break;

                case Opcode.AddD:
                    instruction = new As3AddD();
                    break;

                case Opcode.AddI:
                    instruction = new As3AddI();
                    break;

                case Opcode.ApplyType:
                    instruction = new As3ApplyType(stream.ReadU30());
                    break;

                case Opcode.AsType:
                    instruction = new As3AsType(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.AsTypeLate:
                    instruction = new As3AsTypeLate();
                    break;

                case Opcode.BitAnd:
                    instruction = new As3BitAnd();
                    break;

                case Opcode.BitNot:
                    instruction = new As3BitNot();
                    break;

                case Opcode.BitOr:
                    instruction = new As3BitOr();
                    break;

                case Opcode.BitXor:
                    instruction = new As3BitXor();
                    break;

                case Opcode.Call:
                    instruction = new As3Call(stream.ReadU30());
                    break;

                case Opcode.CallProperty:
                    instruction = new As3CallProperty(abc.ConstantPool.GetMultinameAt(stream.ReadU30()), stream.ReadU30());
                    break;

                case Opcode.CallPropLex:
                    instruction = new As3CallPropLex(abc.ConstantPool.GetMultinameAt(stream.ReadU30()), stream.ReadU30());
                    break;

                case Opcode.CallPropVoid:
                    instruction = new As3CallPropVoid(abc.ConstantPool.GetMultinameAt(stream.ReadU30()), stream.ReadU30());
                    break;

                case Opcode.CallSuper:
                    instruction = new As3CallSuper(abc.ConstantPool.GetMultinameAt(stream.ReadU30()), stream.ReadU30());
                    break;

                case Opcode.CallSuperVoid:
                    instruction = new As3CallSuperVoid(abc.ConstantPool.GetMultinameAt(stream.ReadU30()), stream.ReadU30());
                    break;

                case Opcode.CheckFilter:
                    instruction = new As3CheckFilter();
                    break;

                case Opcode.Coerce:
                    instruction = new As3Coerce(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.CoerceA:
                    instruction = new As3CoerceA();
                    break;

                case Opcode.CoerceB:
                    instruction = new As3CoerceB();
                    break;

                case Opcode.CoerceD:
                    instruction = new As3CoerceD();
                    break;

                case Opcode.CoerceI:
                    instruction = new As3CoerceI();
                    break;

                case Opcode.CoerceO:
                    instruction = new As3CoerceO();
                    break;

                case Opcode.CoerceS:
                    instruction = new As3CoerceS();
                    break;

                case Opcode.CoerceU:
                    instruction = new As3CoerceU();
                    break;

                case Opcode.Construct:
                    instruction = new As3Construct(stream.ReadU30());
                    break;

                case Opcode.ConstructProp:
                    instruction = new As3ConstructProp(abc.ConstantPool.GetMultinameAt(stream.ReadU30()), stream.ReadU30());
                    break;

                case Opcode.ConstructSuper:
                    instruction = new As3ConstructSuper(stream.ReadU30());
                    break;

                case Opcode.ConvertB:
                    instruction = new As3ConvertB();
                    break;

                case Opcode.ConvertD:
                    instruction = new As3ConvertD();
                    break;

                case Opcode.ConvertI:
                    instruction = new As3ConvertI();
                    break;

                case Opcode.ConvertO:
                    instruction = new As3ConvertO();
                    break;

                case Opcode.ConvertS:
                    instruction = new As3ConvertS();
                    break;

                case Opcode.ConvertU:
                    instruction = new As3ConvertU();
                    break;

                case Opcode.DebugLine:
                    instruction = new As3DebugLine(stream.ReadU30());
                    break;

                case Opcode.DebugFile:
                    instruction = new As3DebugFile(stream.ReadU30());
                    break;

                case Opcode.DecLocal:
                    instruction = new As3DecLocal(stream.ReadU30());
                    break;

                case Opcode.DecLocalI:
                    instruction = new As3DecLocalI(stream.ReadU30());
                    break;

                case Opcode.Decrement:
                    instruction = new As3Decrement();
                    break;

                case Opcode.DecrementI:
                    instruction = new As3DecrementI();
                    break;

                case Opcode.DeleteProperty:
                    instruction = new As3DeleteProperty(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.DeletePropertyLate:
                    instruction = new As3DeletePropertyLate();
                    break;

                case Opcode.Divide:
                    instruction = new As3Divide();
                    break;

                case Opcode.Dup:
                    instruction = new As3Dup();
                    break;

                case Opcode.Equals:
                    instruction = new As3Equals();
                    break;

                case Opcode.FindProperty:
                    instruction = new As3FindProperty(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.FindPropStrict:
                    instruction = new As3FindPropStrict(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.GetDescendants:
                    instruction = new As3GetDescendants(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.GetGlobalScope:
                    instruction = new As3GetGlobalScope();
                    break;

                case Opcode.GetLex:
                    instruction = new As3GetLex(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.GetLocal0:
                    instruction = new As3GetLocal0();
                    break;

                case Opcode.GetLocal1:
                    instruction = new As3GetLocal1();
                    break;

                case Opcode.GetLocal2:
                    instruction = new As3GetLocal2();
                    break;

                case Opcode.GetLocal3:
                    instruction = new As3GetLocal3();
                    break;

                case Opcode.GetLocal:
                    instruction = new As3GetLocal(stream.ReadU30());
                    break;

                case Opcode.GetProperty:
                    instruction = new As3GetProperty(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.GetScopeObject:
                    instruction = new As3GetScopeObject(stream.ReadU30());
                    break;

                case Opcode.GetSlot:
                    instruction = new As3GetSlot(stream.ReadU30());
                    break;

                case Opcode.GetSuper:
                    instruction = new As3GetSuper(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.GreaterEquals:
                    instruction = new As3GreaterEquals();
                    break;

                case Opcode.GreaterThan:
                    instruction = new As3GreaterThan();
                    break;

                case Opcode.HasNext2:
                    instruction = new As3HasNext2(stream.ReadU30(), stream.ReadU30());
                    break;

                case Opcode.HasNext:
                    instruction = new As3HasNext();
                    break;

                case Opcode.IfEqual:
                    instruction = new As3IfEqual(stream.ReadS24());
                    break;

                case Opcode.IfFalse:
                    instruction = new As3IfFalse(stream.ReadS24());
                    break;

                case Opcode.IfGreaterEqual:
                    instruction = new As3IfGreaterEqual(stream.ReadS24());
                    break;

                case Opcode.IfGreaterThan:
                    instruction = new As3IfGreaterThan(stream.ReadS24());
                    break;

                case Opcode.IfLessEqual:
                    instruction = new As3IfLessEqual(stream.ReadS24());
                    break;

                case Opcode.IfLessThan:
                    instruction = new As3IfLessThan(stream.ReadS24());
                    break;

                case Opcode.IfNotEqual:
                    instruction = new As3IfNotEqual(stream.ReadS24());
                    break;

                case Opcode.IfNotGreaterEqual:
                    instruction = new As3IfNotGreaterEqual(stream.ReadS24());
                    break;

                case Opcode.IfNotGreaterThan:
                    instruction = new As3IfNotGreaterThan(stream.ReadS24());
                    break;

                case Opcode.IfNotLessEqual:
                    instruction = new As3IfNotLessEqual(stream.ReadS24());
                    break;

                case Opcode.IfNotLessThan:
                    instruction = new As3IfNotLessThan(stream.ReadS24());
                    break;

                case Opcode.IfStrictEqual:
                    instruction = new As3IfStrictEqual(stream.ReadS24());
                    break;

                case Opcode.IfStrictNotEqual:
                    instruction = new As3IfStrictNotEqual(stream.ReadS24());
                    break;

                case Opcode.IfTrue:
                    instruction = new As3IfTrue(stream.ReadS24());
                    break;

                case Opcode.In:
                    instruction = new As3In();
                    break;

                case Opcode.Inclocal:
                    instruction = new As3IncLocal(stream.ReadU30());
                    break;

                case Opcode.InclocalI:
                    instruction = new As3IncLocalI(stream.ReadU30());
                    break;

                case Opcode.Increment:
                    instruction = new As3Increment();
                    break;

                case Opcode.IncrementI:
                    instruction = new As3IncrementI();
                    break;

                case Opcode.InitProperty:
                    instruction = new As3InitProperty(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.IsType:
                    instruction = new As3IsType(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.IsTypeLate:
                    instruction = new As3IsTypeLate();
                    break;

                case Opcode.Jump:
                    instruction = new As3Jump(stream.ReadS24());
                    break;

                case Opcode.Kill:
                    instruction = new As3Kill(stream.ReadU30());
                    break;

                case Opcode.Label:
                    instruction = new As3Label();
                    break;

                case Opcode.LessEquals:
                    instruction = new As3LessEquals();
                    break;

                case Opcode.LessThan:
                    instruction = new As3LessThan();
                    break;

                case Opcode.LookupSwitch:
                    int   defOffset   = stream.ReadS24();
                    int[] caseOffsets = new int[stream.ReadU30() + 1];
                    for (int i = 0; i < caseOffsets.Length; ++i)
                    {
                        caseOffsets[i] = stream.ReadS24();
                    }
                    instruction = new As3LookupSwitch(defOffset, caseOffsets);
                    break;

                case Opcode.LShift:
                    instruction = new As3LShift();
                    break;

                case Opcode.Modulo:
                    instruction = new As3Modulo();
                    break;

                case Opcode.Multiply:
                    instruction = new As3Multiply();
                    break;

                case Opcode.MultiplyI:
                    instruction = new As3MultiplyI();
                    break;

                case Opcode.Negate:
                    instruction = new As3Negate();
                    break;

                case Opcode.NegateI:
                    instruction = new As3NegateI();
                    break;

                case Opcode.NewActivation:
                    instruction = new As3NewActivation();
                    break;

                case Opcode.NewArray:
                    instruction = new As3NewArray(stream.ReadU30());
                    break;

                case Opcode.NewCatch:
                    instruction = new As3NewCatch(stream.ReadU30());
                    break;

                case Opcode.NewClass:
                    instruction = new As3NewClass(stream.ReadU30());
                    break;

                case Opcode.NewFunction:
                    instruction = new As3NewFunction(stream.ReadU30());
                    break;

                case Opcode.NewObject:
                    instruction = new As3NewObject(stream.ReadU30());
                    break;

                case Opcode.NextName:
                    instruction = new As3NextName();
                    break;

                case Opcode.NextValue:
                    instruction = new As3NextValue();
                    break;

                case Opcode.Nop:
                    instruction = new As3Nop();
                    break;

                case Opcode.Not:
                    instruction = new As3Not();
                    break;

                case Opcode.Pop:
                    instruction = new As3Pop();
                    break;

                case Opcode.PopScope:
                    instruction = new As3PopScope();
                    break;

                case Opcode.PushByte:
                    instruction = new As3PushByte((sbyte)stream.ReadByte());
                    break;

                case Opcode.PushDouble:
                    instruction = new As3PushDouble(stream.ReadU30());
                    break;

                case Opcode.PushFalse:
                    instruction = new As3PushFalse();
                    break;

                case Opcode.PushInt:
                    instruction = new As3PushInt(stream.ReadU30());
                    break;

                case Opcode.PushNan:
                    instruction = new As3PushNan();
                    break;

                case Opcode.PushNull:
                    instruction = new As3PushNull();
                    break;

                case Opcode.PushScope:
                    instruction = new As3PushScope();
                    break;

                case Opcode.PushShort:
                    instruction = new As3PushShort(stream.ReadU30());
                    break;

                case Opcode.PushString:
                    instruction = new As3PushString(abc.ConstantPool.GetStringAt(stream.ReadU30()));
                    break;

                case Opcode.PushTrue:
                    instruction = new As3PushTrue();
                    break;

                case Opcode.PushUInt:
                    instruction = new As3PushUInt(stream.ReadU30());
                    break;

                case Opcode.PushUndefined:
                    instruction = new As3PushUndefined();
                    break;

                case Opcode.PushWith:
                    instruction = new As3PushWith();
                    break;

                case Opcode.ReturnValue:
                    instruction = new As3ReturnValue();
                    break;

                case Opcode.ReturnVoid:
                    instruction = new As3ReturnVoid();
                    break;

                case Opcode.RShift:
                    instruction = new As3RShift();
                    break;

                case Opcode.SetLocal0:
                    instruction = new As3SetLocal0();
                    break;

                case Opcode.SetLocal1:
                    instruction = new As3SetLocal1();
                    break;

                case Opcode.SetLocal2:
                    instruction = new As3SetLocal2();
                    break;

                case Opcode.SetLocal3:
                    instruction = new As3SetLocal3();
                    break;

                case Opcode.SetLocal:
                    instruction = new As3SetLocal(stream.ReadU30());
                    break;

                case Opcode.SetProperty:
                    instruction = new As3SetProperty(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.SetSlot:
                    instruction = new As3SetSlot(stream.ReadU30());
                    break;

                case Opcode.SetSuper:
                    instruction = new As3SetSuper(abc.ConstantPool.GetMultinameAt(stream.ReadU30()));
                    break;

                case Opcode.StrictEquals:
                    instruction = new As3StrictEquals();
                    break;

                case Opcode.Subtract:
                    instruction = new As3Subtract();
                    break;

                case Opcode.SubtractI:
                    instruction = new As3SubtractI();
                    break;

                case Opcode.Swap:
                    instruction = new As3Swap();
                    break;

                case Opcode.Throw:
                    instruction = new As3Throw();
                    break;

                case Opcode.TypeOf:
                    instruction = new As3TypeOf();
                    break;

                case Opcode.URShift:
                    instruction = new As3URShift();
                    break;

                case Opcode.SI8:
                    instruction = new As3SI8();
                    break;

                case Opcode.SI16:
                    instruction = new As3SI16();
                    break;

                case Opcode.SI32:
                    instruction = new As3SI32();
                    break;

                case Opcode.SF32:
                    instruction = new As3SF32();
                    break;

                case Opcode.LI8:
                    instruction = new As3LI8();
                    break;

                case Opcode.LI16:
                    instruction = new As3LI16();
                    break;

                case Opcode.LI32:
                    instruction = new As3LI32();
                    break;

                case Opcode.LF32:
                    instruction = new As3LF32();
                    break;

                case Opcode.LF64:
                    instruction = new As3LF64();
                    break;

                case Opcode.SXI1:
                    instruction = new As3SX1();
                    break;

                case Opcode.SXI8:
                    instruction = new As3SXI8();
                    break;

                case Opcode.SXI16:
                    instruction = new As3SX16();

                    break;

                default:
                    throw new Exception("Unknown opcode: " + o);
                }

                #endregion

                _instructions.Add(instruction);

                _instructionPositions[instruction] = pos;

                if (instruction is IJump)
                {
                    _jumpInstructions.Add(instruction as IJump);
                }


                if (instruction is ICaseSwitch)
                {
                    _switchInstructions.Add(instruction as ICaseSwitch);
                }
            }
        }