如何抓取网卡来的数据包 ( 积分: 200 )

  • 主题发起人 主题发起人 不爱学习
  • 开始时间 开始时间

不爱学习

Unregistered / Unconfirmed
GUEST, unregistred user!
问题是这样的:
一端是用Vc写的程序,另一端用delphi,两端用双绞线、网卡连接。vc那端不定时的发
送数据包,包格式已知,delphi这边的程序如何捕获数据包的内容,解包分行放入文本
中。而且,delphi的程序也要对另一端发数据包。看了delphi中的demo/chat,也研究了一下socket,还是不太明白数据如何传输,请各位大虾指点一二:)
 
截网卡跟Delphi的chat差远了。
一般都是hook winsock
 
能详细点吗,最好有示例[:)]
 
socket.sendtext();[?]
 
没有人知道吗,d7里没有Tclientsocket和Tserversocket吗?
 
首先我不知道你的这个程序为什么这么做,原因就不用问了。我这里提一个就是使用hook,直接勾住socket,或者用winpcap,这个有现成的控件。当然,winpcap只能获取数据包,而不能对数据包进行丢包之类的处理的哈。对数据包进行控制,那是上升到防火墙的高度了,如果实在不行,那就用防火墙的思想,写驱动吧。
 
我很严重的告诉你d7中有Tclientsocket和Tserversocket,但默认安装是没有的。
 
有Tclientsocket和Tserversocket的,自己找到對應的bpl,裝上就是了
 
强烈建议用wincap
 
看了一下winpcap,似乎只方便抓包,我还要发包。由于传过来的肯定是个完整的包,不需要对包进行校验,而且另一端用的socket,所以还是决定用原始套接字,继续学习,继续等待高手答复
 
Hook API就是了,我有现成的控件,商用的话就联系我吧。kryso@21cn.com
 
解决问题了,欢迎继续讨论,进来就给分
 
我的源码(分析数据包部分):
procedure TForm1.ReadPacket(Data: pointer; recvbytes: Word);
type TBaseProtoHdrs=packed record
Ether_Hdr:THdrEthernet;
IP_Hdr :THdrIP;
Data: array[0..0]of Byte ;
end;
PBaseProtoHdrs= ^TBaseProtoHdrs;

type TUDPPack=packed record
UDP_Hdr :THdrUDP;
Data:array[0..0]of Byte;
end;
PUDPPack=^TUDPPack;

type TTCPPack=packed record
TCP_Hdr :THdrTCP;
Data:array[0..0]of Byte;
end;
PTCPPack=^TTCPPack;
//ICMP
{
类型代码 类型描述
0 响应应答(ECHO-REPLY)
3 不可到达
4 源抑制
5 重定向
8 响应请求(ECHO-REQUEST)
11 超时
12 参数失灵
13 时间戳请求
14 时间戳应答
15 信息请求(*已作废)
16 信息应答(*已作废)
17 地址掩码请求
18 地址掩码应答
其中代码为15、16的信息报文已经作废。
}

type TsICMP= packed record
case Integer of
0: (uc1,uc2,uc3,uc4 : CHAR );
1: (us1,us2 : Word );
2: (sUL : LongWord );
end;

type ICMP_hdr=packed record
ICMPType,
ICMPCode : Byte;
ICMPChecksum : Word;
sICMP : TsICMP;
ICMP_Originate_Timestamp,
ICMP_Receive_Timestamp,
ICMP_Transmit_Timestamp : LongWord;
end;
PICMP_hdr=^ICMP_hdr;

TICMPPack=packed record
ICMPHdr:ICMP_hdr;
Data:array[0..0]of Byte;
end;
PICMPPack=^TICMPPack;

//IGMP
type IGMP_Hdr = record
IGMP_Type : Byte; //协议的信息类型
IGMP_Code : Byte; //routing code
IGMP_CheckSum : Word; //校验和
Group : ULONG;
end;

TIGMPPack=packed record
IGMPHdr: IGMP_Hdr;
Data: array[0..0]of Byte;
end;
PIGMPPack=^TIGMPPack;

var
Base:PBaseProtoHdrs;
DataLen:Word;
List:TStringList;
str:string;
ListItem:TListItem;

PUDP: PUDPPack;

TCPHeader:THdrTCP;
PTCPData:Pointer;
UDPHeader:THdrUDP;
PUDPData:Pointer;
IcmpHeader:ICMP_hdr;
PIcmpData:Pointer;
IGMPHeader:IGMP_Hdr;
PIGMPData:Pointer;
begin
Base:=PBaseProtoHdrs(data);

List:=TStringList.Create;
SetLength(str,SizeOf(THdrEthernet));
System.Move(Base^,str[1],SizeOf(THdrEthernet));
List.Append('以太网头部: '+str);

str:='';
SetLength(str,SizeOf(THdrIP));
System.Move(Base^.IP_Hdr,str[1],SizeOf(THdrIP));
List.Append('IP头部: '+str);

//lv1.Items.BeginUpdate;
if NTop50.Checked then //只显示最新30行选中。
begin
while (lv1.Items.Count>=30) do
begin
if lv1.Items[0].Data<> nil then
begin
TStringList(lv1.Items[0].Data).Free;
lv1.Items[0].Data:=nil;
end;
lv1.Items.Delete(0);
end;
end
else if NTop50.Checked then //只显示最新50行选中。
begin
while (lv1.Items.Count>=50) do
begin
if lv1.Items[0].Data<> nil then
begin
TStringList(lv1.Items[0].Data).Free;
lv1.Items[0].Data:=nil;
end;
lv1.Items.Delete(0);
end;
end
else if NTop100.Checked then
begin
while (lv1.Items.Count>=100) do //只显示最新100行选中。
begin
if lv1.Items[0].Data<> nil then
begin
TStringList(lv1.Items[0].Data).Free;
lv1.Items[0].Data:=nil;
end;
lv1.Items.Delete(0);
end;
end else if mniNAll.Checked then
begin
//
end;
//lv1.Items.EndUpdate;

ListItem:=Lv1.items.add;
with ListItem do
begin
Caption:=ProtocolStr(Base^.IP_Hdr.protocol);
SubItems.Add(IPtoStr(Base^.IP_Hdr.saddr));
Subitems.add('');
SubItems.Add(IPtoStr(Base^.IP_Hdr.daddr));
Subitems.add('');
end;

case Base^.IP_Hdr.protocol of
1: //ICMP
begin
IcmpHeader:=PICMPPack(@Base.Data)^.ICMPHdr;
if @IcmpHeader<>nil then
begin
str:='';
SetLength(str,SizeOf(ICMP_Hdr));
System.Move(IcmpHeader,str[1],SizeOf(ICMP_Hdr));
List.Append('ICMP头部:'+str);

PIcmpData:=@PICMPPack(@Base.Data)^.Data;
if PIcmpData<>nil then
begin
DataLen:=recvbytes-sizeof(THdrEthernet)-sizeof(THdrIP)-sizeof(ICMP_Hdr);

SetLength(str,DataLen);
System.Move(PIcmpData^,str[1],DataLen);
List.Append('ICMP正文内容:'+str);
end;
end;
ListItem.Data:=Pointer(List);
end;
2 : //IGMP
begin
IGMPHeader:=PIGMPPack(@Base.Data)^.IGMPHdr;
if @IGMPHeader<>nil then
begin
str:='';
SetLength(str,SizeOf(IGMP_Hdr));
System.Move(IGMPHeader,str[1],SizeOf(IGMP_Hdr));
List.Append('IGMP头部:'+str);

PIGMPData:=@PIGMPPack(@Base.Data)^.Data;
if PIGMPData<>nil then
begin
DataLen:=recvbytes-sizeof(THdrEthernet)-sizeof(THdrIP)-sizeof(IGMP_Hdr);

SetLength(str,DataLen);
System.Move(PIGMPData^,str[1],DataLen);
List.Append('ICMP正文内容:'+str);
end;
end;
ListItem.Data:=Pointer(List);
end;
6: //TCP
begin
TCPHeader:=PTCPPack(@Base.Data)^.TCP_Hdr;
if @TCPHeader<>nil then
begin
str:='';
SetLength(str,SizeOf(THdrTCP));
System.Move(TCPHeader,str[1],SizeOf(THdrTCP));
List.Append('TCP头部:'+str);

PTCPData:=@PTCPPack(@Base.Data)^.Data;
DataLen:=recvbytes-sizeof(THdrEthernet)-sizeof(THdrIP)-sizeof(THdrTCP);
SetLength(str,DataLen);
if (PTCPData<>nil) then
begin
System.Move(PTCPData^,str[1],DataLen);
List.Append('TCP正文内容:'+str);
end
else
List.Append('TCP正文内容:空 ');

ListItem.SubItems.Strings[1]:=inttostr( ntohs(TCPHeader.source));
ListItem.SubItems.Strings[3]:=inttostr( ntohs(TCPHeader.dest));
end;

ListItem.Data:=Pointer(List);
end;
14: ; //telnet
17: //UDP
begin

UDPHeader:=PUDPPack(@Base.Data)^.UDP_Hdr;
if @UDPHeader<>nil then
begin
str:='';
SetLength(str,SizeOf(THdrUDP));
System.Move(UDPHeader,str[1],SizeOf(THdrUDP));
List.Append('UDP头部:'+str);


PUDPData:=@PUDPPack(@Base.Data)^.Data;
DataLen:=recvbytes-sizeof(THdrEthernet)-sizeof(THdrIP)-sizeof(THdrUDP);
SetLength(str,DataLen);
if PUDPData<>nil then
begin
System.Move(PUDPData^,str[1],DataLen);
List.Append('UDP正文内容:'+str);
end else
List.Append('UDP正文内容:空');

ListItem.SubItems.Strings[1]:=inttostr( ntohs(UDPHeader.src_port));
ListItem.SubItems.Strings[3]:=inttostr( ntohs(UDPHeader.dst_port));
end;

ListItem.Data:=Pointer(List);
end;
else
begin
//
end;


//List.Free;
end;

end;
 
{
********************************************************************************
--------------------------------------------------------------------------------
TZNIFFER

for Packet Capture Driver by Politecnico di Torino

Written by Lars Peter Christiansen
--------------------------------------------------------------------------------
TERMS AND CONDITIONS OF USE.
All of this software is Copyright(C) 2002 Lars Peter Christiansen.

The author of this software assumes no liability for damages caused under
any circumstances whatsoever, and is under no obligation. Use of the software
indicates acceptance of all conditions contained in this document. If you do
not agree to these terms, you must delete this software immediately.

You may distribute the archive in which this software is distributed, but
under no circumstances must this archive be changed. Distributing a modified
archive is a violation of the software license.

If you do redistribute this software, please let me know at the email address
given below.

If you have any questions, requests, bug reports, etc., please contact me at
the address given below.

Lars Peter Christiansen
Email : lp@nzlab.dk
Website: http://www.nzlab.dk

--------------------------------------------------------------------------------

[ user application ]
[ TZniffer ] <- you are here!
[ PCAP ]
[ Netadapter ]


********************************************************************************
}
unit Zniffer;

interface
uses Windows,
Classes,
Sysutils,
Pcap,
Packet32;
Type

PETHERNET_HDR = ^ETHERNET_HDR;
ETHERNET_HDR = packed record
Destination: array[0..5] of UCHAR;
Source: array[0..5] of UCHAR;
Protocol: array[0..1] of UCHAR;
Data: array[0..0] of UCHAR;
end;

PIP_RHDR = ^IP_RHDR;
IP_RHDR = packed record
Verlen: UCHAR; //4bit version 4bit length (bytes/8)
Service: UCHAR; // TOS
Length: WORD;
Ident: WORD;
Flagoff: array[0..1] of UCHAR; //3bit flag - 13 bit offset
TimeLive: UCHAR;
Protocol: UCHAR;
Checksum: WORD;
SrcIP: array[0..3] of UCHAR;
DestIP: array[0..3] of UCHAR;
Data: array[0..0] of UCHAR;
end;

// Added ( Lars Peter Christiansen 13-04-2001)
PTCP_RHDR = ^TCP_RHDR;
TCP_RHDR = Packed record
SrcPort : WORD;
DestPort : WORD;
SequenceNr : array[0..3] of UCHAR;
AckNumber : array[0..3] of UCHAR;
LenResvFlags: array[0..1] of UCHAR; //length(4bits) rsvd(6bits) flags(6bits)
WindowSize : array[0..1] of UCHAR;
Checksum : array[0..1] of UCHAR;
UrgentPtr : array[0..1] of UCHAR;
Data : array[0..0] of UCHAR;
end;

Tzniffer = class;

// Thread that listens to selected Netadapter
TZnifferThread = Class(Tthread)
private
Z : Tzniffer;
public
ReadTimes : integer;
Constructor Create(Zniffer:Tzniffer);
Destructor Destroy;override;
Procedure Execute;override;
end;

// The main TZniffer Class here
TZniffer = Class
private
FPCAP : PPCAP; // Handle to the pcapdriver
Fadapters :TstringList; // the adapters found on the system
FadapterIndex:Integer; // current adapter
FThread : TZnifferThread; // The listening thread
Fsnooping : Boolean; // Flag indicating snooping activity
Function GetAdapters(Var ErrStr:string) : boolean;
procedure ThreadTerminate(Sender:tobject);
procedure SetAdapterIndex(const Value: integer);
public
OnPacket : Procedure(Data:pointer;recvbytes:Word) of Object;
Constructor Create;
Destructor Destroy;override;
Function Activate(var ErrStr:string) : boolean;
Function Deactivate(var ErrStr:string):boolean;
property Snooping : boolean Read Fsnooping;
property Adapters : TstringList read Fadapters;
property AdapterIndex:integer read FadapterIndex write SetAdapterIndex;
end;

Const //Look in rfc1340 dokument
PROTO_IP = $0800;

function TOUSHORT(x: PChar): SHORT; // Ripped C Makro
implementation

function TOUSHORT(x: PChar): SHORT;
begin Result := (SHORT(x^) shl 8) or (SHORT((x + 1)^)); // FP May 10, 1999
end;


{ TZniffer }
constructor TZniffer.Create;
var S:string;
begin
FAdapters := Tstringlist.Create;
FadapterIndex := 0;
FPCAP := Nil;
Fsnooping:=false;
GetAdapters(s);
end;

destructor TZniffer.Destroy;
Var E:string;
begin

DeActivate(E);
Fadapters.free;
Fadapters := nil;

inherited;

end;



//------------------------------------------------------------------------------
// ACTIVATE SNOOP AND START READTHREAD
//------------------------------------------------------------------------------
function TZniffer.Activate(var ErrStr: string): boolean;
begin
Result := false;

// Check if Snooping is active
if Fsnooping or (FPCAP<>nil) then
begin
ErrStr := 'Snooping already activated';
exit;
end;

// Open Driver and NetAdapter
FPCAP := Pcap.pcap_open_live(Pchar(FAdapters[FAdapterindex]),
DEFAULT_SNAPLEN,TRUE,100,ErrStr);
if FPCAP = nil then exit;

if not Assigned(OnPacket) then
begin
ErrStr:='No Packet Read Callback function assigned';
exit;
end;

// Start Snoop Read Thread
FThread := TZnifferThread.create(self);
Fthread.ReadTimes := 10;
Fthread.OnTerminate := ThreadTerminate;
Fthread.FreeOnTerminate := false;
Fthread.resume;
FSnooping := True;

result:=true;
end;


function TZniffer.Deactivate(var ErrStr: string): boolean;
var
P:Tpacket;
T:longword;
begin
result := false;
if (not Fsnooping) then begin errstr:='Snooping not active';exit;end;
if FThread=nil then begin errstr:='No thread to stop';exit;end;

// Stop Snooping Thread
FThread.Terminate;
FThread.WaitFor;
FThread.Free;
Fthread := nil;

// Release Driver Handle
Pcap_Close(FPCAP);

result :=true;
end;


//------------------------------------------------------------------------------
// GET ADAPTERS IN SYSTEM
//------------------------------------------------------------------------------
function TZniffer.GetAdapters(var ErrStr:string): boolean;
begin
result:=false;

if FAdapters=nil then
begin
ErrStr :='Memory for Adapterlist not allocated';
exit;
end;

Fadapters.commatext := Pcap.pcap_GetAdapternames(',',ErrStr);
if Fadapters.CommaText='' then exit;

result := true;
end;

//------------------------------------------------------------------------------

//
// And Snoop Driver Callback function which cannot be procedure of object!
//------------------------------------------------------------------------------

procedure CaptureCB(User:pointer;const Header:Ppcap_pkthdr;const Data:pchar);
begin
TZniffer(user).OnPacket(Data,Header.len);
end;

//======================================================
{ TZnifferThread }
constructor TZnifferThread.Create(Zniffer:Tzniffer);
begin
ReadTimes:=0;
Z:=Zniffer;
PacketSetReadTimeout(z.Fpcap.Adapter,100);
inherited Create(TRUE);
end;

destructor TZnifferThread.Destroy;
begin
inherited;

end;

procedure TZnifferThread.Execute;
begin
if Z=nil then exit;

While Not Terminated do
begin
Pcap_Read(Z.FPCAP,0,CaptureCB,Pointer(Z));
end;

end;

//==========================================
procedure TZniffer.ThreadTerminate(Sender: tobject);
begin
Fsnooping:=false;
end;

procedure TZniffer.SetAdapterIndex(const Value: integer);
begin
if (value>-1) and (value<Adapters.count) then
FadapterIndex := Value;
end;

end.
 
hook winsck的代码我也有啊

欢迎交流啊~~~~~~~~~~~~~
 
多人接受答案了。
 
后退
顶部