Beispiel #1
0
        private void LoadMessages()
        {
            ABCFile abc = ABCFiles.Last();
            ASClass habboMessagesClass = abc.GetClass("HabboMessages");

            if (habboMessagesClass == null)
            {
                IsPostShuffle = false;
                foreach (ASClass @class in abc.Classes)
                {
                    if (@class.Traits.Count != 2 || @class.Traits[0].Type?.Name != "Map" || @class.Traits[1].Type?.Name != "Map")
                    {
                        continue;
                    }
                    if (@class.Instance.Traits.Count != 2)
                    {
                        continue;
                    }

                    habboMessagesClass = @class;
                    break;
                }
                if (habboMessagesClass == null)
                {
                    return;
                }
            }

            ASCode code            = habboMessagesClass.Constructor.Body.ParseCode();
            int    outMapTypeIndex = habboMessagesClass.Traits[1].QNameIndex;

            ASInstruction[] instructions = code
                                           .Where(i => i.OP == OPCode.GetLex ||
                                                  i.OP == OPCode.PushShort ||
                                                  i.OP == OPCode.PushByte).ToArray();

            for (int i = 0; i < instructions.Length; i += 3)
            {
                GetLexIns getLexInst = instructions[i + 0] as GetLexIns;
                bool      isOutgoing = getLexInst?.TypeNameIndex == outMapTypeIndex;

                Primitive primitive = instructions[i + 1] as Primitive;
                ushort    id        = Convert.ToUInt16(primitive?.Value);

                getLexInst = instructions[i + 2] as GetLexIns;
                ASClass messageClass = abc.GetClass(getLexInst?.TypeName.Name);

                HMessage message = new HMessage(id, isOutgoing, messageClass);
                (isOutgoing ? OutMessages : InMessages).Add(id, message);

                if (!_messages.ContainsKey(messageClass))
                {
                    _messages.Add(messageClass, message);
                }
            }
        }
Beispiel #2
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());
        }
Beispiel #3
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);
        }
Beispiel #4
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);
        }