示例#1
0
        private PacketValue[] GetOutgoingStructure(ASCode code, Local getLocal)
        {
            List <PacketValue> structure = new List <PacketValue>();

            for (int i = 0; i < code.Count; i++)
            {
                ASInstruction instruction = code[i];
                if (instruction == getLocal)
                {
                    break;
                }
                if (!Local.IsGetLocal(instruction.OP))
                {
                    continue;
                }

                Local local = (Local)instruction;
                if (local.Register != getLocal.Register)
                {
                    continue;
                }

                for (i += 1; i < code.Count; i++)
                {
                    ASInstruction next = code[i];
                    if (next.OP != OPCode.CallPropVoid)
                    {
                        continue;
                    }

                    CallPropVoidIns callPropVoid = (CallPropVoidIns)next;
                    if (callPropVoid.PropertyName.Name != "push")
                    {
                        continue;
                    }

                    ASInstruction previous = code[i - 1];
                    if (previous.OP == OPCode.GetProperty)
                    {
                        ASClass        classToCheck = Class;
                        GetPropertyIns getProperty  = (GetPropertyIns)previous;
                        ASMultiname    propertyName = getProperty.PropertyName;

                        ASInstruction beforeGetProp = code[i - 2];
                        if (beforeGetProp.OP == OPCode.GetLex)
                        {
                            GetLexIns getLex = (GetLexIns)beforeGetProp;
                            classToCheck = classToCheck.GetABC().GetClass(getLex.TypeName);
                        }

                        if (!TryGetPacketValue(propertyName, classToCheck, out PacketValue piece))
                        {
                            return(null);
                        }
                        structure.Add(piece);
                    }
                }
            }
            return(structure.Count == 0 ? null : structure.ToArray());
        }
示例#2
0
        private string GetOutgoingStructure(ASCode code, Local getLocal)
        {
            string structure = null;

            for (int i = 0; i < code.Count; i++)
            {
                ASInstruction instruction = code[i];
                if (instruction == getLocal)
                {
                    break;
                }
                if (!Local.IsGetLocal(instruction.OP))
                {
                    continue;
                }

                var local = (Local)instruction;
                if (local.Register != getLocal.Register)
                {
                    continue;
                }

                for (i += 1; i < code.Count; i++)
                {
                    ASInstruction next = code[i];
                    if (next.OP != OPCode.CallPropVoid)
                    {
                        continue;
                    }

                    var callPropVoid = (CallPropVoidIns)next;
                    if (callPropVoid.PropertyName.Name != "push")
                    {
                        continue;
                    }

                    ASInstruction previous = code[i - 1];
                    if (previous.OP == OPCode.GetProperty)
                    {
                        ASClass     classToCheck = Class;
                        var         getProperty  = (GetPropertyIns)previous;
                        ASMultiname propertyName = getProperty.PropertyName;

                        ASInstruction beforeGetProp = code[i - 2];
                        if (beforeGetProp.OP == OPCode.GetLex)
                        {
                            var getLex = (GetLexIns)beforeGetProp;
                            classToCheck = classToCheck.GetABC().GetClass(getLex.TypeName);
                        }

                        if (!TryGetStructurePiece(propertyName, classToCheck, out char piece))
                        {
                            return(null);
                        }
                        structure += piece;
                    }
                }
            }
            return(structure);
        }
示例#3
0
        private ASMultiname GetTraitType(ASContainer container, ASMultiname traitName)
        {
            if (container == null)
            {
                return(traitName);
            }

            return(container.GetTraits(TraitKind.Slot, TraitKind.Constant, TraitKind.Getter)
                   .FirstOrDefault(t => t.QName == traitName)?.Type);
        }
示例#4
0
        private ASClass GetMessageParser()
        {
            ABCFile    abc      = Class.GetABC();
            ASInstance instance = Class.Instance;

            ASInstance superInstance = abc.GetInstance(instance.Super);

            if (superInstance == null)
            {
                superInstance = instance;
            }

            ASMethod parserGetterMethod = superInstance.GetGetter("parser")?.Method;

            if (parserGetterMethod == null)
            {
                return(null);
            }

            IEnumerable <ASMethod> methods = instance.GetMethods();

            foreach (ASMethod method in methods.Concat(new[] { instance.Constructor }))
            {
                ASCode code = method.Body.ParseCode();
                foreach (ASInstruction instruction in code)
                {
                    ASMultiname multiname = null;
                    if (instruction.OP == OPCode.FindPropStrict)
                    {
                        var findPropStrictIns = (FindPropStrictIns)instruction;
                        multiname = findPropStrictIns.PropertyName;
                    }
                    else if (instruction.OP == OPCode.GetLex)
                    {
                        var getLexIns = (GetLexIns)instruction;
                        multiname = getLexIns.TypeName;
                    }
                    else
                    {
                        continue;
                    }

                    foreach (ASClass refClass in abc.GetClasses(multiname))
                    {
                        ASInstance refInstance = refClass.Instance;
                        if (refInstance.ContainsInterface(parserGetterMethod.ReturnType.Name))
                        {
                            return(refClass);
                        }
                    }
                }
            }
            return(null);
        }
 protected void ResolveMultiname(ASMachine machine, ASMultiname multiname)
 {
     if (multiname.IsNameNeeded)
     {
         object name = machine.Values.Pop();
     }
     if (multiname.IsNamespaceNeeded)
     {
         object @namespace = machine.Values.Pop();
     }
 }
        protected int ResolveMultinamePops(ASMultiname multiname)
        {
            int popCount = 0;

            if (multiname.IsNameNeeded)
            {
                popCount++;
            }
            if (multiname.IsNamespaceNeeded)
            {
                popCount++;
            }
            return(popCount);
        }
示例#7
0
 public void Write(ASMultiname multiname)
 {
     if (multiname?.Kind == MultinameKind.TypeName)
     {
         Write(multiname.QName);
         Write(multiname.TypeIndices.Count);
         foreach (ASMultiname type in multiname.GetTypes())
         {
             Write(type);
         }
     }
     else if (multiname == null ||
              HGame.IsValidIdentifier(multiname.Name, true))
     {
         Write(multiname?.Name ?? "*");
     }
 }
示例#8
0
 protected virtual void WriteMultinameHashData(BinaryWriter hashInput, ASMultiname asMultiname)
 {
     hashInput.Write((byte)asMultiname.MultinameType);
     switch (asMultiname.ObjName)
     {
     case "int":
     case "Class":
     case "Array":
     case "String":
     case "Boolean":
     case "Function":
     {
         hashInput.Write(asMultiname.ObjName);
         break;
     }
     }
 }
示例#9
0
        private bool TryGetStructurePiece(ASMultiname multiname, ASClass @class, out char piece)
        {
            ASMultiname returnValueType = multiname;

            if (@class != null)
            {
                returnValueType = GetTraitType(@class, multiname) ?? GetTraitType(@class.Instance, multiname);
            }

            switch (returnValueType.Name.ToLower())
            {
            case "int":
            case "readint":
            case "gettimer": piece = 'i'; break;

            case "byte":
            case "readbyte": piece = 'b'; break;

            case "double":
            case "readdouble": piece = 'd'; break;

            case "string":
            case "readstring": piece = 's'; break;

            case "boolean":
            case "readboolean": piece = 'B'; break;

            case "array": piece = char.MinValue; break;

            default:
            {
                if (!IsOutgoing && !HGame.IsValidIdentifier(returnValueType.Name, true))
                {
                    piece = 'i';     // This reference call is most likely towards 'readInt'
                }
                else
                {
                    piece = char.MinValue;
                }
                break;
            }
            }
            return(piece != char.MinValue);
        }
示例#10
0
        private bool TryGetPacketValue(ASMultiname multiname, ASClass @class, out PacketValue value)
        {
            ASMultiname returnValueType = multiname;

            if (@class != null)
            {
                returnValueType = GetTraitType(@class, multiname) ?? GetTraitType(@class.Instance, multiname);
            }

            switch (returnValueType.Name.ToLower())
            {
            case "int":
            case "readint":
            case "gettimer": value = PacketValue.Integer; break;

            case "byte":
            case "readbyte": value = PacketValue.Byte; break;

            case "double":
            case "readdouble": value = PacketValue.Double; break;

            case "string":
            case "readstring": value = PacketValue.String; break;

            case "boolean":
            case "readboolean": value = PacketValue.Boolean; break;

            case "array": value = PacketValue.Unknown; break;

            default:
            {
                if (!IsOutgoing && !HGame.IsValidIdentifier(returnValueType.Name, true))
                {
                    value = PacketValue.Integer;         // This reference call is most likely towards 'readInt'
                }
                else
                {
                    value = PacketValue.Unknown;
                }
                break;
            }
            }
            return(value != PacketValue.Unknown);
        }
示例#11
0
        protected ASMethod FindVerifyMethod(ASInstance instance, ABCFile abc, out int rsaStart)
        {
            List <MethodGetterSetterTrait> methodTraits =
                instance.FindTraits <MethodGetterSetterTrait>(TraitType.Method);

            rsaStart = -1;
            foreach (MethodGetterSetterTrait mgsTrait in methodTraits)
            {
                ASMethod method = mgsTrait.Method;

                if (method.ReturnType.ObjName != "void")
                {
                    continue;
                }
                if (method.Parameters.Count != 1)
                {
                    continue;
                }

                using (var code = new FlashReader(method.Body.Bytecode))
                {
                    while (code.Position != code.Length)
                    {
                        OPCode op = code.ReadOP();
                        if (op != OPCode.GetLex)
                        {
                            continue;
                        }

                        int         typeIndex = code.Read7BitEncodedInt();
                        ASMultiname type      = abc.Constants.Multinames[typeIndex];

                        if (type?.ObjName == "RSAKey")
                        {
                            rsaStart = code.Position;
                            return(method);
                        }
                    }
                }
            }
            return(null);
        }
示例#12
0
        /// <summary>
        ///     Modifies the "ClientHelloMessageComposer" (Packet 4000) class
        ///     to send the current environment instead of the protocol revision.
        /// </summary>
        public void PatchClientHelloMessageComposer()
        {
            var abc = _flash.AbcGame;

            // Grab ClientHelloMessageComposer.
            var composerClass = MessagesOutgoing[4000].Clazz;

            // Find CommunicationUtils.
            var communicationUtilsClass  = _lookup.Get(HabboClass.CommunicationUtils);
            var communicationUtilsMethod = communicationUtilsClass.Traits
                                           .AsParallel()
                                           .FirstOrDefault(x => x.IsStatic &&
                                                           x.Kind == TraitKind.Method &&
                                                           x.Method.Parameters.Count == 2 &&
                                                           x.Method.Parameters[1].IsOptional &&
                                                           x.Method.ReturnType.Name.Equals("String"));

            if (communicationUtilsMethod == null)
            {
                throw new ApplicationException("Unable to find communicationUtilsMethod.");
            }

            // Find com.sulake.habbo.communication.demo:IncomingMessages.
            var incomingMessagesClass  = _lookup.Get(HabboClass.IncomingMessages);
            var incomingMessagesMethod = incomingMessagesClass.Instance.Traits
                                         .AsParallel()
                                         .Where(x => x.Kind == TraitKind.Method &&
                                                x.Method.Parameters.Count == 1 &&
                                                x.Method.Parameters[0].Type.Name.Equals("Event") &&
                                                x.Method.Parameters[0].IsOptional &&
                                                x.Method.ReturnType.Name.Equals("void"))
                                         .Select(x => x.Method)
                                         .FirstOrDefault();

            if (incomingMessagesMethod == null)
            {
                throw new ApplicationException("Unable to find incomingMessagesMethod.");
            }

            var incomingMessagesCode = incomingMessagesMethod.Body.ParseCode();

            // Modify the method of IncomingMessages.
            var constructComposer = incomingMessagesCode
                                    .Where(x => x.OP == OPCode.ConstructProp && ((ConstructPropIns)x).PropertyName.NameIndex == composerClass.QName.NameIndex)
                                    .Cast <ConstructPropIns>()
                                    .First();

            // IncomingMessages: Add an argument when constructing the message.
            constructComposer.ArgCount = 1;

            // IncomingMessages: Add the argument value.
            incomingMessagesCode.InsertRange(incomingMessagesCode.IndexOf(constructComposer), new ASInstruction[]
            {
                new GetLexIns(abc, abc.Pool.Multinames.IndexOf(communicationUtilsClass.QName)),
                new PushStringIns(abc, "environment"),
                new CallPropertyIns(abc, communicationUtilsMethod.QNameIndex, 1),
                new CoerceSIns()
            });

            // IncomingMessages: Increase stack.
            incomingMessagesMethod.Body.MaxStack += 4;
            incomingMessagesMethod.Body.Code      = incomingMessagesCode.ToArray();

            // Modify the constructor of ClientHelloMessageComposer.
            var composerConstructor = composerClass.Instance.Constructor;
            var composerCode        = composerConstructor.Body.ParseCode();

            // ClientHelloMessageComposer: Add "String" parameter.
            composerConstructor.Parameters.Add(new ASParameter(abc.Pool, composerConstructor)
            {
                TypeIndex = abc.Pool.GetMultinameIndex("String")
            });

            // ClientHelloMessageComposer: Add "environmentId" variable.
            var composerSlotQName = new ASMultiname(abc.Pool)
            {
                NameIndex      = abc.Pool.AddConstant("environmentId"),
                Kind           = MultinameKind.QName,
                NamespaceIndex = 1
            };

            var composerSlot = new ASTrait(abc)
            {
                Kind       = TraitKind.Slot,
                QNameIndex = abc.Pool.AddConstant(composerSlotQName),
                TypeIndex  = abc.Pool.GetMultinameIndex("String")
            };

            composerClass.Instance.Traits.Add(composerSlot);

            // ClientHelloMessageComposer: Set parameter of constructor to "environmentId".
            composerCode.InsertRange(composerCode.Count - 1, new ASInstruction[]
            {
                new GetLocal1Ins(),
                new FindPropertyIns(abc, composerSlot.QNameIndex),
                new SwapIns(),
                new SetPropertyIns(abc, composerSlot.QNameIndex),
            });

            composerConstructor.Body.LocalCount = 2;
            composerConstructor.Body.MaxStack   = 2;
            composerConstructor.Body.Code       = composerCode.ToArray();

            // Modify the method that returns packet as array.
            var getArrayMethod = composerClass.Instance.Traits
                                 .AsParallel()
                                 .First(x => x.Kind == TraitKind.Method &&
                                        x.Method.Parameters.Count == 0 &&
                                        x.Method.ReturnType.Name.Equals("Array"));

            var getArrayCode = getArrayMethod.Method.Body.ParseCode();

            // getArray: Remove everything until constructing array.
            getArrayCode.Clear();
            getArrayCode.AddRange(new ASInstruction[]
            {
                new GetLocal0Ins(),
                new PushScopeIns(),

                new PushStringIns(abc, Revision),
                new PushStringIns(abc, RevisionProtocol),
                new PushIntIns(abc, 3), // Android.
                new PushIntIns(abc, 1),
                new GetLexIns(abc, composerSlot.QNameIndex),

                new NewArrayIns(5),
                new ReturnValueIns(),
            });

            // getArray: Apply patch.
            getArrayMethod.Method.Body.MaxStack   = 5;
            getArrayMethod.Method.Body.LocalCount = 1;
            getArrayMethod.Method.Body.Code       = getArrayCode.ToArray();

            // ClientHelloMessageComposer: Clean class.
            composerClass.Instance.Traits.Remove(composerClass.Instance.Traits.First(x => x.Kind == TraitKind.Slot && x.QNameIndex != composerSlot.QNameIndex));
        }
示例#13
0
        private string GetIncomingStructure(ASInstance instance, ASMethod method)
        {
            if (method.Body.Exceptions.Count > 0)
            {
                return(null);
            }

            ASCode code = method.Body.ParseCode();

            if (code.JumpExits.Count > 0 || code.SwitchExits.Count > 0)
            {
                return(null);
            }

            string  structure = null;
            ABCFile abc       = method.GetABC();

            for (int i = 0; i < code.Count; i++)
            {
                ASInstruction instruction = code[i];
                if (instruction.OP != OPCode.GetLocal_1)
                {
                    continue;
                }

                ASInstruction next = code[++i];
                switch (next.OP)
                {
                case OPCode.CallProperty:
                {
                    var callProperty = (CallPropertyIns)next;
                    if (callProperty.ArgCount > 0)
                    {
                        ASMultiname   propertyName = null;
                        ASInstruction previous     = code[i - 2];

                        switch (previous.OP)
                        {
                        case OPCode.GetLex:
                        {
                            var getLex = (GetLexIns)previous;
                            propertyName = getLex.TypeName;
                            break;
                        }

                        case OPCode.ConstructProp:
                        {
                            var constructProp = (ConstructPropIns)previous;
                            propertyName = constructProp.PropertyName;
                            break;
                        }

                        case OPCode.GetLocal_0:
                        {
                            propertyName = instance.QName;
                            break;
                        }
                        }

                        ASInstance innerInstance = abc.GetInstance(propertyName);
                        ASMethod   innerMethod   = innerInstance.GetMethod(callProperty.PropertyName.Name, null, callProperty.ArgCount);
                        if (innerMethod == null)
                        {
                            ASClass innerClass = abc.GetClass(propertyName);
                            innerMethod = innerClass.GetMethod(callProperty.PropertyName.Name, null, callProperty.ArgCount);
                        }

                        string innerStructure = GetIncomingStructure(innerInstance, innerMethod);
                        if (string.IsNullOrWhiteSpace(innerStructure))
                        {
                            return(null);
                        }
                        structure += innerStructure;
                    }
                    else
                    {
                        if (!TryGetStructurePiece(callProperty.PropertyName, null, out char piece))
                        {
                            return(null);
                        }
                        structure += piece;
                    }
                    break;
                }

                case OPCode.ConstructProp:
                {
                    var        constructProp = (ConstructPropIns)next;
                    ASInstance innerInstance = abc.GetInstance(constructProp.PropertyName);

                    string innerStructure = GetIncomingStructure(innerInstance, innerInstance.Constructor);
                    if (string.IsNullOrWhiteSpace(innerStructure))
                    {
                        return(null);
                    }
                    structure += innerStructure;
                    break;
                }

                case OPCode.ConstructSuper:
                {
                    ASInstance superInstance = abc.GetInstance(instance.Super);

                    string innerStructure = GetIncomingStructure(superInstance, superInstance.Constructor);
                    if (string.IsNullOrWhiteSpace(innerStructure))
                    {
                        return(null);
                    }
                    structure += innerStructure;
                    break;
                }

                case OPCode.CallSuper:
                {
                    var        callSuper     = (CallSuperIns)next;
                    ASInstance superInstance = abc.GetInstance(instance.Super);
                    ASMethod   superMethod   = superInstance.GetMethod(callSuper.MethodName.Name, null, callSuper.ArgCount);

                    string innerStructure = GetIncomingStructure(superInstance, superMethod);
                    if (string.IsNullOrWhiteSpace(innerStructure))
                    {
                        return(null);
                    }
                    structure += innerStructure;
                    break;
                }

                case OPCode.CallPropVoid:
                {
                    var callPropVoid = (CallPropVoidIns)next;
                    if (callPropVoid.ArgCount != 0)
                    {
                        return(null);
                    }

                    if (!TryGetStructurePiece(callPropVoid.PropertyName, null, out char piece))
                    {
                        return(null);
                    }
                    structure += piece;
                    break;
                }

                default: return(null);
                }
            }
            return(structure);
        }
示例#14
0
        public ASClass GetIncomingParser(ASInstance incomingInstance)
        {
            if (_incomingParsersCache.ContainsKey(incomingInstance))
            {
                return(_incomingParsersCache[incomingInstance]);
            }

            ASClass parserClass = null;
            ABCFile abc         = incomingInstance.ABC;

            try
            {
                using (var codeOut = new FlashReader(
                           incomingInstance.Constructor.Body.Bytecode))
                {
                    while (codeOut.IsDataAvailable)
                    {
                        OPCode   op     = codeOut.ReadOP();
                        object[] values = codeOut.ReadValues(op);
                        if (op != OPCode.GetLex)
                        {
                            continue;
                        }

                        var         getLexIndex = (int)values[0];
                        ASMultiname getLexName  = abc.Constants.Multinames[getLexIndex];
                        parserClass = abc.FindClassByName(getLexName.ObjName);
                        if (parserClass != null)
                        {
                            return(parserClass);
                        }
                        break;
                    }
                }

                ASInstance incomingSuperInstance = abc.FindInstanceByName(
                    incomingInstance.SuperType.ObjName);

                ASMultiname parserReturnType = incomingSuperInstance
                                               .FindGetter("parser").Method.ReturnType;

                SlotConstantTrait parserSlot = incomingSuperInstance
                                               .FindSlot("*", parserReturnType.ObjName);

                foreach (ASTrait trait in incomingInstance.Traits)
                {
                    if (trait.TraitType != TraitType.Method)
                    {
                        continue;
                    }

                    var mgsTrait = (MethodGetterSetterTrait)trait.Data;
                    if (mgsTrait.Method.Parameters.Count != 0)
                    {
                        continue;
                    }

                    using (var codeOut = new FlashReader(
                               mgsTrait.Method.Body.Bytecode))
                    {
                        while (codeOut.IsDataAvailable)
                        {
                            OPCode   op     = codeOut.ReadOP();
                            object[] values = codeOut.ReadValues(op);
                            if (op != OPCode.GetLex)
                            {
                                continue;
                            }

                            var         getLexIndex = (int)values[0];
                            ASMultiname getLexType  = abc.Constants.Multinames[getLexIndex];
                            if (getLexType.ObjName != parserSlot.ObjName)
                            {
                                continue;
                            }

                            parserClass = abc.FindClassByName(mgsTrait.Method.ReturnType.ObjName);
                            if (parserClass != null)
                            {
                                return(parserClass);
                            }
                            break;
                        }
                    }
                }
                return(parserClass);
            }
            finally
            {
                if (parserClass != null)
                {
                    _incomingParsersCache[incomingInstance] = parserClass;
                }
            }
        }
示例#15
0
        public bool FindMessageInstances()
        {
            if (OutgoingTypes.Count > 0 &&
                IncomingTypes.Count > 0)
            {
                return(true);
            }

            ABCFile abc           = ABCFiles[2];
            ASClass habboMessages = abc.FindClassByName("HabboMessages");

            if (habboMessages == null || habboMessages.Traits.Count < 2)
            {
                return(false);
            }

            ASTrait incomingMap = habboMessages.Traits[0];
            ASTrait outgoingMap = habboMessages.Traits[1];

            using (var mapReader = new FlashReader(
                       habboMessages.Constructor.Body.Bytecode.ToArray()))
            {
                while (mapReader.Position != mapReader.Length)
                {
                    OPCode op = mapReader.ReadOP();
                    if (op != OPCode.GetLex)
                    {
                        continue;
                    }

                    int  mapTypeIndex = mapReader.Read7BitEncodedInt();
                    bool isOutgoing   = (mapTypeIndex == outgoingMap.TypeIndex);
                    bool isIncoming   = (mapTypeIndex == incomingMap.TypeIndex);
                    if (!isOutgoing && !isIncoming)
                    {
                        continue;
                    }

                    op = mapReader.ReadOP();
                    if (op != OPCode.PushShort && op != OPCode.PushByte)
                    {
                        continue;
                    }

                    ushort header = 0;
                    if (op == OPCode.PushByte)
                    {
                        header = mapReader.ReadByte();
                    }
                    else
                    {
                        header = (ushort)mapReader.Read7BitEncodedInt();
                    }

                    op = mapReader.ReadOP();
                    if (op != OPCode.GetLex)
                    {
                        continue;
                    }

                    int         messageTypeIndex = mapReader.Read7BitEncodedInt();
                    ASMultiname messageType      = abc.Constants.Multinames[messageTypeIndex];
                    ASClass     messageInstance  = abc.FindClassByName(messageType.ObjName);

                    if (isOutgoing)
                    {
                        OutgoingTypes[header] = messageInstance;
                    }
                    else if (isIncoming)
                    {
                        IncomingTypes[header] = messageInstance;
                    }
                }
            }

            return(OutgoingTypes.Count > 0 &&
                   IncomingTypes.Count > 0);
        }
示例#16
0
        protected void ScanForMessageReference(Dictionary <string, ASClass> messageClasses, ASClass asClass, ASMethod method, int traitIndex, int messageRefCount = 0)
        {
            ABCFile abc          = asClass.ABC;
            ASClass messageClass = null;

            using (var outCode = new FlashReader(method.Body.Bytecode))
            {
                while (outCode.IsDataAvailable)
                {
                    OPCode   op     = outCode.ReadOP();
                    object[] values = outCode.ReadValues(op);
                    switch (op)
                    {
                    case OPCode.NewFunction:
                    {
                        var      newFuncIndex  = (int)values[0];
                        ASMethod newFuncMethod = abc.Methods[newFuncIndex];
                        ScanForMessageReference(messageClasses, asClass, newFuncMethod, traitIndex, messageRefCount);
                        break;
                    }

                    case OPCode.ConstructProp:
                    {
                        var constructPropIndex = (int)values[0];
                        if (messageClass != null)
                        {
                            ASMultiname constructPropType =
                                abc.Constants.Multinames[constructPropIndex];

                            if (constructPropType.ObjName == messageClass.Instance.Type.ObjName)
                            {
                                if (!_messageReferencesCache.ContainsKey(messageClass))
                                {
                                    _messageReferencesCache[messageClass] = new List <Tuple <ASMethod, int> >();
                                }

                                _messageReferencesCache[messageClass].Add(
                                    new Tuple <ASMethod, int>(method, (traitIndex + (++messageRefCount))));
                            }
                            messageClass = null;
                        }
                        break;
                    }

                    case OPCode.FindPropStrict:
                    {
                        var    findPropStrictIndex   = (int)values[0];
                        string findPropStrictObjName = abc.Constants
                                                       .Multinames[findPropStrictIndex].ObjName;

                        if (messageClasses.ContainsKey(findPropStrictObjName))
                        {
                            messageClass = messageClasses[findPropStrictObjName];

                            // Incoming messages currently not supported.
                            if (IncomingTypes.ContainsValue(messageClass))
                            {
                                messageClass = null;
                            }
                        }
                        break;
                    }
                    }
                }
            }
        }
示例#17
0
        public bool ReplaceRSA(int exponent, string modulus)
        {
            ABCFile abc          = ABCFiles[2];
            int     modulusIndex = abc.Constants.AddString(modulus);

            int exponentIndex = abc.Constants
                                .AddString(exponent.ToString("x"));

            int        rsaStart  = 0;
            ASInstance commClass = abc.FindInstanceByName("HabboCommunicationDemo");
            ASMethod   verifier  = FindVerifyMethod(commClass, abc, out rsaStart);

            using (var inCode = new FlashReader(verifier.Body.Bytecode))
                using (var outCode = new FlashWriter(inCode.Length))
                {
                    bool searchingKeys = true;
                    inCode.Position = rsaStart;
                    outCode.Write(inCode.ToArray(), 0, rsaStart);

                    while (inCode.Position != inCode.Length)
                    {
                        byte codeByte = inCode.ReadByte();
                        outCode.Write(codeByte);

                        if (!searchingKeys)
                        {
                            outCode.Write(inCode.ToArray(),
                                          inCode.Position, inCode.Length - inCode.Position);

                            break;
                        }
                        switch ((OPCode)codeByte)
                        {
                        case OPCode.GetLex:
                        {
                            outCode.Position--;
                            outCode.WriteOP(OPCode.PushString);

                            int         typeIndex = inCode.Read7BitEncodedInt();
                            ASMultiname type      = abc.Constants.Multinames[typeIndex];

                            inCode.ReadOP();
                            inCode.Read7BitEncodedInt();
                            inCode.Read7BitEncodedInt();

                            if (modulusIndex > 0)
                            {
                                outCode.Write7BitEncodedInt(modulusIndex);
                                modulusIndex = -1;
                            }
                            else if (searchingKeys)
                            {
                                outCode.Write7BitEncodedInt(exponentIndex);
                                searchingKeys = false;
                            }
                            break;
                        }

                        case OPCode.PushString:
                        {
                            int    stringIndex = inCode.Read7BitEncodedInt();
                            string value       = abc.Constants.Strings[stringIndex];

                            if (string.IsNullOrWhiteSpace(Modulus))
                            {
                                Modulus = value;
                                outCode.Write7BitEncodedInt(modulusIndex);
                            }
                            else if (string.IsNullOrWhiteSpace(Exponent))
                            {
                                Exponent = value;
                                outCode.Write7BitEncodedInt(exponentIndex);

                                searchingKeys = false;
                            }
                            break;
                        }

                        default: continue;
                        }
                    }

                    verifier.Body.Bytecode = outCode.ToArray();
                    if (!searchingKeys)
                    {
                        return(true);
                    }
                }
            return(false);
        }
示例#18
0
        private PacketValue[] GetOutgoingStructure(ASClass @class, ASMultiname propertyName)
        {
            ASMethod constructor = @class.Instance.Constructor;

            if (constructor.Body.Exceptions.Count > 0)
            {
                return(null);
            }

            ASCode code = constructor.Body.ParseCode();

            if (code.JumpExits.Count > 0 || code.SwitchExits.Count > 0)
            {
                return(null);
            }

            List <PacketValue> structure = new List <PacketValue>();

            for (int i = 0; i < code.Count; i++)
            {
                ASInstruction instruction = code[i];
                if (instruction.OP == OPCode.NewArray)
                {
                    NewArrayIns newArray = (NewArrayIns)instruction;
                    if (newArray.ArgCount > 0)
                    {
                        PacketValue[] structurePieces = new PacketValue[newArray.ArgCount];
                        for (int j = i - 1, length = newArray.ArgCount; j >= 0; j--)
                        {
                            ASInstruction previous = code[j];
                            if (Local.IsGetLocal(previous.OP) && previous.OP != OPCode.GetLocal_0)
                            {
                                Local       local     = (Local)previous;
                                ASParameter parameter = constructor.Parameters[local.Register - 1];

                                if (!TryGetPacketValue(parameter.Type, null, out PacketValue piece))
                                {
                                    return(null);
                                }
                                structurePieces[--length] = piece;
                            }
                            if (length == 0)
                            {
                                structure.AddRange(structurePieces);
                                break;
                            }
                        }
                    }
                }
                else if (instruction.OP == OPCode.ConstructSuper)
                {
                    ConstructSuperIns constructSuper = (ConstructSuperIns)instruction;
                    if (constructSuper.ArgCount > 0)
                    {
                        ASClass superClass = @class.GetABC().GetClass(@class.Instance.Super);
                        structure.AddRange(GetOutgoingStructure(superClass, propertyName));
                    }
                }
                if (instruction.OP != OPCode.GetProperty)
                {
                    continue;
                }

                GetPropertyIns getProperty = (GetPropertyIns)instruction;
                if (getProperty.PropertyName != propertyName)
                {
                    continue;
                }

                ASInstruction next         = code[++i];
                ASClass       classToCheck = @class;
                if (Local.IsGetLocal(next.OP))
                {
                    if (next.OP == OPCode.GetLocal_0)
                    {
                        continue;
                    }

                    Local       local     = (Local)next;
                    ASParameter parameter = constructor.Parameters[local.Register - 1];

                    if (!TryGetPacketValue(parameter.Type, null, out PacketValue piece))
                    {
                        return(null);
                    }
                    structure.Add(piece);
                }
                else
                {
                    if (next.OP == OPCode.FindPropStrict)
                    {
                        classToCheck = null;
                    }
                    else if (next.OP == OPCode.GetLex)
                    {
                        GetLexIns getLex = (GetLexIns)next;
                        classToCheck = classToCheck.GetABC().GetClass(getLex.TypeName);
                    }
                    do
                    {
                        next         = code[++i];
                        propertyName = null;
                        if (next.OP == OPCode.GetProperty)
                        {
                            getProperty  = (GetPropertyIns)next;
                            propertyName = getProperty.PropertyName;
                        }
                        else if (next.OP == OPCode.CallProperty)
                        {
                            CallPropertyIns callProperty = (CallPropertyIns)next;
                            propertyName = callProperty.PropertyName;
                        }
                    }while (next.OP != OPCode.GetProperty && next.OP != OPCode.CallProperty);

                    if (!TryGetPacketValue(propertyName, classToCheck, out PacketValue piece))
                    {
                        return(null);
                    }
                    structure.Add(piece);
                }
            }
            return(structure.Count == 0 ? null : structure.ToArray());
        }
示例#19
0
文件: HGame.cs 项目: makinit/Tanji
        protected void FindHabboMessageClasses(ASClass habboMessageClass)
        {
            if (habboMessageClass == null)
            {
                throw new NullReferenceException(nameof(habboMessageClass));
            }

            if (OutgoingMessages != null && IncomingMessages != null)
            {
                return;
            }

            ABCFile abc = habboMessageClass.ABC;

            if (habboMessageClass.Traits.Count < 2)
            {
                return;
            }

            int incomingMapTypeIndex = habboMessageClass.Traits[0].NameIndex;
            int outgoingMapTypeIndex = habboMessageClass.Traits[1].NameIndex;

            var outgoingClasses = new Dictionary <ushort, ASClass>();
            var incomingClasses = new Dictionary <ushort, ASClass>();

            ASMethod constructor = habboMessageClass.Constructor;

            using (var inCode = new FlashReader(constructor.Body.Bytecode))
            {
                while (inCode.IsDataAvailable)
                {
                    object[] values = inCode.ReadValuesUntil(OPCode.GetLex);
                    if (values == null)
                    {
                        break;
                    }

                    // Check if the instruction is referencing one of the in/out map types.
                    int  getLexTypeIndex = (int)values[0];
                    bool isOutgoing      = (getLexTypeIndex == outgoingMapTypeIndex);
                    if (!isOutgoing && getLexTypeIndex != incomingMapTypeIndex)
                    {
                        continue;
                    }

                    OPCode op = 0;
                    values = inCode.ReadValuesUntilEither(out op, OPCode.PushByte, OPCode.PushShort);

                    if (values == null)
                    {
                        return;
                    }
                    var header = Convert.ToUInt16(values[0]);

                    values = inCode.ReadValuesUntil(OPCode.GetLex);
                    if (values == null)
                    {
                        return;
                    }

                    getLexTypeIndex = (int)values[0];
                    ASMultiname messageType  = abc.Constants.Multinames[getLexTypeIndex];
                    ASClass     messageClass = abc.FindFirstClassByName(messageType.Name);

                    Dictionary <ushort, ASClass> messageClasses =
                        (isOutgoing ? outgoingClasses : incomingClasses);

                    messageClasses[header]           = messageClass;
                    _isMessageOutgoing[messageClass] = isOutgoing;
                }
            }

            #region Organize Outgoing Message Dictionaries
            IOrderedEnumerable <KeyValuePair <ushort, ASClass> > orderedOutgoing =
                outgoingClasses.OrderBy(kvp => kvp.Key);

            _outgoingHeaders = orderedOutgoing
                               .ToDictionary(kvp => kvp.Value, kvp => kvp.Key);

            OutgoingMessages = new ReadOnlyDictionary <ushort, ASClass>(
                orderedOutgoing.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
            #endregion
            #region Organize Incoming Message Dictionaries
            IOrderedEnumerable <KeyValuePair <ushort, ASClass> > orderedIncoming =
                incomingClasses.OrderBy(kvp => kvp.Key);

            _incomingHeaders = orderedIncoming
                               .ToDictionary(kvp => kvp.Value, kvp => kvp.Key);

            IncomingMessages = new ReadOnlyDictionary <ushort, ASClass>(
                orderedIncoming.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
            #endregion
        }
示例#20
0
文件: HGame.cs 项目: makinit/Tanji
        /// <summary>
        /// Modifies the bytecode to allow the client to connect to anywhere.
        /// </summary>
        public void BypassRemoteHostCheck()
        {
            ABCFile    abc           = ABCFiles[2];
            ASInstance habboCommMngr = abc.FindFirstInstanceByName("HabboCommunicationManager");

            if (habboCommMngr == null)
            {
                return;
            }

            int    hostValueSlotObjTypeIndex = -1;
            string hostValueSlotObjName      = string.Empty;

            foreach (ASTrait trait in habboCommMngr.Traits)
            {
                if (trait.TraitType != TraitType.Slot)
                {
                    continue;
                }
                if (((SlotConstantTrait)trait.Data).TypeName.Name != "String")
                {
                    continue;
                }

                hostValueSlotObjName      = trait.Name.Name;
                hostValueSlotObjTypeIndex = trait.NameIndex;
                break;
            }

            ASMethod initCompMethod = habboCommMngr
                                      .FindFirstMethod("initComponent", "void");

            int getPropertyObjTypeIndex = abc.Constants
                                          .IndexOfMultiname("getProperty");

            ASMethod initConnectionMethod = null;

            using (var outCode = new FlashWriter())
                using (var inCode = new FlashReader(initCompMethod.Body.Bytecode))
                {
                    object[] values = inCode.ReadValuesUntil(OPCode.CallPropVoid, null, 0);

                    if (values == null)
                    {
                        return;
                    }
                    CopyBytecode(inCode, outCode, 0, inCode.Position);

                    outCode.WriteOP(OPCode.GetLocal_0);
                    outCode.WriteOP(OPCode.FindPropStrict, getPropertyObjTypeIndex);
                    outCode.WriteOP(OPCode.PushString, abc.Constants.AddString("connection.info.host"));
                    outCode.WriteOP(OPCode.CallProperty, getPropertyObjTypeIndex, 1);
                    outCode.WriteOP(OPCode.InitProperty, hostValueSlotObjTypeIndex);
                    WriteLog($"Method '{initCompMethod}' modified to include '{hostValueSlotObjName} = getProperty(\"connection.info.host\");'.");

                    CopyBytecode(inCode, outCode);
                    initCompMethod.Body.Bytecode = outCode.ToArray();

                    values = inCode.ReadValuesUntil(OPCode.CallPropVoid);
                    ASMultiname callPropVoidType = abc.Constants.Multinames[(int)values[0]];
                    initConnectionMethod = habboCommMngr.FindFirstMethod(callPropVoidType.Name, "void");
                }

            using (var outCode = new FlashWriter())
                using (var inCode = new FlashReader(initConnectionMethod.Body.Bytecode))
                {
                    int  ifNeCount          = 0;
                    int  byteJumpCountPos   = 0;
                    int  differenceOffset   = 0;
                    uint byteJumpCountValue = 0;
                    int  magicNumberIndex   = abc.Constants.AddInteger(65290);
                    while (inCode.IsDataAvailable)
                    {
                        OPCode   op     = inCode.ReadOP();
                        object[] values = null;

                        if (op != OPCode.PushInt)
                        {
                            values = inCode.ReadValues(op);
                            outCode.WriteOP(op, values);

                            if (op == OPCode.IfNe &&
                                (++ifNeCount == 2 || ifNeCount == 4))
                            {
                                byteJumpCountPos   = (outCode.Position - 3);
                                byteJumpCountValue = (uint)values[0];
                            }
                            continue;
                        }

                        bool isFinalPushInt = false;
                        int  pushIntIndex   = inCode.Read7BitEncodedInt();
                        int  pushIntValue   = abc.Constants.Integers[pushIntIndex];
                        #region Switch: pushIntValue
                        switch (pushIntValue)
                        {
                        case 65244: //97
                        case 65185: //32
                        case 65191: //175
                        case 65189: //123
                        case 65188: //164
                        case 65174: //45
                        case 65238: //297
                        case 65184: //127
                        case 65171: //20
                        case 65172: //58
                        {
                            pushIntIndex   = magicNumberIndex;
                            isFinalPushInt = (pushIntValue == 65172);
                            break;
                        }
                        }
                        #endregion
                        outCode.WriteOP(op, pushIntIndex);

                        int byteDifference = (((inCode.Position - outCode.Length) * -1) - differenceOffset);
                        if (isFinalPushInt)
                        {
                            int curPos = outCode.Position;
                            differenceOffset += byteDifference;

                            outCode.Position = byteJumpCountPos;
                            outCode.WriteS24(byteJumpCountValue + (uint)byteDifference);
                            outCode.Position = curPos;

                            if (ifNeCount == 4)
                            {
                                CopyBytecode(inCode, outCode);
                                initConnectionMethod.Body.Bytecode = outCode.ToArray();
                                WriteLog($"Method '{initConnectionMethod}' modified to not append suffix to the host value.");
                                return;
                            }
                        }
                    }
                }
        }
示例#21
0
        private List <HReference> FindMessageReferences(ASClass fromClass, ASContainer fromContainer, ASMethod fromMethod)
        {
            int     instructionRank = 0;
            ABCFile abc             = fromMethod.GetABC();

            Stack <ASMultiname> nameStack  = new Stack <ASMultiname>();
            List <HReference>   references = new List <HReference>();

            ASContainer container = null;
            ASCode      code      = fromMethod.Body.ParseCode();

            for (int i = 0; i < code.Count; i++)
            {
                ASInstruction instruction = code[i];
                switch (instruction.OP)
                {
                default: continue;

                case OPCode.NewFunction:
                {
                    NewFunctionIns newFunction = (NewFunctionIns)instruction;
                    references.AddRange(FindMessageReferences(fromClass, fromContainer, newFunction.Method));
                    continue;
                }

                case OPCode.GetProperty:
                {
                    GetPropertyIns getProperty = (GetPropertyIns)instruction;
                    nameStack.Push(getProperty.PropertyName);
                    continue;
                }

                case OPCode.GetLex:
                {
                    GetLexIns getLex = (GetLexIns)instruction;
                    container = abc.GetClass(getLex.TypeName.Name);
                    continue;
                }

                case OPCode.GetLocal_0:
                {
                    container = fromContainer;
                    continue;
                }

                case OPCode.ConstructProp:
                {
                    ConstructPropIns constructProp = (ConstructPropIns)instruction;
                    nameStack.Push(constructProp.PropertyName);
                    break;
                }
                }

                ASMultiname messageQName = nameStack.Pop();
                if (string.IsNullOrWhiteSpace(messageQName.Name))
                {
                    continue;
                }

                ASClass messageClass = abc.GetClass(messageQName.Name);
                if (messageClass == null)
                {
                    continue;
                }

                if (!_messages.TryGetValue(messageClass, out HMessage message))
                {
                    continue;
                }
                if (message.References.Any(r => r.FromMethod == fromMethod))
                {
                    continue;
                }

                HReference reference = new HReference();
                message.References.Add(reference);

                if (message.IsOutgoing)
                {
                    reference.FromClass       = fromClass;
                    reference.FromMethod      = fromMethod;
                    reference.InstructionRank = ++instructionRank;
                    reference.IsAnonymous     = (!fromMethod.IsConstructor && fromMethod.Trait == null);

                    references.Add(reference);
                }
                else
                {
                    ASMultiname methodName     = nameStack.Pop();
                    ASMethod    callbackMethod = fromContainer.GetMethod(methodName.Name);
                    if (callbackMethod == null)
                    {
                        callbackMethod = container.GetMethod(methodName.Name);
                        if (callbackMethod == null)
                        {
                            ASMultiname slotName = nameStack.Pop();

                            ASTrait hostTrait = container.GetTraits(TraitKind.Slot)
                                                .FirstOrDefault(st => st.QName == slotName);

                            container      = abc.GetInstance(hostTrait.Type.Name);
                            callbackMethod = container.GetMethod(methodName.Name);
                        }
                    }
                    reference.FromMethod = callbackMethod;
                }
            }
            return(references);
        }
示例#22
0
        private PacketValue[] GetOutgoingStructure(ASCode code, ASInstruction beforeReturn, int length)
        {
            int getLocalEndIndex = -1;
            int pushingEndIndex  = code.IndexOf(beforeReturn);

            PacketValue[]         structure    = new PacketValue[length];
            Dictionary <int, int> pushedLocals = new Dictionary <int, int>();

            for (int i = pushingEndIndex - 1; i >= 0; i--)
            {
                ASInstruction instruction = code[i];
                if (instruction.OP == OPCode.GetProperty)
                {
                    ASClass        classToCheck = Class;
                    GetPropertyIns getProperty  = (GetPropertyIns)instruction;
                    ASMultiname    propertyName = getProperty.PropertyName;

                    ASInstruction previous = code[i - 1];
                    if (previous.OP == OPCode.GetLex)
                    {
                        GetLexIns getLex = (GetLexIns)previous;
                        classToCheck = classToCheck.GetABC().GetClass(getLex.TypeName);
                    }

                    if (!TryGetPacketValue(propertyName, classToCheck, out PacketValue piece))
                    {
                        return(null);
                    }
                    structure[--length] = piece;
                }
                else if (Local.IsGetLocal(instruction.OP) &&
                         instruction.OP != OPCode.GetLocal_0)
                {
                    Local local = (Local)instruction;
                    pushedLocals.Add(local.Register, --length);
                    if (getLocalEndIndex == -1)
                    {
                        getLocalEndIndex = i;
                    }
                }
                if (length == 0)
                {
                    break;
                }
            }
            for (int i = getLocalEndIndex - 1; i >= 0; i--)
            {
                ASInstruction instruction = code[i];
                if (!Local.IsSetLocal(instruction.OP))
                {
                    continue;
                }

                Local local = (Local)instruction;
                if (pushedLocals.TryGetValue(local.Register, out int structIndex))
                {
                    ASInstruction beforeSet = code[i - 1];
                    pushedLocals.Remove(local.Register);
                    switch (beforeSet.OP)
                    {
                    case OPCode.PushInt:
                    case OPCode.PushByte:
                    case OPCode.Convert_i:
                        structure[structIndex] = PacketValue.Integer;
                        break;

                    case OPCode.Coerce_s:
                    case OPCode.PushString:
                        structure[structIndex] = PacketValue.String;
                        break;

                    case OPCode.PushTrue:
                    case OPCode.PushFalse:
                        structure[structIndex] = PacketValue.Boolean;
                        break;

                    default:
                        throw new Exception($"Don't know what this value type is, tell someone about this please.\r\nOP: {beforeSet.OP}");
                    }
                }
                if (pushedLocals.Count == 0)
                {
                    break;
                }
            }
            return(structure);
        }
示例#23
0
文件: HGame.cs 项目: makinit/Tanji
        /// <summary>
        /// Returns the Incoming message's parser class.
        /// </summary>
        /// <param name="messageClass">The Incoming message class to extract the parser class from.</param>
        /// <returns></returns>
        public ASClass GetIncomingMessageParser(ASClass messageClass)
        {
            if (_messageParsers.ContainsKey(messageClass))
            {
                return(_messageParsers[messageClass]);
            }

            ABCFile    abc = messageClass.ABC;
            ASClass    incomingMsgParserClass = null;
            ASInstance incomingMsgInstance    = messageClass.Instance;

            try
            {
                ASInstance incomingMsgSuperInstance = abc.FindFirstInstanceByName(
                    incomingMsgInstance.SuperType.Name);

                ASMultiname parserReturnType = incomingMsgSuperInstance
                                               .FindFirstGetter("parser", null).ReturnType;

                List <ASMethod> methods =
                    incomingMsgInstance.FindMethodGetterSetterTraits()
                    .Select(mgsTrait => mgsTrait.Method).ToList();

                methods.Add(incomingMsgInstance.Constructor);
                foreach (ASMethod method in methods)
                {
                    var referencedClasses = new List <ASClass>();
                    using (var inCode = new FlashReader(method.Body.Bytecode))
                    {
                        while (inCode.IsDataAvailable)
                        {
                            OPCode   op     = 0;
                            object[] values = inCode.ReadValuesUntilEither(out op, OPCode.FindPropStrict, OPCode.GetLex);
                            if (values == null)
                            {
                                break;
                            }

                            var         typeIndex = (int)values[0];
                            ASMultiname type      = abc.Constants.Multinames[typeIndex];

                            List <ASClass> instances = abc.FindClassesByName(type.Name);
                            referencedClasses.AddRange(instances);
                        }
                    }
                    foreach (ASClass referencedClass in referencedClasses)
                    {
                        ASInstance referencedInstance = referencedClass.Instance;
                        if (referencedInstance.ContainsInterface(parserReturnType.Name))
                        {
                            incomingMsgParserClass = referencedClass;
                            return(incomingMsgParserClass);
                        }
                    }
                }
            }
            finally
            {
                if (incomingMsgParserClass != null)
                {
                    _messageParsers[messageClass] =
                        incomingMsgParserClass;
                }
            }
            return(incomingMsgParserClass);
        }
示例#24
0
        private PacketValue[] GetIncomingStructure(ASInstance instance, ASMethod method)
        {
            if (method.Body.Exceptions.Count > 0)
            {
                return(null);
            }

            ASCode code = method.Body.ParseCode();

            if (code.JumpExits.Count > 0 || code.SwitchExits.Count > 0)
            {
                return(null);
            }

            List <PacketValue> structure = new List <PacketValue>();
            ABCFile            abc       = method.GetABC();

            for (int i = 0; i < code.Count; i++)
            {
                ASInstruction instruction = code[i];
                if (instruction.OP != OPCode.GetLocal_1)
                {
                    continue;
                }

                ASInstruction next = code[++i];
                switch (next.OP)
                {
                case OPCode.CallProperty:
                {
                    CallPropertyIns callProperty = (CallPropertyIns)next;
                    if (callProperty.ArgCount > 0)
                    {
                        ASMultiname   propertyName = null;
                        ASInstruction previous     = code[i - 2];

                        switch (previous.OP)
                        {
                        case OPCode.GetLex:
                        {
                            GetLexIns getLex = (GetLexIns)previous;
                            propertyName = getLex.TypeName;
                            break;
                        }

                        case OPCode.ConstructProp:
                        {
                            ConstructPropIns constructProp = (ConstructPropIns)previous;
                            propertyName = constructProp.PropertyName;
                            break;
                        }

                        case OPCode.GetLocal_0:
                        {
                            propertyName = instance.QName;
                            break;
                        }
                        }

                        ASInstance innerInstance = abc.GetInstance(propertyName);
                        ASMethod   innerMethod   = innerInstance.GetMethod(callProperty.PropertyName.Name, null, callProperty.ArgCount);
                        if (innerMethod == null)
                        {
                            ASClass innerClass = abc.GetClass(propertyName);
                            innerMethod = innerClass.GetMethod(callProperty.PropertyName.Name, null, callProperty.ArgCount);
                        }

                        PacketValue[] innerStructure = GetIncomingStructure(innerInstance, innerMethod);
                        if (innerStructure == null)
                        {
                            return(null);
                        }
                        structure.AddRange(innerStructure);
                    }
                    else
                    {
                        if (!TryGetPacketValue(callProperty.PropertyName, null, out PacketValue piece))
                        {
                            return(null);
                        }
                        structure.Add(piece);
                    }
                    break;
                }

                case OPCode.ConstructProp:
                {
                    ConstructPropIns constructProp = (ConstructPropIns)next;
                    ASInstance       innerInstance = abc.GetInstance(constructProp.PropertyName);

                    PacketValue[] innerStructure = GetIncomingStructure(innerInstance, innerInstance.Constructor);
                    if (innerStructure == null)
                    {
                        return(null);
                    }
                    structure.AddRange(innerStructure);
                    break;
                }

                case OPCode.ConstructSuper:
                {
                    ASInstance superInstance = abc.GetInstance(instance.Super);

                    PacketValue[] innerStructure = GetIncomingStructure(superInstance, superInstance.Constructor);
                    if (innerStructure == null)
                    {
                        return(null);
                    }
                    structure.AddRange(innerStructure);
                    break;
                }

                case OPCode.CallSuper:
                {
                    CallSuperIns callSuper     = (CallSuperIns)next;
                    ASInstance   superInstance = abc.GetInstance(instance.Super);
                    ASMethod     superMethod   = superInstance.GetMethod(callSuper.MethodName.Name, null, callSuper.ArgCount);

                    PacketValue[] innerStructure = GetIncomingStructure(superInstance, superMethod);
                    if (innerStructure == null)
                    {
                        return(null);
                    }
                    structure.AddRange(innerStructure);
                    break;
                }

                case OPCode.CallPropVoid:
                {
                    CallPropVoidIns callPropVoid = (CallPropVoidIns)next;
                    if (callPropVoid.ArgCount != 0)
                    {
                        return(null);
                    }

                    if (!TryGetPacketValue(callPropVoid.PropertyName, null, out PacketValue piece))
                    {
                        return(null);
                    }
                    structure.Add(piece);
                    break;
                }

                default: return(null);
                }
            }
            return(structure.Count == 0 ? null : structure.ToArray());
        }
示例#25
0
文件: HGame.cs 项目: makinit/Tanji
        protected int FindMessageReferences(ASClass fromClass, TraitContainer container, ASMethod fromMethod, int rank, int msgReferencesFound)
        {
            ABCFile abc = fromClass.ABC;

            using (var inCode = new FlashReader(fromMethod.Body.Bytecode))
            {
                var multinameStack = new Stack <ASMultiname>();
                while (inCode.IsDataAvailable)
                {
                    OPCode   op     = inCode.ReadOP();
                    object[] values = inCode.ReadValues(op);

                    switch (op)
                    {
                        #region Case: GetProperty
                    case OPCode.GetProperty:
                    {
                        multinameStack.Push(abc.Constants.Multinames[(int)values[0]]);
                        break;
                    }

                        #endregion
                        #region Case: NewFunction
                    case OPCode.NewFunction:
                    {
                        ASMethod newFuncMethod = abc.Methods[(int)values[0]];
                        msgReferencesFound = FindMessageReferences(fromClass, container, newFuncMethod, rank, msgReferencesFound);
                        break;
                    }

                        #endregion
                        #region Case: ConstructProp
                    case OPCode.ConstructProp:
                    {
                        ASMultiname constructPropType =
                            abc.Constants.Multinames[(int)values[0]];

                        ASClass messageClass =
                            abc.FindFirstClassByName(constructPropType.Name);

                        if (messageClass == null || !IsMessageClass(messageClass))
                        {
                            continue;
                        }

                        if (!_messageReferences.ContainsKey(messageClass))
                        {
                            _messageReferences[messageClass] = new List <ASReference>();
                        }

                        var msgReference = new ASReference(messageClass, fromClass, fromMethod);
                        if (!IsMessageOutgoing(messageClass))
                        {
                            ASMultiname topName = multinameStack.Pop();
                            msgReference.FromMethod = null;

                            IEnumerable <MethodGetterSetterTrait> mgsTraits =
                                container.FindMethodGetterSetterTraits();

                            rank = 0;     // TODO: Move this into a method or something, I'm re-writing it below as well.
                            foreach (MethodGetterSetterTrait mgsTrait in mgsTraits)
                            {
                                rank++;
                                if (mgsTrait.Method.TraitName == topName.Name)
                                {
                                    msgReference.FromMethod = mgsTrait.Method;
                                    break;
                                }
                            }
                            if (msgReference.FromMethod == null && multinameStack.Count > 0)
                            {
                                ASMultiname bottomName = multinameStack.Pop();
                                foreach (ASTrait trait in container.Traits)
                                {
                                    switch (trait.TraitType)
                                    {
                                        #region Case: Slot, Constant
                                    case TraitType.Slot:
                                    case TraitType.Constant:
                                    {
                                        if (trait.Name.Name != bottomName.Name)
                                        {
                                            continue;
                                        }

                                        var scTrait = (SlotConstantTrait)trait.Data;
                                        if (scTrait.TypeName.MultinameType != ConstantType.QName)
                                        {
                                            continue;
                                        }
                                        ASClass slotValueClass = abc.FindFirstClassByName(scTrait.TypeName.Name);

                                        rank      = 0;
                                        mgsTraits = slotValueClass.Instance.FindMethodGetterSetterTraits();
                                        foreach (MethodGetterSetterTrait mgsTrait in mgsTraits)
                                        {
                                            rank++;
                                            if (mgsTrait.Method.TraitName == topName.Name)
                                            {
                                                msgReference.FromMethod = mgsTrait.Method;
                                                break;
                                            }
                                        }

                                        if (msgReference.FromMethod != null)
                                        {
                                            msgReference.FromClass = slotValueClass;
                                        }

                                        break;
                                    }
                                        #endregion
                                    }
                                    if (msgReference.FromMethod != null)
                                    {
                                        break;
                                    }
                                }
                            }
                        }

                        msgReference.Id = ((++msgReferencesFound) + rank);
                        // We can't rely on the amount of references found, since the hooking of incoming messages are randomized each revision.
                        if (!IsMessageOutgoing(messageClass))
                        {
                            msgReference.Id = rank;
                        }

                        _messageReferences[messageClass].Add(msgReference);
                        break;
                    }
                        #endregion
                    }
                }
            }
            return(msgReferencesFound);
        }
示例#26
0
        public bool BypassRemoteHostCheck()
        {
            ABCFile    abc         = ABCFiles[2];
            ASInstance commManager = abc.FindInstanceByName("HabboCommunicationManager");

            if (commManager == null)
            {
                return(false);
            }

            // The "host" value is always the first slot, for now.
            string hostValueSlotName = commManager.FindTraits <SlotConstantTrait>(TraitType.Slot)
                                       .Where(t => t.Type.ObjName == "String").ToArray()[0].ObjName;

            ASMethod initComponent = commManager.FindMethod("initComponent", "void").Method;

            if (initComponent == null)
            {
                return(false);
            }

            using (var inCode = new FlashReader(initComponent.Body.Bytecode))
                using (var outCode = new FlashWriter(inCode.Length))
                {
                    int hostSlotIndex = abc.Constants.IndexOfMultiname(hostValueSlotName);
                    while (inCode.Position != inCode.Length)
                    {
                        OPCode op = inCode.ReadOP();
                        outCode.WriteOP(op);
                        if (op != OPCode.GetLocal_0)
                        {
                            continue;
                        }

                        op = inCode.ReadOP();
                        outCode.WriteOP(op);
                        if (op != OPCode.CallPropVoid)
                        {
                            continue;
                        }

                        int callPropVoidIndex = inCode.Read7BitEncodedInt();
                        outCode.Write7BitEncodedInt(callPropVoidIndex);

                        int callPropVoidArgCount = inCode.Read7BitEncodedInt();
                        outCode.Write7BitEncodedInt(callPropVoidArgCount);

                        if (callPropVoidArgCount != 0)
                        {
                            continue;
                        }

                        int getPropertyNameIndex = abc.Constants
                                                   .IndexOfMultiname("getProperty");

                        outCode.WriteOP(OPCode.GetLocal_0);
                        outCode.WriteOP(OPCode.FindPropStrict);
                        outCode.Write7BitEncodedInt(getPropertyNameIndex);

                        outCode.WriteOP(OPCode.PushString);
                        outCode.Write7BitEncodedInt(abc.Constants.AddString("connection.info.host"));

                        outCode.WriteOP(OPCode.CallProperty);
                        outCode.Write7BitEncodedInt(getPropertyNameIndex);
                        outCode.Write7BitEncodedInt(1);

                        outCode.WriteOP(OPCode.InitProperty);
                        outCode.Write7BitEncodedInt(hostSlotIndex);

                        outCode.Write(inCode.ToArray(),
                                      inCode.Position, inCode.Length - inCode.Position);

                        do
                        {
                            op = inCode.ReadOP();
                        }while (op != OPCode.CallPropVoid);

                        callPropVoidIndex = inCode.Read7BitEncodedInt();
                        ASMultiname callPropVoidName = abc.Constants.Multinames[callPropVoidIndex];
                        ASMethod    connectMethod    = commManager.FindMethod(callPropVoidName.ObjName, "void").Method;
                        RemoveHostSuffix(abc, connectMethod);

                        initComponent.Body.Bytecode = outCode.ToArray();
                        return(true);
                    }
                }
            return(false);
        }