Форум администраторов игровых серверов

Форум администраторов игровых серверов (https://forum.zone-game.info/TT.php)
-   ArcheAge (https://forum.zone-game.info/forumdisplay.php?f=187)
-   -   Отправка пакетов(C#) (https://forum.zone-game.info/showthread.php?t=34398)

Tezarius 11.03.2014 20:42

Отправка пакетов(C#)
 
Приветствую!
Ради интереса решил написать собственный сниффер на C#(с сокетами очень мало опыта).
Нашел несколько рабочих вариантов, из них собрал что-то более-менее рабочее.
Принцип действия следующий: сокет привязывается к существующему интерфейсу, через который идет траффик, по событию BeginReceive передает принятый пакет на обработчик, внутри которого уже фильтруются и выводятся нужные мне пакеты(к примеру, по IP).

Выглядит это как-то так:

Код:

                Action<IAsyncResult> OnReceive = null;
                buffer_list = new byte[4096];


                socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
                socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
                socket.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.100"), 0));

                byte[] byInc1 = new byte[] { 1, 0, 0, 0 };
                byte[] byOut1 = new byte[4];
                socket.IOControl(IOControlCode.ReceiveAll, byInc1, byOut1);


                OnReceive = (ar) =>
                {
                    int nReceived = 0;
                    try
                    {
                        nReceived = socket.EndReceive(ar);
                        Print(buffer_list, nReceived);
                        buffer_list = new byte[4096];

                        socket.BeginReceive(buffer_list, 0, buffer_list.Length, SocketFlags.None, new AsyncCallback(OnReceive), null);
                    }
                    catch (Exception)
                    {
                        return;
                    }
                };

                socket.BeginReceive(buffer_list, 0, buffer_list.Length, SocketFlags.None, new AsyncCallback(OnReceive), null);

где Print - функция-обработчик(на данный момент выводит пакеты между нужными IP, логирует их и все такое).



А вопрос заключается вот в чем: как сдампленные пакеты(либо сформированные) отправить обратно по назначению?

Ugly 12.03.2014 02:05

Re: Отправка пакетов(C#)
 
Дем, у тебя ус отклеился :D
А чтобы не возиться с tcp/ip хедерами и иметь возможность отправлять пакеты, соединение нужно устанавливать самому. Ну или ещё вариант - работать через клиент игры, но тут уже не чистый C#, а надо что-то инжектить в чужой процесс.

WoWan-SM 12.03.2014 02:38

Re: Отправка пакетов(C#)
 
Готовый шаблон того что тебе нужно:
http://habrahabr.ru/post/142819/

А в кратце используй готовые классы:
Socket
TcpClient
StreamReader
StreamWriter

MadHacker 12.03.2014 08:41

Re: Отправка пакетов(C#)
 
Чтоб отправлять данные - тебе уже не сниффер нужен, а прокси.
Вот только к чему писать с нуля свой софт, когда уже есть готовый? Тот же Сауроновский WPF.
К слову и для сниффера есть готовые библиотеки.

Onax 12.03.2014 09:34

Re: Отправка пакетов(C#)
 
Вот из инета простейший SOCKS 5 прокси (в общих чертах)
качаешь Proxifier, направляешь траффик на него...там две кнопки, разберешься
и всё, твой сниффер готов, пакеты ловятся можно смотреть/выводить/отправлять/менять

Код:

delegate void PacketHandlerDelegate(ref byte[] packet, int size);
class SocksProxy
{
    public PacketHandlerDelegate ServerPacketHandler;
    public PacketHandlerDelegate ClientPacketHandler;
    public int Port;

    public SocksProxy(int port)
    {
        this.Port = port;
    }

    public void Listen()
    {
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        listener.Bind(new IPEndPoint(IPAddress.Any, Port));
        listener.Listen(100);
        listener.BeginAccept(listener_Accept, listener);
    }

    private void listener_Accept(IAsyncResult ar)
    {
        byte[] buffer = new byte[2048];
        Socket listener = (Socket)ar.AsyncState;
        listener.BeginAccept(listener_Accept, listener);

        Socket _in = listener.EndAccept(ar);
        Socket _out = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        _in.Receive(buffer, 0, buffer.Length, SocketFlags.None);

        if (buffer[0] == 5 && buffer[2] == 0)
        {
            buffer[1] = 0;
            _in.Send(buffer, 0, 2, SocketFlags.None);
            _in.Receive(buffer, 0, buffer.Length, SocketFlags.None);

            IPEndPoint remoteEndPoint = GetAddress(ref buffer);
            switch (buffer[1])
            {
                case 1:
                    _out.Connect(remoteEndPoint);
                    Console.WriteLine("Socket connected to " + remoteEndPoint);
                    break;

                case 2:
                    _out.Bind(remoteEndPoint);
                    Console.WriteLine("Socket binded to " + remoteEndPoint);
                    break;
            }

            buffer[1] = 0;
            _in.Send(buffer, 0, 10, SocketFlags.None);


            NetworkState state = new NetworkState(_in, _out, buffer);
            _out.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, out_Receive, state);
            _in.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, in_Receive, state);
        }
    }

    private IPEndPoint GetAddress(ref byte[] buf)
    {
        switch (buf[3])
        {
            case 1:
                string ip = buf[4] + "." + buf[5] + "." + buf[6] + "." + buf[7];
                int port = buf[8] * 256 + buf[9];
                return new IPEndPoint(IPAddress.Parse(ip), port);

            case 3:
                byte len = buf[8];
                string host = Encoding.ASCII.GetString(buf, 9, len);
                return HostResolve(host);

            default:
                return new IPEndPoint(0, 0);
        }
    }

    private IPEndPoint HostResolve(string hostname)
    {
        IPHostEntry host = Dns.GetHostEntry(hostname);
        foreach (IPAddress ip in host.AddressList)
        {
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            {
                return new IPEndPoint(ip, 80);
            }
        }
        return new IPEndPoint(0, 0);
    }

    private void in_Receive(IAsyncResult ar)
    {
        NetworkState state = (NetworkState)ar.AsyncState;
        int received = state.In.EndReceive(ar);

        if (received > 0)
        {
            Console.WriteLine("{0} -> {1}", state.In.RemoteEndPoint, state.Out.RemoteEndPoint);
            Console.WriteLine(Utils.HexDump(state.Buffer, received));
            if (ClientPacketHandler != null)
                ClientPacketHandler(ref state.Buffer, received);
            state.Out.Send(state.Buffer, 0, received, SocketFlags.None);
            state.In.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, in_Receive,
                new NetworkState(state.In, state.Out, state.Buffer));
        }
        else
        {
            state.In.Shutdown(SocketShutdown.Both);
            Console.WriteLine("{0} отключен", state.In.RemoteEndPoint);
        }
    }

    private void out_Receive(IAsyncResult ar)
    {
        NetworkState state = (NetworkState)ar.AsyncState;
        int received = state.Out.EndReceive(ar);

        if (received > 0)
        {
            Console.WriteLine("{0} -> {1}", state.Out.RemoteEndPoint, state.In.RemoteEndPoint);
            if (ServerPacketHandler != null)
                ServerPacketHandler(ref state.Buffer, received);
            state.In.Send(state.Buffer, 0, received, SocketFlags.None);
            state.Out.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, out_Receive,
                new NetworkState(state.In, state.Out, state.Buffer));
        }
        else
        {
            state.Out.Shutdown(SocketShutdown.Both);
            Console.WriteLine("{0} отключен", state.Out.RemoteEndPoint);
        }
    }
    private class NetworkState
    {
        public byte[] Buffer;
        public Socket In;
        public Socket Out;
        public NetworkState(Socket sin, Socket sout, byte[] buff)
        {
            this.Buffer = buff;
            this.In = sin;
            this.Out = sout;
        }
    }
}


Tezarius 12.03.2014 20:33

Re: Отправка пакетов(C#)
 
Благодарю.

Nehrk 13.03.2014 01:28

Re: Отправка пакетов(C#)
 
оффтоп:
Свернуть ↑Развернуть ↓


Текущее время: 09:20. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot