Перехват пакетов

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by WON, 19 Jan 2009.

  1. WON

    WON New Member

    Joined:
    2 Jul 2008
    Messages:
    17
    Likes Received:
    2
    Reputations:
    0
    Решил написать программку для пеерхвата пакетов только для моего компьютера, для начала хотя бы читать их содержимое...
    Начал писать на С++, но прога не очень то и работает... Непонятно когда и по каким принцыпам(лично для меня так) она выводит содержимое пакетов(и то не всё)... Может мне ктонибудь подскажет аглоритм и программые методы для осуществение моей цели...

    Code:
    #include <winsock2.h>
    #include <windows.h>
    #include <iostream.h>
    #include <conio.h>
    #include <stdio.h>
    
    #pragma comment( lib, "wsock32.lib" )
    
    int main()
    {
    	WSADATA wd;
    	char buff[1000];
    	SOCKET s, news;
    	sockaddr_in sin, newsin;
    
    	sin.sin_family = AF_INET;
    	sin.sin_port = htons(2593);
    	sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    	
    	if(FAILED(WSAStartup( MAKEWORD(2,2), &wd)) )
    	{
    		cout<<"WSA error - "<<WSAGetLastError()<<endl;
    		return -1;
    	}
    
    	if( (s=socket(AF_INET,SOCK_STREAM,0)) == -1 )
    	{
    		cout<<"WSA error - "<<WSAGetLastError()<<endl;
    		return -1;
    	}
    
         if(bind(s, (sockaddr*)&sin, sizeof(sin) ) == -1 )
         {
              cout<<"Can't bind"<<endl;
              return -1;
         }
    
    	cout<<"Wait for connections..."<<endl;
    	int i=0, len = sizeof(newsin);
    	if(listen(s,5) == -1)
    	{
    		cout<<"Cant listen"<<endl;
    	}
    	int c = 0, tmp;
    	while( c < 1 )
    	{
    		if( (news = accept(s, (sockaddr*)&newsin, &len)) == INVALID_SOCKET )
    		{
    			cout<<"Accept failed"<<endl;
    			getch();
    			return -1;
    		}
    		else
    		{
    			cout<<"New client "<<c<<endl;
    			int msg;
    			if(FAILED(msg = recv(news, buff, sizeof(buff),0 )))
    				return E_FAIL;
    			for(int i = 0; i < 1000; i++)
    				if( isalnum(buff[i]) )
    					cout<<buff[i];
    			cout<<endl;
    			//closesocket(news);
    			++c;
    		}
    	}
    
    		tmp = recv(news,buff, sizeof(buff),0 );
    		if( tmp != SOCKET_ERROR )
    			for(int i = 0; i < 1000; i++)
    				if( isalnum(buff[i]) )
    					cout<<buff[i];
    		tmp = recv(news,buff, sizeof(buff),0 );
    		if( tmp != SOCKET_ERROR )
    			for(int i = 0; i < 1000; i++)
    				if( isalnum(buff[i]) )
    					cout<<buff[i];
    
    	closesocket(s);
    	closesocket(news);
    	WSACleanup();
    
    	return 0;
    }
    Код как я сам понимаю - бред...
     
    1 person likes this.
  2. Qws

    Qws Elder - Старейшина

    Joined:
    17 Jun 2008
    Messages:
    46
    Likes Received:
    57
    Reputations:
    5
    Почемуже бред?В некоторих местах криво,хотя в полне прилично))))
    Зы:Я новичок:))))
     
  3. criz

    criz Elder - Старейшина

    Joined:
    4 Nov 2007
    Messages:
    293
    Likes Received:
    40
    Reputations:
    6
    эммм...у меня глюк или ты не перевел интерфейс в promisc-режим?
    http://forum.antichat.ru/showthread.php?p=1011673
    ТС, твой код пример обычного клиент/сервернго приложения...тока без клиента)))
     
    #3 criz, 19 Jan 2009
    Last edited: 19 Jan 2009
  4. WON

    WON New Member

    Joined:
    2 Jul 2008
    Messages:
    17
    Likes Received:
    2
    Reputations:
    0
    Я например захожу в КС... оно должно мне выводить на экран содержимое пакетов при игре а оно мне выводит пустоту напостой..

    это да... за ссылочку спасибо.. но там заумный для меня код... может есть что по проще... может на Delphi... И ещё по той ссылке что ты мне дал упоминался WinAPI и сетевые протоколы низких уровней... Может они проще...
     
    #4 WON, 19 Jan 2009
    Last edited: 19 Jan 2009
  5. SlyBit

    SlyBit Elder - Старейшина

    Joined:
    4 Jul 2008
    Messages:
    49
    Likes Received:
    8
    Reputations:
    0
    WON

    Твой код не предназначен для перехвата пакетов.

    Тут http://www.ntkernel.com/w&p.php?id=14 расписаны методы перехвата пакетов, позволяющие их редактировать.

    Самый простой способ внедрять в каждый процесс библиотеку, перехватывающую функции для работы с сокетами (модификация IAT или сплайзинг connect, send, sendto, WSASend, WSASendTo, recv, recvfrom, WSARecv).
     
  6. Dr Flint

    Dr Flint Member

    Joined:
    29 Dec 2008
    Messages:
    0
    Likes Received:
    22
    Reputations:
    0
    чем тебе пабликовские сниферы не нравятся?)
     
  7. criz

    criz Elder - Старейшина

    Joined:
    4 Nov 2007
    Messages:
    293
    Likes Received:
    40
    Reputations:
    6
    В первом твоем посте С-шный код, я тебе дал ссылку на С-шный код.
    Может тебе надо сначала ознакомиться с документацией по TCP/IP? Потом код не будет казаться "заумным" ;)
     
  8. WON

    WON New Member

    Joined:
    2 Jul 2008
    Messages:
    17
    Likes Received:
    2
    Reputations:
    0
    Чесно говря я не пытался казаться "заумным", просто в той ссылке что ты мне дал говорилось что есть готовые WinAPI функции и что с ними легче рабаотать... Спасибо... буду разбираться с тем кодом что есть...
     
    1 person likes this.
  9. Pernat1y

    Pernat1y Elder - Старейшина

    Joined:
    20 Dec 2007
    Messages:
    479
    Likes Received:
    79
    Reputations:
    7
    глянь сорцы того-же wireshark'a. он на Сях-же, вроде
     
  10. criz

    criz Elder - Старейшина

    Joined:
    4 Nov 2007
    Messages:
    293
    Likes Received:
    40
    Reputations:
    6
    WON, твой код отличается несколькими строчками: нет перевода интерфейса в promisc-режим и другой вывод информации ;)
    З.Ы. ну еще там IP-заголовок описан.
     
  11. xismyname

    xismyname Elder - Старейшина

    Joined:
    7 Sep 2008
    Messages:
    77
    Likes Received:
    7
    Reputations:
    -5
    Мужик тебе функция accept() не нужна для перехвата пакетов, по той ссылке что скинул Criz все понятно показано,вот одна проблема - тот код не работает на некоторых Windows .

    Если ты хочешь принимать только те пакету которые предназначены для твоей машины то переводит сокет в режим promisc тебе незачем.

    Вот код,для перехвата пакетов предназначенных для твоего компа.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <mstcpip.h>
    #include <conio.h>
    
    typedef struct{
    	unsigned int version 	: 4;
    	unsigned int h_len   	: 4;
    	unsigned int tos     	: 8;
    	unsigned int tot_len 	: 16;
    	unsigned int ID      	: 16;
    	unsigned int flags   	: 3;
    	unsigned int f_offset	: 13;
    	unsigned int TTL        : 8;
    	unsigned int protocol   : 8;
    	unsigned int h_checksum : 16;
    	unsigned int srcip      : 32;
    	unsigned int dstip      : 32;
    }IPHEADER;
    
    int main(void)
    {
    	SOCKADDR_IN      addr;
    	WSADATA          wsd;
    	SOCKET           mSocket;
    	HOSTENT          *host;
    	IPHEADER         *ip;
    	unsigned long    mode = 1;
    	int              len;
    	char             pcname[32];
    	char             buf[sizeof(IPHEADER)];
    
    
    	/* load windows socket interface */
    	if(WSAStartup(MAKEWORD(2,2),&wsd) != 0)
    	{
    		puts("Could not load winsocket api");
    		exit(1);
    	}
    
    	/* Get computer name */
    	len = sizeof(pcname) - 1;
    	GetComputerNameA(pcname,&len);
    	len = 0;
    
    	/* Get host IP address by name */
    	host = gethostbyname(pcname);
    
    	/* Set addr & buf to 0 */
    	memset(&addr,0,sizeof(addr));
    	memset(buf,0,sizeof(buf));
    
    	/* init. local address & create raw socket */
    	addr.sin_addr.s_addr    = ((struct in_addr*)host->h_addr_list[0])->s_addr;
            addr.sin_family         = AF_INET;
    	addr.sin_port           = htons(0);
    	mSocket                 = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
    
    	if(mSocket == INVALID_SOCKET)
    	{
    		puts("Could not create a RAW socket");
    		exit(1);
    	}
    
    	/* Bind socket with local address */
    	if(bind(mSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR)) != -1)
    	{
    		/*-----------------------------------------------*/
    		int x = 1;
    		while(!kbhit())
    		{
    			len = recv(mSocket,buf,sizeof(buf),0);
    
    			/* Check received data */
    			if(len >= sizeof(IPHEADER))
    			{
    				ip = (IPHEADER*)buf;
    				printf("\n+--------- %d ------------+\n",x++);
    
    				printf("| DEST    : %s\n",inet_ntoa(*((struct in_addr*)&ip->dstip)));
    				printf("| SRC     : %s\n",inet_ntoa(*((struct in_addr*)&ip->srcip)));
    				printf("| VERSION : %d\n",ip->version);
    
    				printf("+------------------------+\n");
    
    			}
    		}
    	}
    	else
    	{
    		puts("Could not bind");
    	}
    }
     
  12. WON

    WON New Member

    Joined:
    2 Jul 2008
    Messages:
    17
    Likes Received:
    2
    Reputations:
    0
    xismyname а на чём ты компилируешь...? Я на VS 6.0, подключаю
    #pragma comment( lib, "wsock32.lib" ) и у меня выскакиевает 60 error(s), 19 warning(s) непонятного содержания...
     
  13. criz

    criz Elder - Старейшина

    Joined:
    4 Nov 2007
    Messages:
    293
    Likes Received:
    40
    Reputations:
    6
    Пробуй так:
     
  14. Chaak

    Chaak Elder - Старейшина

    Joined:
    1 Jun 2008
    Messages:
    1,059
    Likes Received:
    1,067
    Reputations:
    80
    windows.h подключай после winsock2, а не наоборот
     
  15. xismyname

    xismyname Elder - Старейшина

    Joined:
    7 Sep 2008
    Messages:
    77
    Likes Received:
    7
    Reputations:
    -5

    В Lcc-win32.

    Если выдает ошибку убери файлы mstcpip.h и ws2tcpip.h.
     
    #15 xismyname, 22 Jan 2009
    Last edited: 22 Jan 2009
  16. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,296
    Reputations:
    327
    бери WinPCAP - там целый фреймворк по захвату и фильтрации пакетов, не ошибешься
     
  17. WON

    WON New Member

    Joined:
    2 Jul 2008
    Messages:
    17
    Likes Received:
    2
    Reputations:
    0
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <winsock2.h>
    #include <windows.h>
    #include <conio.h>
    
    #pragma comment(lib, "ws2_32.lib")  
    
    typedef struct{
    	unsigned int version 	: 4;
    	unsigned int h_len   	: 4;
    	unsigned int tos     	: 8;
    	unsigned int tot_len 	: 16;
    	unsigned int ID      	: 16;
    	unsigned int flags   	: 3;
    	unsigned int f_offset	: 13;
    	unsigned int TTL        : 8;
    	unsigned int protocol   : 8;
    	unsigned int h_checksum : 16;
    	unsigned int srcip      : 32;
    	unsigned int dstip      : 32;
    }IPHEADER;
    
    int main(void)
    {
    	SOCKADDR_IN      addr;
    	WSADATA          wsd;
    	SOCKET           mSocket;
    	HOSTENT          *host;
    	IPHEADER         *ip;
    	unsigned long    mode = 1;
    	int              len;
    	char             pcname[32];
    	char             buf[sizeof(IPHEADER)];
    
    
    	/* load windows socket interface */
    	if(WSAStartup(MAKEWORD(2,2),&wsd) != 0)
    	{
    		puts("Could not load winsocket api");
    		exit(1);
    	}
    
    	/* Get computer name */
    	len = sizeof(pcname) - 1;
    	GetComputerNameA(pcname, (unsigned long *)len);
    	len = 0;
    
    	/* Get host IP address by name */
    	host = gethostbyname(pcname);
    
    	/* Set addr & buf to 0 */
    	memset(&addr,0,sizeof(addr));
    	memset(buf,0,sizeof(buf));
    
    	/* init. local address & create raw socket */
    	addr.sin_addr.s_addr    = ((struct in_addr*)host->h_addr_list[0])->s_addr;
            addr.sin_family         = AF_INET;
    	addr.sin_port           = htons(0);
    	mSocket                 = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
    
    	if(mSocket == INVALID_SOCKET)
    	{
    		puts("Could not create a RAW socket");
    		exit(1);
    	}
    
    	/* Bind socket with local address */
    	if(bind(mSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR)) != -1)
    	{
    		/*-----------------------------------------------*/
    		int x = 1;
    		while(!kbhit())
    		{
    			len = recv(mSocket,buf,sizeof(buf),0);
    
    			/* Check received data */
    			if(len >= sizeof(IPHEADER))
    			{
    				ip = (IPHEADER*)buf;
    				printf("\n+--------- %d ------------+\n",x++);
    
    				printf("| DEST    : %s\n",inet_ntoa(*((struct in_addr*)ip->dstip)));
    				printf("| SRC     : %s\n",inet_ntoa(*((struct in_addr*)ip->srcip)));
    				printf("| VERSION : %d\n",ip->version);
    
    				printf("+------------------------+\n");
    
    			}
    		}
    	}
    	else
    	{
    		puts("Could not bind");
    	}
    	return 0;
    }
    Зделал всё как сказали.. клмпилиться но сразу же выскакивает ошибка "Инструкция по адресу ... обратилась к памяти... и не может быть прочитана...

    Ошибка в строке
    Code:
    GetComputerNameA(pcname, (unsigned long *)len);
    Может подскажете как исправить?
     
    #17 WON, 7 Feb 2009
    Last edited: 7 Feb 2009
  18. __mad

    __mad Elder - Старейшина

    Joined:
    4 Nov 2007
    Messages:
    100
    Likes Received:
    38
    Reputations:
    7
    GetComputerNameA(pcname, &len);
     
  19. WON

    WON New Member

    Joined:
    2 Jul 2008
    Messages:
    17
    Likes Received:
    2
    Reputations:
    0
    Code:
    GetComputerNameA(pcname, &len);
    я тоже об этом думал но оно выдаёт ошибку несоответствия типов поэтому я написал так:

    Code:
    GetComputerNameA(pcname, (unsigned long *)&len);
    программа запускаеться, ошибку не выкидывает но и программа ничего не делает.. показывает красивый чёрный прямоугольник...
     
    #19 WON, 7 Feb 2009
    Last edited: 7 Feb 2009