public bool FindMessageInstances() { 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.Code.ToArray())) { while (mapReader.Position != mapReader.Length) { OPCode op = mapReader.ReadOP(); if (op != OPCode.GetLex) continue; int mapTypeIndex = mapReader.Read7BitEncodedInt(); bool isOutgoing = (mapTypeIndex == outgoingMap.NameIndex); bool isIncoming = (mapTypeIndex == incomingMap.NameIndex); 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]; ASInstance messageInstance = abc.FindInstanceByName(messageType.ObjName); if (isOutgoing) OutgoingTypes[header] = messageInstance; else if (isIncoming) IncomingTypes[header] = messageInstance; } } return (OutgoingTypes.Count > 0 && IncomingTypes.Count > 0); }
protected virtual byte[] GenerateHashData(ASInstance instance, bool isOutgoing) { using (var binStream = new MemoryStream()) using (var binWriter = new BinaryWriter(binStream)) { binWriter.Write(GenerateHashData(instance)); if (!isOutgoing) { ASMethod constructor = instance.Constructor; ASCode ctorCode = constructor.Body.Code; if (constructor.Parameters.Count < 2) { using (var inCode = new FlashReader(ctorCode.ToArray())) { while (inCode.Position != inCode.Length) { OPCode op = inCode.ReadOP(); object[] values = inCode.ReadValues(op); if (op == OPCode.GetLex) { ASMultiname classParamTypeName = _abcFiles[2] .Constants.Multinames[(int)values[0]]; ASInstance inMsgParser = _abcFiles[2] .FindInstanceByName(classParamTypeName.ObjName); if (inCode.ReadOP() == OPCode.ConstructSuper) binWriter.Write(GenerateHashData(inMsgParser)); break; } } } } } binWriter.Close(); return binStream.ToArray(); } }
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; ASCode methodCode = method.Body.Code; using (var code = new FlashReader(methodCode.ToArray())) { 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; }
protected void RemoveDeadFalseConditions(ASCode code) { using (var inCode = new FlashReader(code.ToArray())) 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(); } code.Clear(); code.AddRange(outCode.ToArray()); } }
public bool ReplaceRSA(int exponent, string modulus) { ABCFile abc = _abcFiles[_abcFiles.Count - 1]; int modulusIndex = abc.Constants.Strings.IndexOf(modulus); if (modulusIndex == -1) { abc.Constants.Strings.Add(modulus); modulusIndex = (abc.Constants.Strings.Count - 1); } string e = exponent.ToString("x"); int exponentIndex = abc.Constants.Strings.IndexOf(e); if (exponentIndex == -1) { abc.Constants.Strings.Add(e); exponentIndex = (abc.Constants.Strings.Count - 1); } int rsaStart = 0; ASInstance commClass = abc.FindInstanceByName("HabboCommunicationDemo"); ASMethod verifier = FindVerifyMethod(commClass, abc, out rsaStart); ASCode verifierCode = verifier.Body.Code; using (var inCode = new FlashReader(verifierCode.ToArray())) 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; } } verifierCode.Clear(); verifierCode.AddRange(outCode.ToArray()); if (!searchingKeys) return true; } return false; }
public bool DisableExpirationDateCheck() { ABCFile abc = _abcFiles[2]; ASInstance windowContext = abc.FindInstanceByName("WindowContext"); if (windowContext == null) return false; ASCode methodCode = windowContext.Constructor.Body.Code; using (var inCode = new FlashReader(methodCode.ToArray())) using (var outCode = new FlashWriter(methodCode.Count)) { 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); methodCode.Clear(); methodCode.AddRange(outCode.ToArray()); return true; } } return false; }
protected void RemoveHostSuffix(ABCFile abc, ASMethod connectMethod) { ASCode connectCode = connectMethod.Body.Code; using (var inCode = new FlashReader(connectCode.ToArray())) 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.PushInteger(65290); break; } } outCode.Write7BitEncodedInt(pushIntIndex); } connectCode.Clear(); connectCode.AddRange(outCode.ToArray()); } RemoveDeadFalseConditions(connectCode); }
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; ASCode initCode = initComponent.Body.Code; using (var inCode = new FlashReader(initCode.ToArray())) using (var outCode = new FlashWriter(inCode.Length)) { int hostSlotIndex = abc.Constants.FindMultinameIndex(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 .FindMultinameIndex("getProperty"); outCode.WriteOP(OPCode.GetLocal_0); outCode.WriteOP(OPCode.FindPropStrict); outCode.Write7BitEncodedInt(getPropertyNameIndex); outCode.WriteOP(OPCode.PushString); outCode.Write7BitEncodedInt(abc.Constants.PushString("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); initCode.Clear(); initCode.AddRange(outCode.ToArray()); return true; } } return false; }
private void WriteMethod(BinaryWriter writer, ASMethod method) { ASMethodBody body = method.Body; writer.Write(body.Traits.Count); writer.Write(body.Exceptions.Count); writer.Write(body.MaxStack); writer.Write(body.LocalCount); writer.Write(body.MaxScopeDepth); writer.Write(body.InitialScopeDepth); writer.Write(body.Method.Parameters.Count); foreach (ASParameter parameter in body.Method.Parameters) { switch (parameter.Type.ObjName) { case "int": case "Class": case "Array": case "String": case "Boolean": case "Function": { writer.Write(parameter.Type.ObjName); break; } } writer.Write(parameter.IsOptional); if (parameter.IsOptional) writer.Write((byte)parameter.ValueType); } ASCode code = body.Code; writer.Write("OPERATIONS"); using (var inCode = new FlashReader(code.ToArray())) { string instructions = string.Empty; while (inCode.Position != inCode.Length) { OPCode op = inCode.ReadOP(); inCode.ReadValues(op); instructions += (op + "\r\n"); writer.Write((byte)op); } } }