рдпрд╣ рдореЛрдмрд╛рдЗрд▓ MMORPG рдХреЗ рдиреЗрдЯрд╡рд░реНрдХ рдЯреНрд░реИрдлрд╝рд┐рдХ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдкрд░ рд▓реЗрдЦреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧ рд╣реИред рдирдореВрдирд╛ рд▓реВрдк рд╡рд┐рд╖рдп:
- рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдмреАрдЪ рдкрд╛рд░реНрд╕ рд╕рдВрджреЗрд╢ рд╕реНрд╡рд░реВрдкред
- рдЧреЗрдо рдЯреНрд░реИрдлрд╝рд┐рдХ рдХреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗ рд╕реЗ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрдирдиреЗ рд╡рд╛рд▓рд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд┐рдЦрдирд╛ред
- рдЧреИрд░-HTTP рдкреНрд░реЙрдХреНрд╕реА рд╕рд░реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЯреНрд░реИрдлрд╝рд┐рдХ рдЕрд╡рд░реЛрдзрди рдФрд░ рдЗрд╕рдХрд╛ рд╕рдВрд╢реЛрдзрдиред
- рдЕрдкрдиреЗ рдЦреБрдж рдХреЗ ("рдкрд╛рдпрд░реЗрдЯреЗрдб") рд╕рд░реНрд╡рд░ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓рд╛ рдХрджрдоред
рдЗрд╕ рднрд╛рдЧ рдореЗрдВ рдореИрдВ рдПрдХ рд╢реНрд░рд╡рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди (рд╕реНрдирд┐рдлрд╝рд░) рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдБрдЧрд╛, рдЬреЛ рд╣рдореЗрдВ рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рд╕реНрд░реЛрдд рджреНрд╡рд╛рд░рд╛ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдиреЗ, рд╕рдВрджреЗрд╢ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдЪреБрдирд┐рдВрджрд╛ рд░реВрдк рд╕реЗ рд╕рд╣реЗрдЬрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рдФрд░ рдЦреЗрд▓ рдХреА рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ ("рдмрд╛рдЗрдирд░реА") рдореЗрдВ рднреА рдереЛрдбрд╝рд╛ рд╕рд╛ рдорд┐рд▓реЗрдЧрд╛ред рд╕рд╣рд╛рдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ
рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдмрдлрд╝рд░реНрд╕ рд╕рдорд░реНрдерди рдЬреЛрдбрд╝реЗрдВред рд░реБрдЪрд┐, рдореИрдВ рдмрд┐рд▓реНрд▓реА рдХреЗ рд▓рд┐рдП рдкреВрдЫрдирд╛ред
рдЖрд╡рд╢реНрдпрдХ рдЙрдкрдХрд░рдг
рдиреАрдЪреЗ рд╡рд░реНрдгрд┐рдд рдЪрд░рдгреЛрдВ рдХреЛ рджреЛрд╣рд░рд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдирд┐рдореНрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
- рдкреИрдХреЗрдЯ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рд╡рд┐рд░реЗрдЪрдХ;
- рдиреЗрдЯ;
- WinPcap рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП PcapDotNet рд▓рд╛рдЗрдмреНрд░реЗрд░реА;
- рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдмрдлрд╝рд░реНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрдЯреЛрдмреЙрдлрд╝-рдиреЗрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реАред
рд▓рд┐рд╕рдирд┐рдВрдЧ рдПрдкреНрд▓реАрдХреЗрд╢рди рд▓рд┐рдЦрдирд╛
рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо
рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рд╕реЗ рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ, рдЦреЗрд▓ рдЯреАрд╕реАрдкреА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдВрдЪрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╕рддреНрд░ рдХреЗ рдврд╛рдВрдЪреЗ рдореЗрдВ рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рд╕рд░реНрд╡рд░ рдФрд░ рдПрдХ рдкреЛрд░реНрдЯ рдкрд░ рд╣реЛрддрд╛ рд╣реИред рдЦреЗрд▓ рдЯреНрд░реИрдлрд╝рд┐рдХ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдп рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ:
- рдПрдХ рдореЛрдмрд╛рдЗрд▓ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдкреИрдХреЗрдЯ;
- рдлрд┐рд▓реНрдЯрд░ рдЧреЗрдо рдкреИрдХреЗрдЬ;
- рдЕрдЧрд▓реЗ рдкреИрдХреЗрдЯ рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдЖрдЧреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдмрдлрд░ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ;
- рдмрдлрд╝рд░реНрд╕ рд╕реЗ рдЧреЗрдо рдИрд╡реЗрдВрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЖрдмрд╛рдж рд╣реИрдВред
рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реНрдирд┐рдлрд░ рд╡рд░реНрдЧ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдкреИрдХреЗрдЯ рдХреЛ рдЕрд╡рд░реЛрдзрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП PcapDotNet рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
Sniff
рд╡рд┐рдзрд┐ рдореЗрдВ, рд╣рдо рдПрдбреЗрдкреНрдЯрд░ рдХрд╛ IP рдкрддрд╛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдкреАрд╕реА рдХрд╛ рдкрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рд╡рд╛рдИ-рдлрд╛рдИ рдХреЛ рдЙрд╕реА рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рднреАрддрд░ рдореЛрдмрд╛рдЗрд▓ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд▓рд┐рдП рд╡рд┐рддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдореЛрдмрд╛рдЗрд▓ рдбрд┐рд╡рд╛рдЗрд╕ рдХрд╛ рдЖрдИрдкреА рдкрддрд╛ рдФрд░ рд╕рд░реНрд╡рд░ рдХрд╛ рдЖрдИрдкреА рдкрддрд╛ред рдкрд┐рдЫрд▓реЗ рджреЛ рдХреА рдЕрд╕рдВрдЧрддрд┐ рдХреЗ рдХрд╛рд░рдг (рд╡рд┐рднрд┐рдиреНрди рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдФрд░ рд╕рд░реНрд╡рд░реЛрдВ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХреЗ рдорд╣реАрдиреЛрдВ рдХреЗ рдмрд╛рдж, рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рд╕рд░реНрд╡рд░ рдХрд╛ рдЪрдпрди ~ 50 рд╕рд░реНрд╡рд░реЛрдВ рдХреЗ рдПрдХ рдкреВрд▓ рд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ рдЕрднреА рднреА 5-7 рд╕рдВрднрд╛рд╡рд┐рдд рдкреЛрд░реНрдЯ рд╣реИрдВ), рдореИрдВ рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рддреАрди рдСрдХреНрдЯреЗрдЯ рд╕рдВрдЪрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реВрдВред рдЗрд╕ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ
IsTargetPacket
рдкрджреНрдзрддрд┐ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред
public class Sniffer { private byte[] _data = new byte[4096]; public bool Active { get; set; } = true; private string _adapterIP; private string _target; private string _server; private List<byte> _serverBuffer; private List<byte> _clientBuffer; private LivePacketDevice _device = null; private PacketCommunicator _communicator = null; private Action<Event> _eventCallback = null; public void Sniff(string ip, string target, string server) { _adapterIP = ip; _target = target; _server = server; _serverBuffer = new List<byte>(); _clientBuffer = new List<byte>(); IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine; for (int i = 0; i != allDevices.Count; ++i) { LivePacketDevice device = allDevices[i]; var address = device.Addresses[1].Address + ""; if (address == "Internet " + _adapterIP) { _device = device; } } _communicator = _device.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000); _communicator.SetFilter(_communicator.CreateFilter("ip and tcp")); new Thread(() => { Thread.CurrentThread.IsBackground = true; BeginReceive(); }).Start(); } private void BeginReceive() { _communicator.ReceivePackets(0, OnReceive); do { PacketCommunicatorReceiveResult result = _communicator.ReceivePacket(out Packet packet); switch (result) { case PacketCommunicatorReceiveResult.Timeout: continue; case PacketCommunicatorReceiveResult.Ok: OnReceive(packet); break; } } while (Active); } public void AddEventCallback(Action<Event> callback) { _eventCallback = callback; } private void OnReceive(Packet packet) { if (Active) { IpV4Datagram ip = packet.Ethernet.IpV4; if (IsTargetPacket(ip)) { try { ParseData(ip); } catch (ObjectDisposedException) { } catch (EndOfStreamException e) { Console.WriteLine(e); } catch (Exception) { throw; } } } } private bool IsTargetPacket(IpV4Datagram ip) { var sourceIp = ip.Source.ToString(); var destIp = ip.Destination.ToString(); return (sourceIp != _adapterIP && destIp != _adapterIP) && ( (sourceIp.StartsWith(_target) && destIp.StartsWith(_server)) || (sourceIp.StartsWith(_server) && destIp.StartsWith(_target)) ); } private void ParseData(IpV4Datagram ip) { TcpDatagram tcp = ip.Tcp; if (tcp.Payload != null && tcp.PayloadLength > 0) { var payload = ExtractPayload(tcp); AddToBuffer(ip, payload); ProcessBuffers(); } } private byte[] ExtractPayload(TcpDatagram tcp) { int payloadLength = tcp.PayloadLength; MemoryStream ms = tcp.Payload.ToMemoryStream(); byte[] payload = new byte[payloadLength]; ms.Read(payload, 0, payloadLength); return payload; } private void AddToBuffer(IpV4Datagram ip, byte[] payload) { if (ip.Destination.ToString().StartsWith(_target)) { foreach (var value in payload) _serverBuffer.Add(value); } else { foreach (var value in payload) _clientBuffer.Add(value); } } private void ProcessBuffers() { ProcessBuffer(ref _serverBuffer); ProcessBuffer(ref _clientBuffer); } private void ProcessBuffer(ref List<byte> buffer) {
рдорд╣рд╛рди, рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рд╕реЗ рдкреИрдХреЗрдЯ рдбреЗрдЯрд╛ рд╡рд╛рд▓реЗ рджреЛ рдмрдлрд╝рд░ рд╣реИрдВред рдЦреЗрд▓ рдФрд░ рд╕рд░реНрд╡рд░ рдХреЗ рдмреАрдЪ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЗ рдкреНрд░рд╛рд░реВрдк рдХреЛ рдпрд╛рдж рдХрд░реЗрдВ:
struct Event { uint payload_length <bgcolor=0xFFFF00, name="Payload Length">; ushort event_code <bgcolor=0xFF9988, name="Event Code">; byte payload[payload_length] <name="Event Payload">; };
рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЖрдк рдПрдХ
Event
рдЗрд╡реЗрдВрдЯ рдХреНрд▓рд╛рд╕ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:
public enum EventSource { Client, Server } public enum EventTypes : ushort { Movement = 11, Ping = 30, Pong = 31, Teleport = 63, EnterDungeon = 217 } public class Event { public uint ID; public uint Length { get; protected set; } public ushort Type { get; protected set; } public uint DataLength { get; protected set; } public string EventType { get; protected set; } public EventSource Direction { get; protected set; } protected byte[] _data; protected BinaryReader _br = null; public Event(byte[] data, EventSource direction) { _data = data; _br = new BinaryReader(new MemoryStream(_data)); Length = _br.ReadUInt32(); Type = _br.ReadUInt16(); DataLength = 0; EventType = $"Unknown ({Type})"; if (IsKnown()) { EventType = ((EventTypes)Type).ToString(); } Direction = direction; } public virtual void ParseData() { } public bool IsKnown() { return Enum.IsDefined(typeof(EventTypes), Type); } public byte[] GetPayload(bool hasDatLength = true) { var payloadLength = _data.Length - (hasDatLength ? 10 : 6); return new List<byte>(_data).GetRange(hasDatLength ? 10 : 6, payloadLength).ToArray(); } public virtual void Save() { var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Packets", EventType); Directory.CreateDirectory(path); File.WriteAllBytes(path + $"/{ID}.dump", _data); } public override string ToString() { return $"Type {Type}. Data length: {Length}."; } protected ulong ReadVLQ(bool readFlag = true) { if (readFlag) { var flag = _br.ReadByte(); } ulong vlq = 0; var i = 0; for (i = 0; ; i += 7) { var x = _br.ReadByte(); vlq |= (ulong)(x & 0x7F) << i; if ((x & 0x80) != 0x80) { break; } } return vlq; } }
рдЧреЗрдо рдореЗрдВ рд╕рднреА рдИрд╡реЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдХреЗ рд░реВрдк рдореЗрдВ
Event
рдХреНрд▓рд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣рд╛рдБ
Ping
рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╡рд░реНрдЧ рд╣реИ:
public class Ping : Event { private ulong _pingTime; public Ping(byte[] data) : base(data, EventSource.Client) { EventType = "Ping"; DataLength = 4; _pingTime = _br.ReadUInt32(); } public override string ToString() { return $"Pinging server at {_pingTime}ms."; } }
рдЕрдм рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╡реЗрдВрдЯ рдХреНрд▓рд╛рд╕ рд╣реИ, рддреЛ рд╣рдо
Sniffer
рддрд░реАрдХреЗ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:
private void ProcessBuffer(ref List<byte> buffer) { if (buffer.Count > 0) { while (Active) { if (buffer.Count > 4)
рдПрдХ рдлреЙрд░реНрдо рдХреНрд▓рд╛рд╕ рдмрдирд╛рдПрдВ рдЬреЛ рд╡рд╛рдпрд░рдЯреИрдк рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░реЗрдЧрд╛:
public partial class MainForm : Form { private Sniffer _sniffer = null; private List<Event> _events = new List<Event>(); private List<ushort> _eventTypesFilter = new List<ushort>(); private bool _showClientEvents = true; private bool _showServerEvents = true; private bool _showUnknownEvents = false; private bool _clearLogsOnRestart = true; private uint _eventId = 1; private void InitializeSniffer() { _sniffer = new Sniffer(); _sniffer.AddEventCallback(NewEventThreaded); _sniffer.Sniff("192.168.137.1", "192.168.137.", "123.45.67."); } private void NewEventThreaded(Event ev) { events_table.Invoke(new NewEventCallback(NewEvent), ev); } public delegate void NewEventCallback(Event ev); private void NewEvent(Event ev) { ev.ID = _eventId++; _events.Add(ev); LogEvent(ev); } private void LogEvent(Event ev) { if (FilterEvent(ev)) { var type = ev.GetType(); events_table.Rows.Add(1); events_table.Rows[events_table.RowCount - 1].Cells[0].Value = ev.ID; events_table.Rows[events_table.RowCount - 1].Cells[1].Value = ev.EventType; events_table.Rows[events_table.RowCount - 1].Cells[2].Value = Enum.GetName(typeof(EventSource), ev.Direction); events_table.Rows[events_table.RowCount - 1].Cells[3].Value = ev.ToString(); } } private void ReloadEvents() { events_table.Rows.Clear(); events_table.Refresh(); foreach (var ev in _events) { LogEvent(ev); } } private bool FilterEvent(Event ev) { return ( (ev.Direction == EventSource.Client && _showClientEvents) || (ev.Direction == EventSource.Server && _showServerEvents) ) && (_eventTypesFilter.Contains(ev.Type) || (!ev.IsKnown() && _showUnknownEvents)); } }
рд╣реЛ рдЧрдпрд╛! рдЕрдм рдЖрдк рдШрдЯрдирд╛рдУрдВ рдХреА рд╕реВрдЪреА рдХреЗ рдкреНрд░рдмрдВрдзрди рдХреЗ рд▓рд┐рдП рдХреБрдЫ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ (рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ
_eventTypesFilter
рднрд░рд╛ рд╣реБрдЖ рд╣реИ) рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдореЗрдВ рджреЗрдЦрдирд╛ (рдореБрдЦреНрдп рддрд╛рд▓рд┐рдХрд╛
events_table
)ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд╛рдирджрдВрдбреЛрдВ (
FilterEvent
рд╡рд┐рдзрд┐) рджреНрд╡рд╛рд░рд╛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд┐рдпрд╛:
- рдЧреНрд░рд╛рд╣рдХ рд╕реЗ рдШрдЯрдирд╛рдУрдВ рдХреЛ рджрд┐рдЦрд╛рдиреЗ;
- рд╕рд░реНрд╡рд░ рд╕реЗ рдШрдЯрдирд╛рдУрдВ рдХреЛ рджрд┐рдЦрд╛рдиреЗ;
- рдЕрдЬреНрдЮрд╛рдд рдШрдЯрдирд╛рдУрдВ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди;
- рдЪрдпрдирд┐рдд рдЬреНрдЮрд╛рдд рдШрдЯрдирд╛рдУрдВ рдХреЛ рджрд┐рдЦрд╛рдПрдВред
рдЦреЗрд▓ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рд╕реАрдЦрдирд╛
рдпрджреНрдпрдкрд┐ рдЕрдм рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рдмрд┐рдирд╛ рдЦреЗрд▓ рдХреА рдШрдЯрдирд╛рдУрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рд╕рднреА рдШрдЯрдирд╛ рдХреЛрдбреЛрдВ рдХреЗ рдЕрд░реНрде рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рди рдХреЗрд╡рд▓ рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдореИрдиреБрдЕрд▓ рдХрд╛рдо рд╣реИ, рдмрд▓реНрдХрд┐ рдкреЗрд▓реЛрдб рдХреА рд╕рдВрд░рдЪрдирд╛ рднреА рд╣реИ, рдЬреЛ рдХрд╛рдлреА рдореБрд╢реНрдХрд┐рд▓ рд╣реЛрдЧрд╛, рдЦрд╛рд╕рдХрд░ рдЕрдЧрд░ рдпрд╣ рдХреБрдЫ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЦреЗрд▓ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреБрдЫ рдЬрд╛рдирдХрд╛рд░реА рджреЗрдЦрдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рдЪреВрдВрдХрд┐ рдЦреЗрд▓ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо (рд╡рд┐рдВрдбреЛрдЬ, рдЖрдИрдУрдПрд╕ рдФрд░ рдПрдВрдбреНрд░реЙрдЗрдб рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ), рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдХрд▓реНрдк рдЙрдкрд▓рдмреНрдз рд╣реИрдВ:
- .exe рдлрд╝рд╛рдЗрд▓ (рдореИрдВрдиреЗ рдкрде C рдкрд░ рд╕реНрдерд┐рдд рд╣реИ: / рдкреНрд░реЛрдЧреНрд░рд╛рдо рдлрд╝рд╛рдЗрд▓реЗрдВ / WindowsApps /% appname% /;
- рдПрдХ рдмрд╛рдЗрдирд░реА рдЖрдИрдУрдПрд╕ рдлрд╝рд╛рдЗрд▓ рдЬреЛ рдРрдкреНрдкрд▓ рджреНрд╡рд╛рд░рд╛ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдЧрдИ рд╣реИ, рд▓реЗрдХрд┐рди рдЬреЗрд▓рдмреНрд░реАрдХ рдХреЗ рд╕рд╛рде рдЖрдк рдХреНрд░реИрдХреБрд▓рд╕ рдпрд╛ рдЗрд╕ рддрд░рд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбрд┐рдХреНрд░рд┐рдкреНрдЯреЗрдб рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ;
- Android рд╕рд╛рдЭрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдпрд╣ рдкрде / рдбреЗрдЯрд╛ / рдбреЗрдЯрд╛ /% рдРрдк-рд╡рд┐рдХреНрд░реЗрддрд╛-рдирд╛рдо% / lib / рдкрд░ рд╕реНрдерд┐рдд рд╣реИред
Android рдФрд░ iOS рдХреЗ рд▓рд┐рдП рдХреМрди рд╕реЗ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХрд╛ рдЪрдпрди рдХрд░рдирд╛ рд╣реИ, рдЗрд╕рдХрд╛ рдХреЛрдИ рдЕрдиреБрдорд╛рди рдирд╣реАрдВ рд╣реИ, рдореИрдВрдиреЗ рдПрдХ .exe рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХреА рд╣реИред рд╣рдо рдмрд╛рдЗрдирд░реА рдХреЛ рдЖрдИрдбреАрдП рдореЗрдВ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреА рдкрд╕рдВрдж рджреЗрдЦрддреЗ рд╣реИрдВред

рд╣рдорд╛рд░реА рдЦреЛрдЬ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдХреБрдЫ рдмрд╣реБрдд рд╣реА рдЙрдкрдпреЛрдЧреА рд▓рд╛рдЗрдиреЗрдВ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдХреЛрдбрд╛рдВрддрд░рдХ рдХрд╛ рдЕрдкрдШрдЯрди рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд┐рд░реНрдл "рдмрд╛рдЗрдирд░реА рдлрд╛рдЗрд▓" рдФрд░ "рдПрдордПрд╕-рдбреЙрд╕ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп" рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рдмрд╛рдж рд╕реЗ "рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп 80386" рд╡рд┐рдХрд▓реНрдк рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИред "рдУрдХреЗ" рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ, рдлрд╝рд╛рдЗрд▓ рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд▓реЛрдб рд╣реЛрдиреЗ рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ, рдФрд░ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдирд╛ рдЙрдЪрд┐рдд рд╣реИред рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд╛ рдЕрдВрдд рдЗрд╕ рддрдереНрдп рд╕реЗ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдиреАрдЪреЗ рдмрд╛рдИрдВ рдУрд░ рд╕реНрдерд┐рдд рд╕реНрдерд┐рддрд┐ рдкрдЯреНрдЯреА рдореЗрдВ рдирд┐рдореНрди рд╕реНрдерд┐рддрд┐ рд╣реЛрдЧреА:

рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдЯреИрдм рдкрд░ рдЬрд╛рдПрдВ (рджреЗрдЦреЗрдВ / рдУрдкрди рд╕рдмрд╡реНрдпреВ / рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдпрд╛
Shift + F12
)ред рд▓рд╛рдЗрди рдЬрдирд░реЗрд╢рди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдХреБрдЫ рд╕рдордп рд▓рдЧ рд╕рдХрддрд╛ рд╣реИред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, ~ 47k рд▓рд╛рдЗрдиреЗрдВ рдорд┐рд▓реАрдВред рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рд╕реНрдерд╛рди рдХреЗ рд▓рд┐рдП рдкрддреЗ рдореЗрдВ рдкреНрд░рдкрддреНрд░ рдХрд╛ рдПрдХ рдЙрдкрд╕рд░реНрдЧ рд╣реЛрддрд╛ рд╣реИ
.rdata
рдФрд░
рдЕрдиреНрдп ред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рднреА "рд░реЛрдЪрдХ" рд▓рд╛рдЗрдиреЗрдВ
.rdata
рдЦрдВрдб рдореЗрдВ рдереАрдВ, рдЬрд┐рд╕рдХрд╛ рдЖрдХрд╛рд░ ~ 44.5k рд░рд┐рдХреЙрд░реНрдб рдерд╛ред рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ:
- рд▓реЙрдЧрд┐рди рдЪрд░рдг рдХреЗ рджреМрд░рд╛рди рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдФрд░ рдХреНрд╡реЗрд░реА рд╕реЗрдЧрдореЗрдВрдЯ;
- рдЧреЗрдо, рдЧреЗрдо рдЗрдВрдЬрди, рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рд▓рд┐рдП рдПрд░рд░ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдФрд░ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреА рдЬрд╛рдирдХрд╛рд░реА;
- рдмрд╣реБрдд рд╕рд╛рд░рд╛ рдХрдЪрд░рд╛;
- рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рддрд░рдл рдЧреЗрдо рдЯреЗрдмрд▓ рдХреА рдПрдХ рд╕реВрдЪреА;
- рдЦреЗрд▓ рдореЗрдВ рдЦреЗрд▓ рдЗрдВрдЬрди рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛;
- рдкреНрд░рднрд╛рд╡реЛрдВ рдХреА рд╕реВрдЪреА;
- рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреБрдВрдЬреА рдХреА рд╡рд┐рд╢рд╛рд▓ рд╕реВрдЪреА;
- рдЖрджрд┐
рдЕрдВрдд рдореЗрдВ, рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдЕрдВрдд рдХреЗ рдХрд░реАрдм рдЖрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХреНрдпрд╛ рджреЗрдЦ рд░рд╣реЗ рдереЗред

рдпрд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рдХреЗ рдмреАрдЪ рдИрд╡реЗрдВрдЯ рдХреЛрдб рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИред рдЦреЗрд▓ рдХреЗ рдиреЗрдЯрд╡рд░реНрдХ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╕рдордп рдпрд╣ рд╣рдорд╛рд░реЗ рдЬреАрд╡рди рдХреЛ рд╕рд░рд▓ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рд╡рд╣рд╛рдБ рдирд╣реАрдВ рд░реБрдХреЗрдВрдЧреЗ! рдпрд╣ рдЬрд╛рдВрдЪрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдШрдЯрдирд╛ рдХреЛрдб рдХрд╛ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдореВрд▓реНрдп рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред рд╣рдо рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдХреЛрдб
CMSG_PING
рдФрд░
SMSG_PONG
рдХреЗ "рдкрд░рд┐рдЪрд┐рдд" рдХреЛ
SMSG_PONG
30 (
1E 16
) рдФрд░ 31 (
1F 16
) рдХреЛрдб рдХреЗ рд╕рд╛рде
SMSG_PONG
рд╣реИрдВред рдХреЛрдб рдореЗрдВ рдЗрд╕ рд╕реНрдерд╛рди рдкрд░ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрди рдкрд░ рдбрдмрд▓-рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдХреЛрдб рдХреЗ
0x10 0x1E
рдореВрд▓реНрдпреЛрдВ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж
0x10 0x1E
рдФрд░
0x10 0x1F
рдХрд╛ рдПрдХ рдХреНрд░рдо рд╣реИред рдЦреИрд░, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЖрдк рдкреВрд░реА рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдШрдЯрдирд╛рдУрдВ рдХреА рд╕реВрдЪреА рдФрд░ рдЙрдирдХреЗ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдореВрд▓реНрдп рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдЖрдЧреЗ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЛ рд╕рд░рд▓ рдХрд░реЗрдЧрд╛ред
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЧреЗрдо рдХрд╛ рд╡рд┐рдВрдбреЛрдЬ рд╕рдВрд╕реНрдХрд░рдг рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рдореЛрдмрд╛рдЗрд▓ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рд╕реЗ рдкреАрдЫреЗ рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП .exe рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдпрджреНрдпрдкрд┐ рдпрд╣ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЗрд╕ рдкрд░ рднрд░реЛрд╕рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рд╕рд╛рде рдбрд╛рдпрдиреЗрдорд┐рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛, рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдПрдХ рдордВрдЪ рдкрд░ рджреЗрдЦрд╛ рдХрд┐ рдЖрдИрдУрдПрд╕ рдмрд╛рдпрдиреЗрд░рд┐рдЬрд╝ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реА рдореЗрдЯрд╛-рдЬрд╛рдирдХрд╛рд░реА рд╣реИред рд▓реЗрдХрд┐рди рдЕрдлрд╕реЛрд╕,
CMSG_PING
рдорд╛рди
CMSG_PING
рдореЗрдВ рдПрдХ рдЦреЛрдЬ рдХреЗ рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖрдПред
рдЖрд╢рд╛ рдХреЗ рдмрд┐рдирд╛, рдореИрдВ iOS рдмрд╛рдЗрдирд░реА рдореЗрдВ рдПрдХ рд╣реА рдЦреЛрдЬ рдХрд░ рд░рд╣рд╛ рд╣реВрдБ - рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп, рд▓реЗрдХрд┐рди рд╡рд╣рд╛рдБ рдбреЗрдЯрд╛ред Exe рдХреЗ рд╕рдорд╛рди рд╣реА рдирд┐рдХрд▓рд╛! рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЖрдИрдбреАрдП рдкрд░ рдЕрдкрд▓реЛрдб рдХрд░реЗрдВред

рдореИрдВ рдкрд╣рд▓рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╡рд┐рдХрд▓реНрдк рдЪреБрдирддрд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХрд┐рд╕рдХреА рдЬрд░реВрд░рдд рд╣реИ рдлрд┐рд░ рд╕реЗ, рд╣рдо рдлрд╝рд╛рдЗрд▓ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдЕрдВрдд рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ (рдмрд╛рдЗрдирд░реА рдЖрдХрд╛рд░ рдореЗрдВ рд▓рдЧрднрдЧ 4 рдЧреБрдирд╛ рдмрдбрд╝рд╛ рд╣реИредред, рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╕рдордп, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рднреА рдмрдврд╝ рдЧрдпрд╛ рд╣реИ)ред рд╣рдо рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЦрд┐рдбрд╝рдХреА рдЦреЛрд▓рддреЗ рд╣реИрдВ, рдЬреЛ рдЗрд╕ рдмрд╛рд░ 51k рдирд┐рдХрд▓рд╛ред
Ctrl + F
рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рдо
CMSG_PING
рдФрд░ ... рд╣рдореЗрдВ рдпрд╣ рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рд╣реИред рд╡рд░реНрдг рджреНрд╡рд╛рд░рд╛ рдХреЛрдб рд╡рд░реНрдг рджрд░реНрдЬ рдХрд░рддреЗ рд╣реБрдП, рдЖрдк рдЗрд╕ рдкрд░рд┐рдгрд╛рдо рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ:

рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ, IDA рдиреЗ рдкреВрд░реА
Opcode.proto
рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рд░рдЦрд╛ред рдХреЛрдб рдореЗрдВ рдЗрд╕ рд╕реНрдерд╛рди рдкрд░ рдбрдмрд▓-рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рд╕рдВрд░рдЪрдирд╛ рдХреЛ .exe рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рдорд╛рди рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдк рдЗрд╕реЗ рдХрд╛рдЯ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ
Enum
рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЕрдВрдд рдореЗрдВ, рдпрд╣ рдпрд╛рдж рд░рдЦрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐, рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдкрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ,
рдПрдорд▓ рдиреЗ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдХрд┐ рдЦреЗрд▓ рдХреА рд╕рдВрджреЗрд╢ рд╕рдВрд░рдЪрдирд╛
рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдмрдлрд╝рд░реНрд╕ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред рдпрджрд┐ рдЖрдк рдмрд╛рдЗрдирд░реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреЛрдб рдХреЛ рдХрд░реАрдм рд╕реЗ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐
Opcode
рд╡рд┐рд╡рд░рдг рдЗрд╕ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рднреА рд╣реИред

рд╣рдо рд╕рднреА рдХреЛрдб рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 010Editor рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд╛рд░реНрд╕рд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рд▓рд┐рдЦреЗрдВрдЧреЗред
рдЕрдкрдбреЗрдЯреЗрдб рдкреИрдХ * 010Editor рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк рдХреЛрдбрдорд╛рдореВрд▓реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдореЗрдВ рд▓рд╛рдкрддрд╛ рд▓реЛрдЧреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝реАрд▓реНрдб рд▓реЗрдмрд▓ рд╕рддреНрдпрд╛рдкрди рд╣реЛрддрд╛ рд╣реИред
uint PeekTag() { if (FTell() == FileSize()) { return 0; } Varint tag; FSkip(-tag.size); return tag._ >> 3; } struct Packed (uint fieldNumber) { if (PeekTag() != fieldNumber) { break; } Varint key <bgcolor=0xFFBB00>; local uint wiredType = key._ & 0x7; local uint field = key._ >> 3; local uint size = key.size; switch (wiredType) { case 1: double value; size += 8; break; case 5: float value; size += 4; break; default: Varint value; size += value.size; break; } }; struct PackedString(uint fieldNumber) { if (PeekTag() != fieldNumber) { break; } Packed length(fieldNumber); char str[length.value._]; };
struct Code { Packed size(2) <bgcolor=0x00FF00>; PackedString code_name(1) <bgcolor=0x00FF00>; Packed code_value(2) <bgcolor=0x00FF00>; Printf("%s = %d,\n", code_name.str, code_value.value._);
рдкрд░рд┐рдгрд╛рдо рдХреБрдЫ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк! рд╡рд╕реНрддреБ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЕрдзрд┐рд╕реВрдЪрд┐рдд
pb
? рдЕрдиреНрдп рд░реЗрдЦрд╛рдУрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛, рдЕрдЪрд╛рдирдХ рдЗрд╕ рддрд░рд╣ рдХреА рдмрд╣реБрдд рд╕рд╛рд░реА рд╡рд╕реНрддреБрдПрдВ рд╣реИрдВ?

рдкрд░рд┐рдгрд╛рдо рдмреЗрд╣рдж рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд╣реИрдВред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдЦреЗрд▓ рдХреА рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдХрдИ рдкреНрд░рдХрд╛рд░ рдХреЗ рдбреЗрдЯрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдмреАрдЪ рдЧрдгрдирд╛ рдФрд░ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рд░реВрдк рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдпрд╣рд╛рдБ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд░реНрдгрди рдХрд╛ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬреЛ рджреБрдирд┐рдпрд╛ рдореЗрдВ рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ:

рдПрдХ рддреНрд╡рд░рд┐рдд рдЦреЛрдЬ рдиреЗ рджреЛ рдмрдбрд╝реЗ рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рдкреНрд░рдХрдЯ рдХрд┐рдпрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдПрдХ рдХрд░реАрдмреА рдкрд░реАрдХреНрд╖рд╛ рд╢рд╛рдпрдж рдЕрдиреНрдп рдЫреЛрдЯреЗ рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рдкреНрд░рдХрдЯ рдХрд░реЗрдЧреАред рдЙрдиреНрд╣реЗрдВ рдХрд╛рдЯрдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдлрд╝рд╛рдЗрд▓ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рд╡рд░рдг рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП C # рдореЗрдВ рдПрдХ рдЫреЛрдЯреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦреА (рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдпрд╣ рдШрдЯрдирд╛ рдХреЛрдб рдХреА рд╕реВрдЪреА рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рдорд╛рди рд╣реИ) - 010Editor рдореЗрдВ рдЙрдирдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред
class Program { static void Main(string[] args) { var br = new BinaryReader(new FileStream("./BinaryFile.partX", FileMode.Open)); while (br.BaseStream.Position < br.BaseStream.Length) { var startOffset = br.BaseStream.Position; var length = ReadVLQ(br, out int size); var tag = br.ReadByte(); var eventName = br.ReadString(); br.BaseStream.Position = startOffset; File.WriteAllBytes($"./parsed/{eventName}", br.ReadBytes((int)length + size + 1)); } } static ulong ReadVLQ(BinaryReader br, out int size) { var flag = br.ReadByte(); ulong vlq = 0; size = 0; var i = 0; for (i = 0; ; i += 7) { var x = br.ReadByte(); vlq |= (ulong)(x & 0x7F) << i; size++; if ((x & 0x80) != 0x80) { break; } } return vlq; } }
рдореИрдВ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд░реВрдк рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╛ рддреЛ рдпрд╣ рдкреНрд░рд╢реНрди рдореЗрдВ рдЦреЗрд▓ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИ, рдпрд╛ рдпрд╣
Protocol Buffers
рдореЗрдВ рдЖрдо рддреМрд░ рдкрд░ рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдкреНрд░рд╛рд░реВрдк рд╣реИ (рдпрджрд┐ рдХреЛрдИ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЬрд╛рдирддрд╛ рд╣реИ, рддреЛ рдХреГрдкрдпрд╛ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВ)ред рдореИрдВ рдХреНрдпрд╛ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реИ:
- рд╡рд┐рд╡рд░рдг
Protocol Buffers
рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рднреА рдЖрддрд╛ рд╣реИ; - рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЙрд╕рдХрд╛ рдирд╛рдо, рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЙрд╕рдХреА рдЕрдкрдиреА рдкреНрд░рдХрд╛рд░ рдХреА рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:
string TypeToStr (uint type) { switch (type) { case 2: return "Float"; case 4: return "UInt64"; case 5: return "UInt32"; case 8: return "Boolean"; case 9: return "String"; case 11: return "Struct"; case 14: return "Enum"; default: local string s; SPrintf(s, "%Lu", type); return s; } };
- рдпрджрд┐ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдПрдХ рдЧрдгрдирд╛ рдпрд╛ рд╕рдВрд░рдЪрдирд╛ рд╣реИ, рддреЛ рд╡рд╛рдВрдЫрд┐рдд рд╡рд╕реНрддреБ рдХрд╛ рдПрдХ рд▓рд┐рдВрдХ рдерд╛ред
рдЦреИрд░, рдЖрдЦрд┐рд░реА рдЪреАрдЬ рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ рд╡рд╣ рд╣реИ рд╣рдорд╛рд░реЗ рд╕реБрдирдиреЗ рд╡рд╛рд▓реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:
protobuf-net
рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдирд╛ред
using ProtoBuf;
рдорд╛рдзреНрдпрдо рд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ,
using ProtoBuf;
рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЖрдк рд╕рдВрджреЗрд╢реЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдХреНрд╖рд╛рдПрдВ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рд╕реЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд▓реЗрдВ: рдЪрд░рд┐рддреНрд░ рдЖрдВрджреЛрд▓рдиред рдЬрдм рд╣рд╛рдЗрд▓рд╛рдЗрдЯрд┐рдВрдЧ рдЦрдВрдб рдЗрд╕ рд╕реНрд╡рд░реВрдк рдХрд╛ рд╕реНрд╡рд░реВрдкрд┐рдд рд╡рд┐рд╡рд░рдг рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

рдбреАрдмрдЧ рдЖрдЙрдЯрдкреБрдЯ рдЖрдкрдХреЛ рдЗрд╕рд╕реЗ рдЫреЛрдЯрд╛ рд╡рд┐рд╡рд░рдг рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:
Field 1 (Type 13): time Field 2 (Struct .pb.CxGS_Vec3): position Field 3 (UInt64): guid Field 4 (Struct .pb.CxGS_Vec3): direction Field 5 (Struct .pb.CxGS_Vec3): speed Field 6 (UInt32): state Field 10 (UInt32): flag Field 11 (Float): y_speed Field 12 (Boolean): is_flying Field 7 (UInt32): emote_id Field 9 (UInt32): emote_duration Field 8 (Boolean): emote_loop
рдЕрдм рдЖрдк
protobuf-net
рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдкрдпреБрдХреНрдд рд╡рд░реНрдЧ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред
[ProtoContract] public class MoveInfo : ProtoBufEvent<MoveInfo> { [ProtoMember(3)] public ulong GUID; [ProtoMember(1)] public ulong Time; [ProtoMember(2)] public Vec3 Position; [ProtoMember(4)] public Vec3 Direction; [ProtoMember(5)] public Vec3 Speed; [ProtoMember(6)] public ulong State; [ProtoMember(7, IsRequired = false)] public uint EmoteID; [ProtoMember(8, IsRequired = false)] public bool EmoteLoop; [ProtoMember(9, IsRequired = false)] public uint EmoteDuration; [ProtoMember(10, IsRequired = false)] public uint Flag; [ProtoMember(11, IsRequired = false)] public float SpeedY; [ProtoMember(12)] public bool IsFlying; public override string ToString() { return $"{GUID}: {Position}"; } }
рддреБрд▓рдирд╛ рдХреЗ рд▓рд┐рдП, рдпрд╣рд╛рдВ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рд╕реЗ рдЙрд╕реА рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИ:
struct MoveEvent { uint data_length <bgcolor=0x00FF00, name="Data Length">; Packed move_time <bgcolor=0x00FFFF>; PackedVector3 position <bgcolor=0x00FF00>; PackedVector3 direction <bgcolor=0x00FF00>; PackedVector3 speed <bgcolor=0x00FF00>; Packed state <bgcolor=0x00FF00>; };
рдЬрдм
Event
рдХреНрд▓рд╛рд╕ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ
ParseData
, рддреЛ рд╣рдо рдкреИрдХреЗрдЬ рдбреЗрдЯрд╛ рдХреЛ
ParseData
рдХрд░рдХреЗ
ParseData
рд╡рд┐рдзрд┐ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
class CMSG_MOVE_INFO : Event { private MoveInfo _message; [...] public override void ParseData() { _message = MoveInfo.Deserialize(GetPayload()); } public override string ToString() { return _message.ToString(); } }
рд╡рд╣ рд╕рдм рд╣реИред рдЕрдЧрд▓рд╛ рдХрджрдо рдЗрдВрдЬреЗрдХреНрд╢рди, рд╕реНрдкреВрдлрд┐рдВрдЧ рдФрд░ рдХрдЯрд┐рдВрдЧ рдкреИрдХреЗрдЬ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рдЧреЗрдо рдХреЗ рдЯреНрд░реИрдлрд╝рд┐рдХ рдХреЛ рд╣рдорд╛рд░реЗ рдкреНрд░реЙрдХреНрд╕реА рд╕рд░реНрд╡рд░ рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рдирд╛ рд╣реИред