Пример #1
0
        public override void HandleData(ByteBuffer buff)
        {
            Log.outDebug(LogFilter.Warden, "Handle data");

            _dataSent            = false;
            _clientResponseTimer = 0;

            ushort Length   = buff.ReadUInt16();
            uint   Checksum = buff.ReadUInt32();

            if (!IsValidCheckSum(Checksum, buff.GetData(), Length))
            {
                Log.outWarn(LogFilter.Warden, "{0} failed checksum. Action: {1}", _session.GetPlayerInfo(), Penalty());
                return;
            }

            // TIMING_CHECK
            {
                byte result = buff.ReadUInt8();
                // @todo test it.
                if (result == 0x00)
                {
                    Log.outWarn(LogFilter.Warden, "{0} failed timing check. Action: {1}", _session.GetPlayerInfo(), Penalty());
                    return;
                }

                uint newClientTicks = buff.ReadUInt32();

                uint ticksNow = GameTime.GetGameTimeMS();
                uint ourTicks = newClientTicks + (ticksNow - _serverTicks);

                Log.outDebug(LogFilter.Warden, "ServerTicks {0}", ticksNow);         // Now
                Log.outDebug(LogFilter.Warden, "RequestTicks {0}", _serverTicks);    // At request
                Log.outDebug(LogFilter.Warden, "Ticks {0}", newClientTicks);         // At response
                Log.outDebug(LogFilter.Warden, "Ticks diff {0}", ourTicks - newClientTicks);
            }

            BigInteger      rs;
            WardenCheck     rd;
            WardenCheckType type;
            ushort          checkFailed = 0;

            foreach (var id in _currentChecks)
            {
                rd = Global.WardenCheckMgr.GetWardenDataById(id);
                rs = Global.WardenCheckMgr.GetWardenResultById(id);

                type = rd.Type;
                switch (type)
                {
                case WardenCheckType.Memory:
                {
                    byte Mem_Result = buff.ReadUInt8();

                    if (Mem_Result != 0)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT MEM_CHECK not 0x00, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        checkFailed = id;
                        continue;
                    }

                    if (buff.ReadBytes(rd.Length).Compare(rs.ToByteArray()))
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT MEM_CHECK fail CheckId {0} account Id {1}", id, _session.GetAccountId());
                        checkFailed = id;
                        continue;
                    }

                    Log.outDebug(LogFilter.Warden, "RESULT MEM_CHECK passed CheckId {0} account Id {1}", id, _session.GetAccountId());
                    break;
                }

                case WardenCheckType.PageA:
                case WardenCheckType.PageB:
                case WardenCheckType.Driver:
                case WardenCheckType.Module:
                {
                    byte value = 0xE9;
                    if (buff.ReadUInt8() != value)
                    {
                        if (type == WardenCheckType.PageA || type == WardenCheckType.PageB)
                        {
                            Log.outDebug(LogFilter.Warden, "RESULT PAGE_CHECK fail, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        }
                        if (type == WardenCheckType.Module)
                        {
                            Log.outDebug(LogFilter.Warden, "RESULT MODULE_CHECK fail, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        }
                        if (type == WardenCheckType.Driver)
                        {
                            Log.outDebug(LogFilter.Warden, "RESULT DRIVER_CHECK fail, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        }
                        checkFailed = id;
                        continue;
                    }

                    if (type == WardenCheckType.PageA || type == WardenCheckType.PageB)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT PAGE_CHECK passed CheckId {0} account Id {1}", id, _session.GetAccountId());
                    }
                    else if (type == WardenCheckType.Module)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT MODULE_CHECK passed CheckId {0} account Id {1}", id, _session.GetAccountId());
                    }
                    else if (type == WardenCheckType.Driver)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT DRIVER_CHECK passed CheckId {0} account Id {1}", id, _session.GetAccountId());
                    }
                    break;
                }

                case WardenCheckType.LuaStr:
                {
                    byte Lua_Result = buff.ReadUInt8();

                    if (Lua_Result != 0)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT LUA_STR_CHECK fail, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        checkFailed = id;
                        continue;
                    }

                    byte luaStrLen = buff.ReadUInt8();
                    if (luaStrLen != 0)
                    {
                        Log.outDebug(LogFilter.Warden, "Lua string: {0}", buff.ReadString(luaStrLen));
                    }

                    Log.outDebug(LogFilter.Warden, "RESULT LUA_STR_CHECK passed, CheckId {0} account Id {1}", id, _session.GetAccountId());
                    break;
                }

                case WardenCheckType.MPQ:
                {
                    byte Mpq_Result = buff.ReadUInt8();

                    if (Mpq_Result != 0)
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT MPQ_CHECK not 0x00 account id {0}", _session.GetAccountId());
                        checkFailed = id;
                        continue;
                    }

                    if (!buff.ReadBytes(20).Compare(rs.ToByteArray()))         // SHA1
                    {
                        Log.outDebug(LogFilter.Warden, "RESULT MPQ_CHECK fail, CheckId {0} account Id {1}", id, _session.GetAccountId());
                        checkFailed = id;
                        continue;
                    }

                    Log.outDebug(LogFilter.Warden, "RESULT MPQ_CHECK passed, CheckId {0} account Id {1}", id, _session.GetAccountId());
                    break;
                }

                default:                                            // Should never happen
                    break;
                }
            }

            if (checkFailed > 0)
            {
                WardenCheck check = Global.WardenCheckMgr.GetWardenDataById(checkFailed);
                Log.outWarn(LogFilter.Warden, "{0} failed Warden check {1}. Action: {2}", _session.GetPlayerInfo(), checkFailed, Penalty(check));
            }

            // Set hold off timer, minimum timer should at least be 1 second
            uint holdOff = WorldConfig.GetUIntValue(WorldCfg.WardenClientCheckHoldoff);

            _checkTimer = (holdOff < 1 ? 1 : holdOff) * Time.InMilliseconds;
        }
Пример #2
0
        public override void RequestData()
        {
            Log.outDebug(LogFilter.Warden, "Request data");

            // If all checks were done, fill the todo list again
            if (_memChecksTodo.Empty())
            {
                _memChecksTodo.AddRange(Global.WardenCheckMgr.MemChecksIdPool);
            }

            if (_otherChecksTodo.Empty())
            {
                _otherChecksTodo.AddRange(Global.WardenCheckMgr.OtherChecksIdPool);
            }

            _serverTicks = GameTime.GetGameTimeMS();

            ushort          id;
            WardenCheckType type;
            WardenCheck     wd;

            _currentChecks.Clear();

            // Build check request
            for (uint i = 0; i < WorldConfig.GetUIntValue(WorldCfg.WardenNumMemChecks); ++i)
            {
                // If todo list is done break loop (will be filled on next Update() run)
                if (_memChecksTodo.Empty())
                {
                    break;
                }

                // Get check id from the end and remove it from todo
                id = _memChecksTodo.Last();
                _memChecksTodo.Remove(id);

                // Add the id to the list sent in this cycle
                _currentChecks.Add(id);
            }

            ByteBuffer buffer = new ByteBuffer();

            buffer.WriteUInt8((byte)WardenOpcodes.Smsg_CheatChecksRequest);

            for (uint i = 0; i < WorldConfig.GetUIntValue(WorldCfg.WardenNumOtherChecks); ++i)
            {
                // If todo list is done break loop (will be filled on next Update() run)
                if (_otherChecksTodo.Empty())
                {
                    break;
                }

                // Get check id from the end and remove it from todo
                id = _otherChecksTodo.Last();
                _otherChecksTodo.Remove(id);

                // Add the id to the list sent in this cycle
                _currentChecks.Add(id);

                wd = Global.WardenCheckMgr.GetWardenDataById(id);

                switch (wd.Type)
                {
                case WardenCheckType.MPQ:
                case WardenCheckType.LuaStr:
                case WardenCheckType.Driver:
                    buffer.WriteUInt8((byte)wd.Str.GetByteCount());
                    buffer.WriteString(wd.Str);
                    break;

                default:
                    break;
                }
            }

            byte xorByte = _inputKey[0];

            // Add TIMING_CHECK
            buffer.WriteUInt8(0x00);
            buffer.WriteUInt8((byte)((int)WardenCheckType.Timing ^ xorByte));

            byte index = 1;

            foreach (var checkId in _currentChecks)
            {
                wd = Global.WardenCheckMgr.GetWardenDataById(checkId);

                type = wd.Type;
                buffer.WriteUInt8((byte)((int)type ^ xorByte));
                switch (type)
                {
                case WardenCheckType.Memory:
                {
                    buffer.WriteUInt8(0x00);
                    buffer.WriteUInt32(wd.Address);
                    buffer.WriteUInt8(wd.Length);
                    break;
                }

                case WardenCheckType.PageA:
                case WardenCheckType.PageB:
                {
                    buffer.WriteBytes(wd.Data.ToByteArray());
                    buffer.WriteUInt32(wd.Address);
                    buffer.WriteUInt8(wd.Length);
                    break;
                }

                case WardenCheckType.MPQ:
                case WardenCheckType.LuaStr:
                {
                    buffer.WriteUInt8(index++);
                    break;
                }

                case WardenCheckType.Driver:
                {
                    buffer.WriteBytes(wd.Data.ToByteArray());
                    buffer.WriteUInt8(index++);
                    break;
                }

                case WardenCheckType.Module:
                {
                    uint seed = RandomHelper.Rand32();
                    buffer.WriteUInt32(seed);
                    HmacHash hmac = new HmacHash(BitConverter.GetBytes(seed));
                    hmac.Finish(wd.Str);
                    buffer.WriteBytes(hmac.Digest);
                    break;
                }

                /*case PROC_CHECK:
                 * {
                 *  buff.append(wd.i.AsByteArray(0, false).get(), wd.i.GetNumBytes());
                 *  buff << uint8(index++);
                 *  buff << uint8(index++);
                 *  buff << uint32(wd.Address);
                 *  buff << uint8(wd.Length);
                 *  break;
                 * }*/
                default:
                    break;                                          // Should never happen
                }
            }
            buffer.WriteUInt8(xorByte);

            WardenDataServer packet = new WardenDataServer();

            packet.Data = EncryptData(buffer.GetData());
            _session.SendPacket(packet);

            _dataSent = true;

            string stream = "Sent check id's: ";

            foreach (var checkId in _currentChecks)
            {
                stream += checkId + " ";
            }

            Log.outDebug(LogFilter.Warden, stream);
        }