Ejemplo n.º 1
0
        /// <summary>
        /// Injects the specified public RSA keys into the bytecode that handles the verification of the received primes.
        /// </summary>
        /// <param name="exponent">The public exponent.</param>
        /// <param name="modulus">The public modulus.</param>
        public void ReplaceRSAKeys(int exponent, string modulus)
        {
            ABCFile    abc = ABCFiles[2];
            ASInstance habboCommDemoInstance = abc.FindFirstInstanceByName("HabboCommunicationDemo");

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

            ASMethod method          = null;
            int      rsaKeyTypeIndex = abc.Constants.IndexOfMultiname("RSAKey");

            foreach (MethodGetterSetterTrait mgsTrait in mgsTraits)
            {
                if (mgsTrait.Method.ReturnType.Name != "void")
                {
                    continue;
                }
                if (mgsTrait.Method.Parameters.Count != 1)
                {
                    continue;
                }

                if (ContainsOperation(mgsTrait.Method, OPCode.GetLex, rsaKeyTypeIndex))
                {
                    method = mgsTrait.Method;
                    WriteLog($"Found reference to 'RSAKey' in method '{method}'.");
                    break;
                }
            }

            using (var outCode = new FlashWriter())
                using (var inCode = new FlashReader(method.Body.Bytecode))
                {
                    int modulusStringIndex     = abc.Constants.AddString(modulus);
                    int exponentStringIndex    = abc.Constants.AddString(exponent.ToString("x")); // Turn the number to hex, remeber guys, (65537= 10001(hex))
                    int keyObfuscatorTypeIndex = abc.Constants.IndexOfMultiname("KeyObfuscator");

                    // Replace the first 'GetLex[KeyObfuscator]' operation with 'PushString[modulus]'.
                    ReplaceNextOperation(inCode, outCode, method,
                                         OPCode.GetLex, new object[] { keyObfuscatorTypeIndex },
                                         OPCode.PushString, new object[] { modulusStringIndex });

                    // Ignore these operations, do not write.
                    inCode.ReadValuesUntil(OPCode.CallProperty);

                    // Replace the second 'GetLex[KeyObfuscator]' operation with 'PushString[exponent]'.
                    ReplaceNextOperation(inCode, outCode, method,
                                         OPCode.GetLex, new object[] { keyObfuscatorTypeIndex },
                                         OPCode.PushString, new object[] { exponentStringIndex });

                    // Ignore these operations, do not write.
                    inCode.ReadValuesUntil(OPCode.CallProperty);

                    CopyBytecode(inCode, outCode);
                    method.Body.Bytecode = outCode.ToArray();
                }
        }
Ejemplo n.º 2
0
        /// <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);
        }