コード例 #1
0
        public static IEnumerable <PotentialArray> FindArrays(ReadOnlyMemory <byte> payload)
        {
            using var reader = new GameBinaryReader(payload.GetArray());

            for (var i = 0; i < reader.Length; i++)
            {
                reader.Position = i;

                if (!reader.CanRead(sizeof(ushort) * 2))
                {
                    break;
                }

                var countPos  = reader.Position;
                var count     = reader.ReadUInt16();
                var offsetPos = reader.Position;
                var offset    = reader.ReadOffset();

                if (count == 0 || (count * (sizeof(ushort) * 2 + sizeof(byte)) + sizeof(ushort) * 2) > reader.Length)
                {
                    continue;
                }

                var positions = new HashSet <int>
                {
                    countPos,
                    countPos + sizeof(byte),
                    offsetPos,
                    offsetPos + sizeof(byte),
                };

                var elems = new List <PotentialArrayElement>();
                var good  = true;
                var last  = offsetPos;
                var next  = offset;

                while (next != -PacketHeader.HeaderSize)
                {
                    if (!(good = next >= 0 && next > last && next <= reader.Length - sizeof(ushort) * 2 - sizeof(byte)))
                    {
                        break;
                    }

                    last = next + sizeof(ushort) * 2;

                    reader.Position = next;

                    var herePos = reader.Position;
                    var here    = reader.ReadOffset();

                    if (!(good = here == herePos && here == next && positions.Add(herePos) && positions.Add(herePos + sizeof(byte))))
                    {
                        break;
                    }

                    var nextPos = reader.Position;
                    next = reader.ReadOffset();

                    if (!(good = positions.Add(nextPos) && positions.Add(nextPos + sizeof(byte))))
                    {
                        break;
                    }

                    elems.Add(new PotentialArrayElement(here, nextPos, next == -PacketHeader.HeaderSize ? 0 : next));
                }

                if (good && elems.Count == count)
                {
                    yield return(new PotentialArray(countPos, count, offsetPos, offset, elems));
                }
            }
        }
コード例 #2
0
        void DeserializeObject(GameBinaryReader reader, object target)
        {
            foreach (var info in GetPacketInfo(target.GetType()).Fields.Cast <ReflectionPacketFieldInfo>())
            {
                if (info.IsByteArray)
                {
                    var offset = reader.ReadOffset();
                    var count  = reader.ReadUInt16();

                    var list = (List <byte>)info.Property.GetValue(target);

                    list.Clear();

                    if (count == 0)
                    {
                        continue;
                    }

                    reader.Seek(offset, (r, op) => list.AddRange(r.ReadBytes(count)));
                }
                else if (info.IsArray)
                {
                    var count  = reader.ReadUInt16();
                    var offset = reader.ReadOffset();
                    var list   = (IList)info.Property.GetValue(target);

                    list.Clear();

                    if (count == 0)
                    {
                        continue;
                    }

                    var next = offset;

                    for (var i = 0; i < count; i++)
                    {
                        reader.Seek(next, (r, op) =>
                        {
                            r.ReadOffset();
                            next = r.ReadOffset();

                            var elem = info.ElementConstructor();

                            DeserializeObject(r, elem);
                            list.Add(elem);
                        });
                    }
                }
                else if (info.IsString)
                {
                    var offset = reader.ReadOffset();

                    info.Property.SetValue(target, reader.Seek(offset, (r, op) => r.ReadString()));
                }
                else
                {
                    var val = info.PrimitiveDeserializer(reader);

                    info.EnumValidator?.Invoke(val);
                    info.Property.SetValue(target, val);
                }
            }
        }
コード例 #3
0
        public static IEnumerable <PotentialString> FindStrings(ReadOnlyMemory <byte> payload,
                                                                bool whiteSpace, bool control, int minLength)
        {
            using var reader = new GameBinaryReader(payload.GetArray());

            for (var i = 0; i < reader.Length; i++)
            {
                reader.Position = i;

                if (!reader.CanRead(sizeof(ushort)))
                {
                    break;
                }

                var offsetPos = reader.Position;
                var offset    = reader.ReadOffset();

                if (offset < 0 || offset < offsetPos + sizeof(ushort) || offset > reader.Length - sizeof(char))
                {
                    continue;
                }

                reader.Position = offset;

                string str;

                try
                {
                    str = reader.ReadString();

                    GameBinaryReader.Encoding.GetString(GameBinaryReader.Encoding.GetBytes(str));
                }
                catch (Exception e) when(IsStringException(e))
                {
                    continue;
                }

                if (!whiteSpace && string.IsNullOrWhiteSpace(str))
                {
                    continue;
                }

                if (minLength != 0 && str.Length < minLength)
                {
                    continue;
                }

                var hasBadChars = str.Any(c =>
                {
                    var cat = char.GetUnicodeCategory(c);

                    return(cat == UnicodeCategory.Control ||
                           cat == UnicodeCategory.Format ||
                           cat == UnicodeCategory.OtherNotAssigned ||
                           cat == UnicodeCategory.PrivateUse ||
                           cat == UnicodeCategory.Surrogate);
                });

                if (!control && hasBadChars)
                {
                    continue;
                }

                yield return(new PotentialString(offsetPos, offset, str));
            }
        }