Показать сообщение отдельно

  #4  
Старый 30.05.2009, 20:24
Gar|k
Постоянный
Регистрация: 20.03.2009
Сообщений: 564
Провел на форуме:
991929

Репутация: 395


По умолчанию

Я думаю для поставленной задачи подойдет и RAW сокет в "promiscuous_mode".

Пример кода на Си
Код:
int main(int argc, char * argv[]) {

    WSADATA wsadata;
    SOCKET sock;
    CHAR szHostName[16];
    HOSTENT * phe;
    SOCKADDR_IN sa;
    DWORD flag = TRUE;

    unsigned char buffer[65555];

    struct in_addr need; // А это необходимо для inet_ntoa макроса

    WSAStartup(MAKEWORD(2, 2), &wsadata);

    sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

    if (sock == INVALID_SOCKET) {
        printf("Error create socket\n");
        return 0;
    }

    if (gethostname(szHostName, sizeof szHostName) != 0) {
        printf("Error get hostname\n");
        return 0;
    }

    phe = gethostbyname(szHostName);
    if (phe == NULL) {
        printf("Error get hostname data\n");
        return 0;
    }

    ZeroMemory( & sa, sizeof sa);
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = ((struct in_addr * ) phe - >h_addr_list[0]) - >s_addr;

    need.s_addr = sa.sin_addr.s_addr;

    if (bind(sock, &sa, sizeof(sa)) != 0) {
        printf("Error set bind socket\n");
        return 0;
    }

    if (ioctlsocket(sock, SIO_RCVALL, &flag) == SOCKET_ERROR) {
        printf("Error activate promiscuous mode\n");
        return 0;
    }

    while (1)

    {
        resbuf = recvfrom(sock, buffer, sizeof buffer, 0, 0, 0);

        // ставим фильтр тока на исходящий траффик
        // можешь убрать или настроить только на входящий
        ip = (struct my_ip * )(buffer);
        if (need.s_addr != ip - >ip_source) {
            continue;
        }

        // анализ принятого буффера
    }

    closesocket(sock);
    WSACleanup;

    return 0;
}
Практически тоже самое на MASM
Код:
.386
.model flat, stdcall
option casemap:none

include C:\masm32\include\windows.inc

include C:\masm32\include\masm32.inc ;много полезных функций masm32
includelib C:\masm32\lib\masm32.lib

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib

include C:\masm32\include\user32.inc ;функции user32.dll
includelib C:\masm32\lib\user32.lib

include C:\masm32\include\ws2_32.inc ;работ с сокетами - winsock
includelib C:\masm32\lib\ws2_32.lib


      
BUFFER_SIZE equ 50000 ;буфер, который будем использовать для загрузки страницы - 50000 байт


SIO_RCVALL equ 98000001h

.data?
sock SOCKET ?
buffer db BUFFER_SIZE dup(?)
hfile DWORD ?
szHostName db 16 dup(?)

.data
WSAStruct WSADATA <> ;структура, которая нужна для инициализации сокета
SocketAddress sockaddr_in <> ;структура, содержащая адрес и порт, куда будем подключаться


fname db "C:\small\test.log",0


flag DWORD TRUE  

;--------------
Caption db "Сообщение",0
SockErr1 db "Ошибка инициализации сокета",0
Gethosterr db "Ошибка получении имени хоста",0
GetHostFail db "Ошибка получения IP-адреса. Проверьте наличие сетевого подключения.",0
BindErr db "Error set bind socket",0
ioErr db "Error activate promiscuous mode",0
;--------------




.code
start:

	invoke WSAStartup,0101h,offset WSAStruct ;инициализируем сокет версии 2.2 (0101h)
	cmp eax,0
	je @F
      		invoke MessageBox,NULL,offset SockErr1,offset Caption,MB_ICONERROR
      		jmp qApp

@@: ; создаем сокет
	invoke socket,AF_INET,SOCK_RAW,IPPROTO_IP 
	cmp eax,INVALID_SOCKET
   	jne @F
      		invoke MessageBox,NULL,offset SockErr1,offset Caption,MB_ICONERROR
      		jmp exitAppQsocks

@@: ; получаем имя хоста
   
	mov sock,eax 
	
	invoke gethostname,offset szHostName,16
	cmp eax,0
	je @F
		invoke MessageBox,NULL,offset Gethosterr,offset Caption,MB_ICONERROR
		jmp closesock

@@: ;получаем IP-адрес хоста
        invoke gethostbyname,offset szHostName 
        cmp eax,0
        jne @F
        	invoke MessageBox,NULL,offset GetHostFail,offset Caption,MB_ICONERROR ;если не удалось - выведем ошибку и выйдем из программы
		jmp closesock

@@:
 
        mov eax,[eax+12] ;эти три строчки - получение ip-адреса из возвращаемой gethostbyname структуры
        mov eax,[eax]
        mov eax,[eax] ;в итоге IP-адрес в виде double будет в регистре eax
 
 	mov SocketAddress.sin_family, AF_INET
        mov SocketAddress.sin_addr,EAX 

@@: ;биндим сокет

	invoke bind,sock,offset SocketAddress, SIZEOF SocketAddress
	cmp eax,0
	je @F
        	invoke MessageBox,NULL,offset BindErr,offset Caption,MB_ICONERROR ;если не удалось - выведем ошибку и выйдем из программы
		jmp closesock

@@: ; переводим в нужный режим

	invoke ioctlsocket, sock, SIO_RCVALL, offset flag
	cmp eax,SOCKET_ERROR
	jne @F
  		invoke MessageBox,NULL,offset ioErr,offset Caption,MB_ICONERROR ;если не удалось - выведем ошибку и выйдем из программы
		jmp closesock

@@:


while_1: ;бесконечный цикел

invoke recvfrom,sock,offset buffer,BUFFER_SIZE,0,0,0




@@:
; тут надо чето делать :)

invoke CreateFile,offset fname,GENERIC_WRITE,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 ;создаем файл, если существует, то перезаписываем его (флаг OPEN_ALWAYS)
cmp eax,-1
jne @F
   invoke MessageBox,NULL,offset ioErr,offset Caption,MB_ICONERROR ;если не удалось - выведем ошибку и выйдем из программы
		jmp closesock

@@:
mov hfile,eax
 invoke WriteFile,hfile,offset buffer,BUFFER_SIZE,0,0 ;запишем данные в файл
 invoke CloseHandle,hfile ;и закроем его

jmp while_1


closesock:
invoke closesocket,sock

exitAppQsocks:
call WSACleanup 

qApp :
invoke ExitProcess,0

end start
За тобой анализ буффера в памяти
лично я для Си версии использовал юниксовую функцию memmem

Код:
#if defined(__cplusplus) && __cplusplus
 extern "C" {
#endif

void *memmem(const void *buf, const void *pattern, size_t buflen, size_t len)
{

#if defined(__TURBOC__) && (__TURBOC__ >= 0x500)

      char *bf = (char *)buf, *pt = (char *)pattern, *p = bf;

      while (len <= (buflen - (p - bf)))
      {
            if (NULL != (p = memchr(p, (int)(*pt), buflen - (p - bf))))
            {
                  if (0 == memcmp(p, pattern, len))
                        return p;
                  else  ++p;
            }
            else  break;
      }
      return NULL;

#else /* Borland/Turbo C/C++ version prior to 4.x */

      size_t i, j;
      char *bf = (char *)buf, *pt = (char *)pattern;

      if (len > buflen)
            return (void *)NULL;

      for (i = 0; i <= (buflen - len); ++i)
      {
            for (j = 0; j < len; ++j)
            {
                  if (pt[j] != bf[i + j])
                        break;
            }
            if (j == len)
                  return (bf + i);
      }
      return NULL;

#endif
}

#if defined(__cplusplus) && __cplusplus
 }
#endif
 
Ответить с цитированием