Example #1
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);
        }
Example #2
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();
                }
        }
Example #3
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;
                            }
                        }
                    }
                }
        }