Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: помогите со sniffer разобраться  (Прочитано 6869 раз)
0 Пользователей и 1 Гость смотрят эту тему.
warlocklex
Гость
« : 14-05-2006 01:43 » 

много чего написано многое читал.почему то не запускаеться выдает ошибку.
Текст юнита такой:


#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#include <conio.h>
#include <stdio.h>
#include <winsock2.h>

//#connet        "ws2_32.lib"
#define MAX_PACKET_SIZE    0x10000
#define SIO_RCVALL         0x98000001
char Buffer[MAX_PACKET_SIZE]; // 64 Kb


typedef struct IPHeader {
  UCHAR   iph_verlen;   
  UCHAR   iph_tos;     
  USHORT  iph_length;   
  USHORT  iph_id;       
  USHORT  iph_offset;   
  UCHAR   iph_ttl;     
  UCHAR   iph_protocol;
  USHORT  iph_xsum;     
  ULONG   iph_src;     
  ULONG   iph_dest;     
} IPHeader;

char src[10];
char dest[10];
char ds[15];
unsigned short lowbyte;
unsigned short hibyte;

void sniff()
{
  WSADATA     wsadata;   
  SOCKET      s;         
  char        name[128]; .
  HOSTENT*    phe;       
  SOCKADDR_IN sa;       
  IN_ADDR sa1;       
  unsigned long        flag = 1; 
 
  WSAStartup(MAKEWORD(2,2), &wsadata);
  s = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
  gethostname(name, sizeof(name));
  phe = gethostbyname( name );
  ZeroMemory( &sa, sizeof(sa) );
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = ((struct in_addr *)phe->h_addr_list[0])->s_addr;
  bind(s, (SOCKADDR *)&sa, sizeof(SOCKADDR));
 
 
  ioctlsocket(s, SIO_RCVALL, &flag);

 
  while( !kbhit() )
  {
    int count;
    count = recv( s, Buffer, sizeof(Buffer), 0 );
   
    if( count >= sizeof(IPHeader) )
    {
      IPHeader* hdr = (IPHeader *)Buffer;
     

strcpy(src,"Iaeao: ");
CharToOem(src,dest);
printf(dest);

printf("From ");
sa1.s_addr = hdr->iph_src;
printf(inet_ntoa(sa1));


printf(" To ");
sa1.s_addr = hdr->iph_dest;
printf(inet_ntoa(sa1));


printf(" Prot: ");
if(hdr->iph_protocol == IPPROTO_TCP) printf("TCP ");
if(hdr->iph_protocol == IPPROTO_UDP) printf("UDP ");


printf("Size: ");
lowbyte = hdr->iph_length>>8;
hibyte = hdr->iph_length<<8;
hibyte = hibyte + lowbyte;
printf("%s",itoa(hibyte,"",10));


printf(" TTL:%s",itoa(hdr->iph_ttl,"",10));
printf("\n");

    }
  }

  closesocket( s );
  WSACleanup();
}
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
sniff();
}
//---------------------------------------------------------------------------
 


ws2_32.lib-эту бибилиотеку кидаю в папку с проектом.
ошибка такая:
Access violation at adress 00455CC5 in module'Project1.exe'.Read adress 000000000
« Последнее редактирование: 10-12-2007 17:30 от Алексей1153++ » Записан
kroum
Интересующийся

ua
Offline Offline

« Ответ #1 : 17-05-2006 10:11 » 

Гкхм.
Решение просто скопировать реализацию консольного приложения не может не радовать.  Отлично

Используемые в теле sniff() функции printf(), и kbhit() (обращение к которой, собственно, и генерит указанную ошибку) не позволят просто так, без изменений и дополнений, юзать ее в Win32 Application.
Записан
warlocklex
Гость
« Ответ #2 : 17-05-2006 10:53 » 

Гкхм.
Решение просто скопировать реализацию консольного приложения не может не радовать.  Отлично

Используемые в теле sniff() функции printf(), и kbhit() (обращение к которой, собственно, и генерит указанную ошибку) не позволят просто так, без изменений и дополнений, юзать ее в Win32 Application.
printf()
я заменил на  winAPi :
Код:
void zapiz(char*  cTextBuffer)
{
char cBuffer[0x400];
HANDLE hFile;DWORD dwBytes;

hFile=CreateFile("sniff.log",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
   {    MessageBox(NULL, "ошибка", "внимание", NULL);    }
 SetFilePointer(hFile,0,0,FILE_END);
 WriteFile(hFile,cTextBuffer,40,&dwBytes,NULL);
 CloseHandle(hFile);
 for(int i=0;i<sizeof(cTextBuffer);i++){cTextBuffer[i]=0;};
 }

буквы сохраняет в ероглифы.

а на что заменить kbhit()Не понялНе понялНе понялНе понялНе понял?
« Последнее редактирование: 10-12-2007 17:31 от Алексей1153++ » Записан
kroum
Интересующийся

ua
Offline Offline

« Ответ #3 : 18-05-2006 14:32 » 

Ага. Ты решил вести запись в лог-файл...  Улыбаюсь

1. Функция zapiz()
Мусор выдает, потомучто ты вызовом
Цитата
  WriteFile(hFile,cTextBuffer,40,&dwBytes,NULL);
всякий раз записываешь в файл 40 байт. Вне зависимости от объема полезной информации. То есть, недостающий до 40 байт кусок заполняется мусором.
Нужно заменить 40 на strlen(cTextBuffer)

Смысл последней строки в этой функции для меня не ясен. Имхо, ее можно смело убирать.

А вообще, можно было использовать стандартную сишную функцию fprintf

2. Функция sniff()
Во-первых, она недозаписывает TTL и перевод на новую строку.
Дело в том, что вторым параметром в вызове функции itoa должен быть указатель на строку, в которой результат будет храниться. То есть вместо "" можно подставить объявленные уже src, dest или ds, поскольку эти переменные в дальнейшем функцией не используются.

Во-вторых, хорошо бы эту функцию сделать членом класса основной формы. Хотя можно этого и не делать.

Функция kbhit() отлавливает нажатие волшебной клавиши "Any key" при работе консольного приложения. Чтобы реализовать то же самое в Win32 GUI приложении, нужно идти по-другому.
Во-первых, убрать этот цикл, чтобы функция формировала только одну строку.
По нажатию кнопки на форме необходимо запустить что-то типа убранного ранее цикла, но чтобы его выполнение можно было остановить, а программа не висла.

Самый быстрый способ - добавить на форму компонент таймер, установить частоту его обновления как больше нравится. В обработчик таймера этого засунуть вызов функции, а нажатием кнопки этот таймер запускать/останавливать.

Второй способ более правильный, на мой взгляд, но более трудоемкий. Связанный с отловом сообщений Windows.
Если интересует именно второй способ - You wellcome!
Записан
warlocklex
Гость
« Ответ #4 : 21-05-2006 16:38 » 

попробывал так
Код:
#include <vcl.h>
#include <winsock2.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#define MAX_PACKET_SIZE    0x10000
#define SIO_RCVALL         0x98000001
TForm1 *Form1;

char Buffer[MAX_PACKET_SIZE]; // 64 Kb

  WSADATA     wsadata;   
  SOCKET      s;         
  char        name[128];
  HOSTENT*    phe;       
  SOCKADDR_IN sa;   
  IN_ADDR sa1;       
  unsigned long        flag = 1; 

typedef struct IPHeader {
  UCHAR   iph_verlen; 
  UCHAR   iph_tos;     
  USHORT  iph_length;
  USHORT  iph_id;   
  USHORT  iph_offset; 
  UCHAR   iph_ttl;     
  UCHAR   iph_protocol;
  USHORT  iph_xsum;   
  ULONG   iph_src;     
  ULONG   iph_dest;     
} IPHeader;

char src[10];
char dest[10];
char ds[15];
unsigned short lowbyte;
unsigned short hibyte;



 void zapiz(char*  cTextBuffer)
{
char cBuffer[0x400];
HANDLE hFile;DWORD dwBytes;

hFile=CreateFile("sniff.log",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
   {    MessageBox(NULL, "íå ñîçäàí ôàéë", "ÂÍÈÌÀÍÈÅ", NULL);    }
 SetFilePointer(hFile,0,0,FILE_END);
 WriteFile(hFile,cTextBuffer,sizeof(cTextBuffer),&dwBytes,NULL);
 CloseHandle(hFile);
 for(int i=0;i<sizeof(cTextBuffer);i++){cTextBuffer[i]=0;};
 }

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
WSAStartup(MAKEWORD(2,2), &wsadata);
  s = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
  gethostname(name, sizeof(name));
  phe = gethostbyname( name );
  ZeroMemory( &sa, sizeof(sa) );
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = ((struct in_addr *)phe->h_addr_list[0])->s_addr;
  bind(s, (SOCKADDR *)&sa, sizeof(SOCKADDR));

  // Âêëþ÷åíèå promiscuous mode.
  ioctlsocket(s, SIO_RCVALL, &flag);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Timer1->Enabled=true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
 int count;
    count = recv( s, Buffer, sizeof(Buffer), 0 );
    // îáðàáîòêà IP-ïàêåòà
    if( count >= sizeof(IPHeader) )
    {
      IPHeader* hdr = (IPHeader *)Buffer;
      //Íà÷èíàåì ðàçáîð ïàêåòà...

strcpy(src,"Ïàêåò: ");
        zapiz("Ïàêåò: ");
CharToOem(src,dest);
        //Memo1->Lines->Add(dest);
// Ïðåîáðàçóåì â ïîíÿòíûé âèä àäðåñ îòïðàâèòåëÿ.
Memo1->Lines->Add("From ");
        zapiz("From ");
sa1.s_addr = hdr->iph_src;
Memo1->Lines->Add(inet_ntoa(sa1));
        zapiz(inet_ntoa(sa1));

// Ïðåîáðàçóåì â ïîíÿòíûé âèä àäðåñ ïîëó÷àòåëÿ.
Memo1->Lines->Add(" To ");
sa1.s_addr = hdr->iph_dest;
Memo1->Lines->Add(inet_ntoa(sa1));
        zapiz(inet_ntoa(sa1));
// Âû÷èñëÿåì ïðîòîêîë. Ïîëíûé ñïèñîê ýòèõ êîíñòàíò
// ñîäåðæèòñÿ â ôàéëå winsock2.h
Memo1->Lines->Add(" Prot: ");
if(hdr->iph_protocol == IPPROTO_TCP) Memo1->Lines->Add("TCP ");
if(hdr->iph_protocol == IPPROTO_UDP) Memo1->Lines->Add("UDP ");

// Âû÷èñëÿåì ðàçìåð. Òàê êàê â ñåòè ïðèíÿò ïðÿìîé ïîðÿäîê
// áàéòîâ, à íå îáðàòíûé, òî ïðèéä¸òñÿ ïîìåíÿòü áàéòû ìåñòàìè.
        Memo1->Lines->Add("Size: ");
        zapiz("Size: ");
lowbyte = hdr->iph_length>>8;
hibyte = hdr->iph_length<<8;
hibyte = hibyte + lowbyte;
Memo1->Lines->Add(itoa(hibyte,"",10));
        zapiz(itoa(hibyte,"",10));


zapiz(itoa(hdr->iph_ttl,"",10));

}
}

void __fastcall TForm1::Button2Click(TObject *Sender)
{
Timer1->Enabled=false;
}

жутко тормозит. а когда нет пакетов то вообще виснит.

помогите,что делать?
Записан
kroum
Интересующийся

ua
Offline Offline

« Ответ #5 : 26-05-2006 07:02 » 

Еще раз обращаю внимание на строку

WriteFile(hFile,cTextBuffer,sizeof(cTextBuffer),&dwBytes,NULL);

Нужно использовать strlen, не sizeof. Последняя будет возвращать не длину строки, а размер указателя, то есть 4.

По поводу тормозов.
Скорее всего, ты поставил слишком малое время на обработку. Функция не успевает отработать, а таймер пробует ее запустить снова. Поставь внутри "ловушку", например, объяви булевую переменную (глобальную), в начале выполнения функции обработки таймера проверяй ее значение (например, если true-можно запускать sniffer), в начале sniffer присваивай ей false, а последним оператором sniffer-а будет присвоение ей true.

Зависание...
Не было времени искать... Нужно проверить инициализированный SOCKET s
При отсутствии сети программа виснет на операторе

count = recv( s, Buffer, sizeof(Buffer), 0 );

Как проверять этот s и на что проверять - не подскажу. Потому как не знаю.
Записан
warlocklex
Гость
« Ответ #6 : 26-05-2006 13:27 » 

Еще раз обращаю внимание на строку


пасибо буду искать
Записан
kroum
Интересующийся

ua
Offline Offline

« Ответ #7 : 26-05-2006 13:36 » 

Пожалст  Улыбаюсь
Внимательнее мой первый ответ прочтите, молодой человек. Там еще itoa упоминалось. 
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines