Ejemplo n.º 1
0
 protected void ReplaceNextOperation(FlashReader inCode, FlashWriter outCode, ASMethod method, OPCode oldOP, object[] oldValues, OPCode newOP, object[] newValues)
 {
     while (inCode.IsDataAvailable)
     {
         OPCode   op     = inCode.ReadOP();
         object[] values = inCode.ReadValues(op);
         if (op != oldOP)
         {
             outCode.WriteOP(op, values);
             continue;
         }
         if (oldValues != null && (oldValues.Length == values.Length))
         {
             bool valuesMatch = true;
             for (int i = 0; i < oldValues.Length; i++)
             {
                 if (oldValues[i] != null &&
                     !oldValues[i].Equals(values[i]))
                 {
                     valuesMatch = false;
                     break;
                 }
             }
             if (!valuesMatch)
             {
                 outCode.WriteOP(op, values);
                 continue;
             }
         }
         outCode.WriteOP(newOP, newValues);
         WriteLog($"Replaced operation '{oldOP}[{string.Join(", ", oldValues)}]' with '{newOP}[{string.Join(", ", newValues)}]' in method '{method}'.");
         break;
     }
 }
Ejemplo n.º 2
0
 protected void RemoveDeadFalseConditions(ASMethodBody body)
 {
     using (var inCode = new FlashReader(body.Bytecode))
         using (var outCode = new FlashWriter(inCode.Length))
         {
             while (inCode.Position != inCode.Length)
             {
                 OPCode op = inCode.ReadOP();
                 if (op != OPCode.PushFalse)
                 {
                     outCode.WriteOP(op);
                     continue;
                 }
                 op = inCode.ReadOP();
                 if (op != OPCode.PushFalse)
                 {
                     outCode.WriteOP(OPCode.PushFalse);
                     outCode.WriteOP(op);
                     continue;
                 }
                 op = inCode.ReadOP();
                 if (op != OPCode.IfNe)
                 {
                     outCode.WriteOP(OPCode.PushFalse);
                     outCode.WriteOP(OPCode.PushFalse);
                     outCode.WriteOP(op);
                     continue;
                 }
                 else
                 {
                     inCode.ReadS24();
                 }
             }
             body.Bytecode = outCode.ToArray();
         }
 }
Ejemplo n.º 3
0
        protected void RemoveHostSuffix(ABCFile abc, ASMethod connectMethod)
        {
            using (var inCode = new FlashReader(connectMethod.Body.Bytecode))
                using (var outCode = new FlashWriter(inCode.Length))
                {
                    int ifNeCount = 0;
                    while (inCode.Position != inCode.Length)
                    {
                        OPCode op = inCode.ReadOP();
                        outCode.WriteOP(op);
                        if (op == OPCode.IfNe && ++ifNeCount == 2)
                        {
                            var iFNeJumpCount = (int)inCode.ReadS24();
                            outCode.WriteS24(iFNeJumpCount + 6);
                            continue;
                        }
                        else if (op != OPCode.PushInt)
                        {
                            continue;
                        }

                        int pushIntIndex = inCode.Read7BitEncodedInt();
                        int integerValue = abc.Constants.Integers[pushIntIndex];
                        switch (integerValue)
                        {
                        case 65244:
                        case 65185:
                        case 65191:
                        case 65189:
                        case 65188:
                        case 65174:
                        case 65238:
                        case 65184:
                        case 65171:
                        case 65172:
                        {
                            pushIntIndex = abc.Constants.AddInteger(65290);
                            break;
                        }
                        }
                        outCode.Write7BitEncodedInt(pushIntIndex);
                    }
                    connectMethod.Body.Bytecode = outCode.ToArray();
                }
            RemoveDeadFalseConditions(connectMethod.Body);
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
        public bool DisableExpirationDateCheck()
        {
            ABCFile    abc           = ABCFiles[2];
            ASInstance windowContext = abc.FindInstanceByName("WindowContext");

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

            using (var inCode = new FlashReader(windowContext.Constructor.Body.Bytecode))
                using (var outCode = new FlashWriter())
                {
                    int setLocal11Itterations = 0;
                    while (inCode.Position != inCode.Length)
                    {
                        OPCode op = inCode.ReadOP();
                        outCode.WriteOP(op);
                        if (op != OPCode.SetLocal)
                        {
                            continue;
                        }

                        int setLocalIndex = inCode.Read7BitEncodedInt();
                        outCode.Write7BitEncodedInt(setLocalIndex);
                        if (setLocalIndex != 11 || (++setLocal11Itterations != 2))
                        {
                            continue;
                        }

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

                        windowContext.Constructor.Body.Bytecode = outCode.ToArray();
                        return(true);
                    }
                }
            return(false);
        }
Ejemplo n.º 6
0
        protected virtual void WriteMethodHashData(BinaryWriter hashInput, ASMethod asMethod, bool writeInstructions)
        {
            WriteTraitsHashData(hashInput, asMethod.Body);
            hashInput.Write(asMethod.Body.Exceptions.Count);
            hashInput.Write(asMethod.Body.MaxStack);
            hashInput.Write(asMethod.Body.LocalCount);
            hashInput.Write(asMethod.Body.MaxScopeDepth);
            hashInput.Write(asMethod.Body.InitialScopeDepth);

            hashInput.Write(asMethod.Parameters.Count);
            foreach (ASParameter parameter in asMethod.Parameters)
            {
                if (parameter.IsOptional)
                {
                    hashInput.Write(parameter.IsOptional);
                    WriteValueSlotHashData(hashInput, parameter);
                }

                if (parameter.Type != null)
                {
                    WriteMultinameHashData(hashInput, parameter.Type);
                }
            }

            if (writeInstructions)
            {
                using (var codeOutput =
                           new FlashReader(asMethod.Body.Bytecode))
                {
                    while (codeOutput.IsDataAvailable)
                    {
                        OPCode   op     = codeOutput.ReadOP();
                        object[] values = codeOutput.ReadValues(op);
                        hashInput.Write((byte)op);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        protected void FixLocalRegisters(ASMethod method)
        {
            // But, what about nested branches? Does not work with those yet, sadly.
            if (method.Body == null)
            {
                return;
            }
            if (method.Body.LocalCount == (1 + method.Parameters.Count))
            {
                return;
            }

            ABCFile abc = method.ABC;

            using (var outCode = new FlashWriter())
                using (var inCode = new FlashReader(method.Body.Bytecode))
                {
                    uint jumpValue       = 0;
                    int  jumpValueEnd    = 0;
                    int  jumpValueStart  = 0;
                    int  totalDifference = 0;
                    bool isJumpingOver   = false;
                    var  labelPositions  = new Stack <int>();
                    while (inCode.IsDataAvailable)
                    {
                        if (isJumpingOver && inCode.Position >= jumpValueEnd)
                        {
                            isJumpingOver = false;
                        }

                        OPCode   op     = inCode.ReadOP();
                        object[] values = inCode.ReadValues(op);
                        if (op != OPCode.Debug || ((byte)values[0] != 1))
                        {
                            if (IsJumpInstruction(op)) // If a label position is contained in the stack, the next jump instruction will go backwards.
                            {
                                // Not a backwards jump, also check to make sure the jump value isn't crazy big, otherwise it might be a reverse jump instruction.
                                // If large: (uint.MaxValue - value[0]) == Bytes to jump back to get to the last saved label position in stack.
                                if (labelPositions.Count == 0 || ((uint)values[0] <= inCode.Length))
                                {
                                    isJumpingOver  = true;
                                    jumpValue      = (uint)values[0];        // To later check if we're in the middle of the jumping range.
                                    jumpValueStart = (outCode.Position + 1); // To re-write the jump value if the data in-between has sgrown.
                                    jumpValueEnd   = (int)(inCode.Position + jumpValue);
                                }
                                else
                                {
                                    // Find by how many bytes we need to move back from current position.
                                    values[0] = (uint)(uint.MaxValue -
                                                       ((outCode.Position + 4) - labelPositions.Pop()));
                                }
                            }
                            else if (op == OPCode.Label) // Store label positions, to easily determine by how many bytes we need to jump back to this position.
                            {
                                labelPositions.Push(outCode.Position + 1);
                            }

                            outCode.WriteOP(op, values);
                            continue;
                        }

                        var local = (byte)values[2];
                        if (local > method.Parameters.Count)
                        {
                            values[1] = abc.Constants
                                        .AddString("local" + local);
                        }
                        outCode.WriteOP(op, values);

                        int difference = (((inCode.Position - outCode.Length) * -1) - totalDifference);
                        totalDifference += difference;

                        if (isJumpingOver)
                        {
                            int curPos = outCode.Position;
                            outCode.Position            = jumpValueStart;
                            outCode.WriteS24(jumpValue += (uint)difference); // PlusEqual the value, in-case we've already modifed within the jumping range.
                            outCode.Position            = curPos;
                        }
                    }
                    method.Body.Bytecode = outCode.ToArray();
                }
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Returns a unique MD5 hash generated from various information contained in the message class.
        /// </summary>
        /// <param name="messageClass">The Outgoing/Incoming message class to create the unique hash from.</param>
        /// <returns></returns>
        public string GetMessageHash(ASClass messageClass)
        {
            if (!IsMessageClass(messageClass))
            {
                throw new ArgumentException(
                          "The specified class is not a valid Outgoing/Incoming message class.", nameof(messageClass));
            }
            if (_messageHashes.ContainsKey(messageClass))
            {
                return(_messageHashes[messageClass]);
            }
            else if (_messageReferences.Count == 0)
            {
                FindMessageReferences();
            }
            using (var hashOut = new FlashHasher())
            {
                hashOut.IsSummarizing = true;
                bool isOutgoing = IsMessageOutgoing(messageClass);

                hashOut.Write(isOutgoing);
                Write(hashOut, messageClass, isOutgoing);
                if (!messageClass.Instance.Name.Name.EndsWith("Composer") &&
                    _messageReferences.ContainsKey(messageClass))
                {
                    List <ASReference> msgReferences = _messageReferences[messageClass];
                    hashOut.Write(msgReferences.Count);
                    foreach (ASReference msgReference in msgReferences)
                    {
                        if (!isOutgoing)
                        {
                            string fromClassName =
                                msgReference.FromClass.Instance.Name.Name;

                            if (fromClassName == "IncomingMessages")
                            {
                                hashOut.Write(fromClassName);
                            }
                        }

                        hashOut.Write(msgReference.Id);
                        hashOut.Write(msgReference.FromMethod, true);

                        byte[] bytecode = msgReference.FromMethod.Body.Bytecode;
                        using (var inCode = new FlashReader(bytecode))
                        {
                            int lineCount = 0;
                            while (inCode.IsDataAvailable)
                            {
                                OPCode   op     = inCode.ReadOP();
                                object[] values = inCode.ReadValues(op); // Avoid common integer values, by starting big...
                                if (op == OPCode.DebugLine)
                                {
                                    hashOut.Write(int.MaxValue - (++lineCount));
                                }
                            }
                        }
                    }
                }

                string hash = hashOut.ToString();
                if (!_messages.ContainsKey(hash))
                {
                    _messages[hash] = new List <ASClass>();
                }

                if (!_messages[hash].Contains(messageClass))
                {
                    _messages[hash].Add(messageClass);
                }

                _messageHashes[messageClass] = hash;
                return(hash);
            }
        }
Ejemplo n.º 10
0
        /// <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;
                            }
                        }
                    }
                }
        }
Ejemplo n.º 11
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;
                }
            }
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
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;
                    }
                    }
                }
            }
        }
Ejemplo n.º 14
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);
        }
Ejemplo n.º 15
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);
        }