|
Постоянный
Регистрация: 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
|