/// <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(); } }
/// <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); }