Пример #1
0
        public static byte[] EditHost(byte[] raw, int localPort)
        {
            var swf = new Swf();

            swf.Decompile(raw);

            foreach (var doAbcTag in swf.DoAbcTagList)
            {
                var abc          = doAbcTag.AbcData;
                var constantPool = abc.ConstantPool;
                var localServer  = $"info@{ProductConfiguration.LocalIP}";

                foreach (var instance in abc.InstanceArray)
                {
                    var className = instance.Name.MKQName.Name;
                    var nameSpace = instance.ProtectedNamespace?.Name?.String;
                    var traits    = instance.TraitArray.GetTraits();

                    if (nameSpace != "ProductConfiguration")
                    {
                        continue;
                    }

                    foreach (var trait in traits)
                    {
                        var memberName = trait.Name.MKQName.Name;

                        if (memberName == "infoHost")
                        {
                            var method   = ((TraitGetter)trait.Trait).Method;
                            var bin      = method.MethodBody.Code;
                            var byteCode = new ByteCode(bin, abc);

                            var instructions = new List <As3Instruction>();
                            var index        = constantPool.StringArrayLength;
                            var stringInfo   = new StringInfo(index, localServer);

                            constantPool.SetStringAt(stringInfo, index);

                            instructions.Add(new As3PushString(index));
                            instructions.Add(new As3ReturnValue());

                            var count = 0;

                            foreach (var instruction in instructions)
                            {
                                byteCode.AddInstructionAt(instruction, count++);
                            }

                            while (byteCode.GetInstructions().Count > count)
                            {
                                byteCode.RemoveInstructionAt(count - 1);
                            }

                            method.MethodBody.Code = byteCode.GetBytes();
                        }
                        else if (memberName == "infoWebSocketPort")
                        {
                            var method       = ((TraitGetter)trait.Trait).Method;
                            var bin          = method.MethodBody.Code;
                            var byteCode     = new ByteCode(bin, abc);
                            var instructions = byteCode.GetInstructions();

                            for (var count = 0; count < instructions.Count; count++)
                            {
                                if (instructions[count] is As3PushShort port &&
                                    443 == port.Short)
                                {
                                    var index = constantPool.IntArrayLength;
                                    constantPool.SetIntAt(localPort, index);
                                    instructions[count] = new As3PushInt(index);
                                }
                            }

                            method.MethodBody.Code = byteCode.GetBytes();
                        }
                    }
                }
            }

            return(swf.Compile());
        }
Пример #2
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);
                }
            }
        }