您好,欢迎来到[编程问答]网站首页   源码下载   电子书籍   软件下载   专题
当前位置:首页 >> 编程问答 >> Delphi >> 网络抓包程序疑惑,不能抓到发送的数据包

网络抓包程序疑惑,不能抓到发送的数据包

来源:网络整理     时间:2016/8/31 8:56:52     关键词:

关于网友提出的“ 网络抓包程序疑惑,不能抓到发送的数据包”问题疑问,本网通过在网上对“ 网络抓包程序疑惑,不能抓到发送的数据包”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:

问题: 网络抓包程序疑惑,不能抓到发送的数据包
描述:

IOC_IN               =$80000000;
   IOC_VENDOR           =$18000000;
   IOC_out              =$40000000;
   SIO_RCVALL           =IOC_IN or IOC_VENDOR or 1;// or IOC_out(or IOC_OUT要出错)
.....
WSAIoctl(Fsocket[i], 
         SIO_RCVALL,
         @dwBufferInLen, 
         sizeof(dwBufferInLen),
         @dwBufferLen, 
         sizeof(dwBufferLen),
         @dwBytesReturned ,
         nil ,
         nil);
当有数据到达的时候,会得到消息,发送的时候是得不到消息的(以及被发送的数据)
怎么弄才能得到?
除HOOK API方式。


解决方案1:

jf&study

解决方案2:

学习一下

解决方案3:

我试了一下keiy的程序,还不错:)
Delphi版本,GetProtocolTxt函数没有翻译完整:)
program Test;
{$APPTYPE CONSOLE}
uses
  SysUtils, WinSock, Windows;
type
  PTCP = ^_TCP;
  _TCP = packed record
    SrcPort: Word; // 源端口
    DstPort: Word; // 目的端口
    SeqNum: DWord; // 顺序号
    AckNum: DWord; // 确认号
    DataOff: Byte; // TCP头长
    Flags: Byte;   // 标志(URG、ACK等)
    Window: Word;  // 窗口大小
    Chksum: Word;  // 校验和
    UrgPtr: Word;  // 紧急指针
  end;
  PIP = ^_IP;
  _IP = record
    U1: record
    case Byte of
      0: (Version: Byte); // 版本
      1: (HdrLen: Byte);  // IHL
    end;
    ServiceType: Byte;    // 服务类型
    TotalLen: Word;       // 总长
    ID: Word;             // 标识
    U2: record
    case Byte of
      0: (Flags: Word);   // 标志
      1: (FragOff: Word); // 分段偏移
    end;
    TimeToLive: Byte;     // 生命期
    Protocol: Byte;       // 协议
    HdrChksum: Word;      // 头校验和
    SrcAddr: DWord;       // 源地址
    DstAddr: DWord;       // 目的地址
    Options: Byte;        // 选项
  end;
const
  IP_HDRINCL = 2;
  IOC_VENDOR = $18000000;
  BUFFER_SIZE = 4096;
function MAKEWORD(a, b: Byte): Word;
begin
  result:=Word(a or ((Word(b) shl 8)));
end;
function SIO_RCVALL: Cardinal;
begin
  result:=IOC_IN or IOC_VENDOR or 1;
end;
function isprint(c: Byte): Boolean;
begin
  result:=(c>$20) and (c<$7e);
end;
function GetProtocolTxt(p: Byte): string;
begin
  case p of
    IPPROTO_IP: result:='IPPROTO_IP';
    //省略了很多:)
    else
      result:='UNKNOW';
  end;
end;
var
  wsData: WSAData;
  sock: Integer;
  flag: Integer = 1;
  localname: array[0..100] of char;
  phost: PHostEnt;
  addr_in: TSockAddrIn;
  dwValue: Integer;
  RecvBuf: array[0..BUFFER_SIZE-1] of byte;
  ret: Integer;
  ip: PIP;
  tcp: PTCP;
  i, j: Integer;
  c: byte;
  s: string;
begin
  WSAStartup(MAKEWORD(2, 2), wsData);
  // 创建原始套接字
sock:=socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  // 设置IP头操作选项,其中flag 设置为ture,亲自对IP头进行处理
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, pchar(@flag), sizeof(flag));
  // 获取本机名
gethostname(@localname, sizeof(localname));
  // 获取本地 IP 地址
phost:=gethostbyname(@localname);
  // 填充SOCKADDR_IN结构
addr_in.sin_addr:=PInAddr(phost.h_addr_list^)^; //IP
addr_in.sin_family:=AF_INET;
addr_in.sin_port:=htons(57274);
  // 把原始套接字sock 绑定到本地网卡地址上
bind(sock, addr_in, sizeof(addr_in));
  // dwValue为输入输出参数,为1时执行,0时取消
dwValue:=1;
  // 设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包。其中SIO_RCVALL
// 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
ioctlsocket(sock, SIO_RCVALL, dwValue);
  // 前面的工作基本上都是对原始套接字进行设置,在将原始套接字设置完毕,使其能按预期目的工作时,
  // 就可以通过recv()函数从网卡接收数据了,接收到的原始数据包存放在缓存RecvBuf[]中,缓冲区长度BUFFER_SIZE定义为65535。
  // 然后就可以根据前面对IP数据段头、TCP数据段头的结构描述而对捕获的数据包进行分析:
  while true do
  begin
    // 接收原始数据包信息
FillMemory(@RecvBuf, BUFFER_SIZE, 0);
    ret:=recv(sock, RecvBuf, BUFFER_SIZE, 0);
    if ret>0 then
    begin
      ip:=@RecvBuf;
tcp:=PTCP(PChar(@RecvBuf)+ip^.U1.HdrLen);
      WriteLn('协议:', GetProtocolTxt(ip^.Protocol));
      WriteLn('IP源地址:', inet_ntoa(PInAddr(@ip^.SrcAddr)^));
      WriteLn('IP目标地址: ', inet_ntoa(PInAddr(@ip^.DstAddr)^));
      WriteLn('TCP源端口号:', tcp^.SrcPort);
      WriteLn('TCP目标端口号:', tcp^.DstPort);
      WriteLn('数据包长度:', ntohs(ip^.TotalLen));
      WriteLn('长度:', ip^.U1.HdrLen, ' ', tcp^.DataOff, ' ', sizeof(_ip), ' ', sizeof(_tcp));
      WriteLn;
      Write('0000:');
      for i:=0 to ntohs(ip^.TotalLen)-1 do
      begin
        s:=Format('%02x ', [RecvBuf[i]]);
        Write(s);
        if (i+1) mod 16 = 0 then
        begin
          Write(' ');
          for j:=0 to 15 do
          begin
            c:=RecvBuf[i-(15-j)];
            if isprint(c) or (c>$a0) then
              Write(char(c))
            else
              Write('.');
          end;
          WriteLn;
          Write(Format('%04x:', [i+1]));
        end;
      end;
      i:=ntohs(ip^.TotalLen) mod 16;
      if i<>0 then
      begin
        for j:=0 to 15-i do
          Write('   ');
        Write(' ');
        for j:=0 to i-1 do
        begin
          c:=RecvBuf[ntohs(ip^.TotalLen)-i+j];
          if isprint(c) or (c>$a0) then
            Write(char(c))
          else
            Write('.');
        end;
      end;
      WriteLn;
      WriteLn('------------------------------------------');
    end;
  end;
  readln;
end.

解决方案4:

我用过VC的,你要吗?
VC console的
#include 
#include 
#include 
#include 
#ifdef _MSC_VER
#pragma comment( lib, "WS2_32.LIB")
#endif
typedef struct _TCP {
   WORD SrcPort; // 源端口
   WORD DstPort; // 目的端口
   DWORD SeqNum; // 顺序号
   DWORD AckNum; // 确认号
   BYTE DataOff; // TCP头长
   BYTE Flags; // 标志(URG、ACK等)
   WORD Window; // 窗口大小
   WORD Chksum; // 校验和
   WORD UrgPtr; // 紧急指针
 } TCP;
typedef TCP *LPTCP;
typedef TCP UNALIGNED * ULPTCP;
typedef struct _IP {
   union {
      BYTE Version; // 版本
      BYTE HdrLen; // IHL
        };
   BYTE ServiceType; // 服务类型
   WORD TotalLen; // 总长
   WORD ID; // 标识
   union{ WORD Flags; // 标志
      WORD FragOff; // 分段偏移
       };
   BYTE TimeToLive; // 生命期
   BYTE Protocol; // 协议
   WORD HdrChksum; // 头校验和
   DWORD SrcAddr; // 源地址
   DWORD DstAddr; // 目的地址
   BYTE Options; // 选项
  } IP;
typedef IP * LPIP;
char *GetProtocolTxt(BYTE p)
{
switch (p)
  {
  case IPPROTO_IP:
     return  "IPPROTO_IP:";
  case IPPROTO_ICMP:
     return  "IPPROTO_ICMP:";
  case IPPROTO_IGMP:
     return  "IPPROTO_IGMP:";
  case IPPROTO_GGP:
     return  "IPPROTO_GGP:";
  case IPPROTO_TCP:
     return  "IPPROTO_TCP:";
  case IPPROTO_PUP:
     return  "IPPROTO_PUP:";
  case IPPROTO_UDP:
     return  "IPPROTO_UDP:";
  case IPPROTO_IDP:
     return  "IPPROTO_IDP:";
// case IPPROTO_IPV6:
 //    return  "IPPROTO_IPV6:";
  case IPPROTO_ND:
     return  "IPPROTO_ND:";
//  case IPPROTO_ICLFXBM:
//     return  "IPPROTO_ICLFXBM:";
  case IPPROTO_RAW:
     return  "IPPROTO_RAW:";
  case IPPROTO_MAX:
     return  "IPPROTO_MAX:";
  case IPPORT_ECHO:
     return  "IPPORT_ECHO:";
  case IPPORT_DISCARD:
     return  "IPPORT_DISCARD:";
  case IPPORT_SYSTAT:
     return  "IPPORT_SYSTAT:";
  case IPPORT_DAYTIME:
     return  "IPPORT_DAYTIME:";
  case IPPORT_NETSTAT:
     return  "IPPORT_NETSTAT:";
  case IPPORT_FTP:
     return  "IPPORT_FTP:";
  case IPPORT_TELNET:
     return  "IPPORT_TELNET:";
  case IPPORT_SMTP:
     return  "IPPORT_SMTP:";
  case IPPORT_TIMESERVER:
     return  "IPPORT_TIMESERVER:";
  case IPPORT_NAMESERVER:
     return  "IPPORT_NAMESERVER:";
  case IPPORT_WHOIS:
     return  "IPPORT_WHOIS:";
  case IPPORT_MTP:
     return  "IPPORT_MTP:";
  case IPPORT_TFTP:
     return  "IPPORT_TFTP:";
  case IPPORT_FINGER:
     return  "IPPORT_FINGER:";
  case IPPORT_TTYLINK:
     return  "IPPORT_TTYLINK:";
  case IPPORT_SUPDUP:
     return  "IPPORT_SUPDUP:";
  case IPPORT_EXECSERVER:
     return  "IPPORT_EXECSERVER:";
  case IPPORT_LOGINSERVER:
     return  "IPPORT_LOGINSERVER:";
  case IPPORT_CMDSERVER:
     return  "IPPORT_CMDSERVER:";
  case IPPORT_EFSSERVER:
     return  "IPPORT_EFSSERVER:";
  case IPPORT_RESERVED:
     return  "IPPORT_RESERVED:";
  case IMPLINK_IP:
     return  "IMPLINK_IP:";
  case IMPLINK_LOWEXPER:
     return  "IMPLINK_LOWEXPER:";
  default:
     return "UNNOW";
  }
}
#define TRACE printf
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
void main()
{
  // 检查 Winsock 版本号,WSAData为WSADATA结构对象
  WSADATA wsaData;
  SOCKET  sock ;
  int flag=true;
  char LocalName[100];
  hostent *pHost;
  SOCKADDR_IN addr_in;
  char RecvBuf[4096];
  #define BUFFER_SIZE 4096
  IP ip;
  TCP tcp;
  WSAStartup(MAKEWORD(2, 2),&wsaData);
  // 创建原始套接字
  sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  // 设置IP头操作选项,其中flag 设置为ture,亲自对IP头进行处理
  setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag));
  // 获取本机名
  gethostname((char*)LocalName, sizeof(LocalName)-1);
  // 获取本地 IP 地址
  pHost = gethostbyname((char*)LocalName);
  // 填充SOCKADDR_IN结构
  addr_in.sin_addr = *(in_addr *)pHost->h_addr_list[0]; //IP
  addr_in.sin_family = AF_INET;
  addr_in.sin_port = htons(57274);
  // 把原始套接字sock 绑定到本地网卡地址上
  bind(sock, (PSOCKADDR)&addr_in, sizeof(addr_in));
  // dwValue为输入输出参数,为1时执行,0时取消
  DWORD dwValue = 1;
  // 设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包。其中SIO_RCVALL
  // 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
  ioctlsocket(sock, SIO_RCVALL, &dwValue);
  // 前面的工作基本上都是对原始套接字进行设置,在将原始套接字设置完毕,使其能按预期目的工作时,就可以通过recv()函数从网卡接收数据了,接收到的原始数据包存放在缓存RecvBuf[]中,缓冲区长度BUFFER_SIZE定义为65535。然后就可以根据前面对IP数据段头、TCP数据段头的结构描述而对捕获的数据包进行分析:
  int i,j;
  unsigned char c;
  while (true)
  {
  // 接收原始数据包信息
    memset( RecvBuf,0x0,BUFFER_SIZE);
    int ret = recv(sock, RecvBuf, BUFFER_SIZE, 0);
    if (ret > 0)
    {
        // 对数据包进行分析,并输出分析结果
        ip = *(IP*)RecvBuf;
        tcp = *(TCP*)(RecvBuf + ip.HdrLen);
     //   if (ip.DstAddr!=0xffffffffu)
     //   if (ip.DstAddr!=0x7000A8C0u)
//        if ((ip.SrcAddr ==0x7700A8C0u) ||(ip.DstAddr ==0x7700A8C0u) )
        {
          TRACE("协议: %s\n",GetProtocolTxt(ip.Protocol));
          TRACE("IP源地址: %s\n",inet_ntoa(*(in_addr*)&ip.SrcAddr));
          TRACE("IP目标地址: %s\n",inet_ntoa(*(in_addr*)&ip.DstAddr));
          TRACE("TCP源端口号: %d\n",tcp.SrcPort);
          TRACE("TCP目标端口号:%d\n",tcp.DstPort);
          TRACE("数据包长度: %d\n",ntohs(ip.TotalLen));
          TRACE("长度:%x %x %x %x\n",ip.HdrLen,tcp.DataOff,sizeof(ip),sizeof(tcp));
          TRACE("长度:%d %d %d %d\n\n",ip.HdrLen,tcp.DataOff,sizeof(ip),sizeof(tcp));
          printf("0000:");
          for(i=0;i<>
          {
            printf("%02x ", (unsigned char )RecvBuf[i]);
            if ((i+1)%16==0)
             {
                putchar(' ');
                for(j=0;j<16;j++)
                {
                    c=  RecvBuf[i-(15-j)];
                    if ((isprint(c)) || (c>0xa0))
                       putchar(c);
                       else
                       putchar('.');
                }
                printf("\n%04x:",i+1);
             }
          }
       if (((i=ntohs(ip.TotalLen)%16))!=0)
        {
           for(j=0;j<16-i;j++)
                printf("   ");
           putchar(' ');     
           for(j=0;j<>
                {
                    c=  RecvBuf[ntohs(ip.TotalLen)-i+j];
                    if ((isprint(c)) || (c>0xa0))
                       putchar(c);
                       else
                       putchar('.');
                }
         }
          printf("\n");
      }
    }
  }
  getchar();
}

解决方案5:

不说了,接分......

解决方案6:

关注


以上介绍了“ 网络抓包程序疑惑,不能抓到发送的数据包”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/3677567.html

相关图片

相关文章