public ASNamespaceSet(ABCFile abc, FlashReader reader) : this(abc) { NamespaceIndices.Capacity = reader.Read7BitEncodedInt(); for (int i = 0; i < NamespaceIndices.Capacity; i++) { NamespaceIndices.Add(reader.Read7BitEncodedInt()); } }
public ASException(ABCFile abc, FlashReader reader) : this(abc) { From = reader.Read7BitEncodedInt(); To = reader.Read7BitEncodedInt(); Target = reader.Read7BitEncodedInt(); ExceptionTypeIndex = reader.Read7BitEncodedInt(); VariableNameIndex = reader.Read7BitEncodedInt(); }
public ASScript(ABCFile abc, FlashReader reader) : this(abc) { FunctionIndex = reader.Read7BitEncodedInt(); Traits.Capacity = reader.Read7BitEncodedInt(); for (int i = 0; i < Traits.Capacity; i++) { Traits.Add(new ASTrait(abc, reader)); } }
public Typename(ABCFile abc, FlashReader reader) : this(abc) { TypeIndex = reader.Read7BitEncodedInt(); ParameterTypeIndices.Capacity = reader.Read7BitEncodedInt(); for (int i = 0; i < ParameterTypeIndices.Capacity; i++) { ParameterTypeIndices.Add(reader.Read7BitEncodedInt()); } }
public ASMetadata(ABCFile abc, FlashReader reader) : this(abc) { ObjNameIndex = reader.Read7BitEncodedInt(); Elements.Capacity = reader.Read7BitEncodedInt(); for (int i = 0; i < Elements.Capacity; i++) { int elementKey = reader.Read7BitEncodedInt(); int elementValue = reader.Read7BitEncodedInt(); Elements.Add(new Tuple <int, int>(elementKey, elementValue)); } }
public SlotConstantTrait(ABCFile abc, FlashReader reader, TraitType traitType) : this(abc, traitType) { SlotId = reader.Read7BitEncodedInt(); TypeIndex = reader.Read7BitEncodedInt(); ValueIndex = reader.Read7BitEncodedInt(); if (ValueIndex != 0) { ValueType = (ConstantType)reader.ReadByte(); } }
public ASMethodBody(ABCFile abc, FlashReader reader) : this(abc) { MethodIndex = reader.Read7BitEncodedInt(); MaxStack = reader.Read7BitEncodedInt(); LocalCount = reader.Read7BitEncodedInt(); InitialScopeDepth = reader.Read7BitEncodedInt(); MaxScopeDepth = reader.Read7BitEncodedInt(); int bytecodeLength = reader.Read7BitEncodedInt(); Bytecode = reader.ReadBytes(bytecodeLength); Exceptions.Capacity = reader.Read7BitEncodedInt(); for (int i = 0; i < Exceptions.Capacity; i++) { Exceptions.Add(new ASException(abc, reader)); } Traits.Capacity = reader.Read7BitEncodedInt(); for (int i = 0; i < Traits.Capacity; i++) { Traits.Add(new ASTrait(abc, reader)); } Method.Body = this; }
public ASClass(ABCFile abc, FlashReader reader) : this(abc) { ConstructorIndex = reader.Read7BitEncodedInt(); if (Constructor != null) { Constructor.IsConstructor = true; } Traits.Capacity = reader.Read7BitEncodedInt(); for (int i = 0; i < Traits.Capacity; i++) { Traits.Add(new ASTrait(abc, reader)); } }
public ABCFile(FlashReader reader) { _reader = reader; MinorVersion = _reader.ReadUInt16(); MajorVersion = _reader.ReadUInt16(); Constants = new ASConstants(this, _reader); Constants.ReadConstants(); Methods = new List <ASMethod>(_reader.Read7BitEncodedInt()); for (int i = 0; i < Methods.Capacity; i++) { Methods.Add(new ASMethod(this, _reader)); } Metadata = new List <ASMetadata>(_reader.Read7BitEncodedInt()); for (int i = 0; i < Metadata.Capacity; i++) { Metadata.Add(new ASMetadata(this, _reader)); } Instances = new List <ASInstance>(_reader.Read7BitEncodedInt()); for (int i = 0; i < Instances.Capacity; i++) { Instances.Add(new ASInstance(this, _reader)); } Classes = new List <ASClass>(Instances.Capacity); for (int i = 0; i < Classes.Capacity; i++) { Classes.Add(new ASClass(this, _reader)); Classes[i].Instance = Instances[i]; } Scripts = new List <ASScript>(_reader.Read7BitEncodedInt()); for (int i = 0; i < Scripts.Capacity; i++) { Scripts.Add(new ASScript(this, _reader)); } MethodBodies = new List <ASMethodBody>(_reader.Read7BitEncodedInt()); for (int i = 0; i < MethodBodies.Capacity; i++) { MethodBodies.Add(new ASMethodBody(this, _reader)); } }
public ASInstance(ABCFile abc, FlashReader reader) : this(abc) { TypeIndex = reader.Read7BitEncodedInt(); SuperTypeIndex = reader.Read7BitEncodedInt(); ClassInfo = (ClassFlags)reader.ReadByte(); if ((ClassInfo & ClassFlags.ProtectedNamespace) != 0) { ProtectedNamespaceIndex = reader.Read7BitEncodedInt(); } InterfaceIndices.Capacity = reader.Read7BitEncodedInt(); for (int i = 0; i < InterfaceIndices.Capacity; i++) { InterfaceIndices.Add(reader.Read7BitEncodedInt()); } ConstructorIndex = reader.Read7BitEncodedInt(); if (Constructor != null) { Constructor.IsConstructor = true; } Traits.Capacity = reader.Read7BitEncodedInt(); for (int i = 0; i < Traits.Capacity; i++) { Traits.Add(new ASTrait(abc, reader)); } }
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); }
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); }
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); }
public ASMethod(ABCFile abc, FlashReader reader) : this(abc) { Parameters.Capacity = reader.Read7BitEncodedInt(); ReturnTypeIndex = reader.Read7BitEncodedInt(); for (int i = 0; i < Parameters.Capacity; i++) { int parameterTypeIndex = reader.Read7BitEncodedInt(); var parameter = new ASParameter(abc, parameterTypeIndex); Parameters.Add(parameter); parameter.Rank = Parameters.Count; } NameIndex = reader.Read7BitEncodedInt(); MethodInfo = (MethodFlags)reader.ReadByte(); if (MethodInfo.HasFlag(MethodFlags.HasOptional)) { int optionalParamCount = reader.Read7BitEncodedInt(); while (optionalParamCount > 0) { int paramIndex = ((Parameters.Count - 1) - (--optionalParamCount)); ASParameter optionalParameter = Parameters[paramIndex]; optionalParameter.IsOptional = true; optionalParameter.ValueIndex = reader.Read7BitEncodedInt(); optionalParameter.ValueType = (ConstantType)reader.ReadByte(); } } if (MethodInfo.HasFlag(MethodFlags.HasParamNames)) { foreach (ASParameter parameter in Parameters) { parameter.ObjNameIndex = reader.Read7BitEncodedInt(); } } }
public FunctionTrait(ABCFile abc, FlashReader reader) : this(abc) { SlotId = reader.Read7BitEncodedInt(); FunctionIndex = reader.Read7BitEncodedInt(); }
/// <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; } } } } }
public ClassTrait(ABCFile abc, FlashReader reader) : this(abc) { SlotId = reader.Read7BitEncodedInt(); ClassIndex = reader.Read7BitEncodedInt(); }
public MethodGetterSetterTrait(ABCFile abc, FlashReader reader, TraitType traitType) : this(abc, traitType) { DispId = reader.Read7BitEncodedInt(); MethodIndex = reader.Read7BitEncodedInt(); }
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); }
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); }
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); }
public RTQName(ABCFile abc, FlashReader reader, ConstantType multinameType) : this(abc, multinameType) { ObjNameIndex = reader.Read7BitEncodedInt(); }
public void ReadConstants() { _integers.Capacity = _reader.Read7BitEncodedInt(); if (_integers.Capacity > 0) { _integers.Add(0); for (int i = 1; i < _integers.Capacity; i++) { _integers.Add(_reader.Read7BitEncodedInt()); } } _uintegers.Capacity = _reader.Read7BitEncodedInt(); if (_uintegers.Capacity > 0) { _uintegers.Add(0); for (int i = 1; i < _uintegers.Capacity; i++) { _uintegers.Add((uint)_reader.Read7BitEncodedInt()); } } _doubles.Capacity = _reader.Read7BitEncodedInt(); if (_doubles.Capacity > 0) { _doubles.Add(double.NaN); for (int i = 1; i < _doubles.Capacity; i++) { _doubles.Add(_reader.ReadDouble()); } } _strings.Capacity = _reader.Read7BitEncodedInt(); if (_strings.Capacity > 0) { _strings.Add(string.Empty); for (int i = 1; i < _strings.Capacity; i++) { _strings.Add(_reader.ReadString()); } } _namespaces.Capacity = _reader.Read7BitEncodedInt(); if (_namespaces.Capacity > 0) { _namespaces.Add(null); for (int i = 1; i < _namespaces.Capacity; i++) { _namespaces.Add(new ASNamespace(ABC, _reader)); } } _namespaceSets.Capacity = _reader.Read7BitEncodedInt(); if (_namespaceSets.Capacity > 0) { _namespaceSets.Add(null); for (int i = 1; i < _namespaceSets.Capacity; i++) { _namespaceSets.Add(new ASNamespaceSet(ABC, _reader)); } } _multinames.Capacity = _reader.Read7BitEncodedInt(); if (_multinames.Capacity > 0) { _multinames.Add(null); for (int i = 1; i < _multinames.Capacity; i++) { _multinames.Add(new ASMultiname(ABC, _reader)); } } }
public MultinameL(ABCFile abc, FlashReader reader, ConstantType multinameType) : this(abc, multinameType) { NamespaceSetIndex = reader.Read7BitEncodedInt(); }
public ASTrait(ABCFile abc, FlashReader reader) : this(abc) { TypeIndex = reader.Read7BitEncodedInt(); byte trueKind = reader.ReadByte(); var traitType = (TraitType)(trueKind & 0xF); Attributes = (TraitAttributes)(trueKind >> 4); #region Trait Reading switch (traitType) { case TraitType.Slot: case TraitType.Constant: { Data = new SlotConstantTrait(abc, reader, traitType) { ObjName = Type.ObjName }; break; } case TraitType.Method: case TraitType.Getter: case TraitType.Setter: { Data = new MethodGetterSetterTrait(abc, reader, traitType) { ObjName = Type.ObjName }; ((MethodGetterSetterTrait)Data).Method.ObjName = ObjName; break; } case TraitType.Class: { Data = new ClassTrait(abc, reader) { ObjName = Type.ObjName }; break; } case TraitType.Function: { Data = new FunctionTrait(abc, reader) { ObjName = Type.ObjName }; break; } default: throw new Exception($"Invalid {nameof(ASTrait)} type: " + traitType); } #endregion if ((Attributes & TraitAttributes.Metadata) != 0) { MetadataIndices.Capacity = reader.Read7BitEncodedInt(); } for (int i = 0; i < MetadataIndices.Capacity; i++) { MetadataIndices.Add(reader.Read7BitEncodedInt()); } }
public ASNamespace(ABCFile abc, FlashReader reader) : this(abc) { NamespaceType = (ConstantType)reader.ReadByte(); ObjNameIndex = reader.Read7BitEncodedInt(); }