|
TCP IP Sniffer - Felix John COLIBRI.
|
- abstract: This program will capture and display the Ethernet packets
travelling on your network
- key words: TCP-IP - Sniffer - Utility - Packet Dump - Packet.Dll -
Packet32.Dll - WinPcap - Snowing
- software used: Windows XP, Delphi 6, Winpcap Dlls
- hardware used: Pentium 1.400Mhz, 256 M ram, 140 G hard disk
- scope: Delphi 1 to 2005, Windows
- level: Intermediate
- plan:
1 - Introduction
About five years or eight ago, I was still using a US Robotics Modem for my web
access. On some occasions my PC seemed to start sending some data to the Net
while I was still quietly programming in Delphi. Being a little bit paranoic, I
installed Zone Alarm to keep intruders out. The constant warnings quickly
became a nuisance, so I decided to try to figure out by myself what was
happening on my machine.
Many programs are available, and finding them by googling here and there was
quite easy. However many of those applications were either only in .EXE format,
or outright commercial. Outside of Windows and Delphi, we do not use any
application which is not in source form, so we had to hunt for an open source
example.
We actually found two in the Delphi / Windows world:
Before we start, let us mention two points:
- the installation of a sniffer using Packet.Dll will not be accepted by all
firewalls.
- many of the sniffer on the market directly or indirectly use WinPcap. You
might prefer to use those a finished product, instead of programming the
sniffing in Delphi.
2 - Sniffing techniques
2.1 - Overview
On a network the data is formatted in packet containing our information and
communication overhead information.
The PC contain one or several network interface cards (NIC, like 3Com, AsusTek
etc.). Each of those cards has a unique hardware identifier. When two person
establish a connection, each packets contain the address of the two network
cards, and those addresses are used to route the packet to the correct PC. But
a PC connected to a network sees all the data packets travelling on the wire.
In the usual case, only those packets with the NIC address of one of our cards
are fetched and sent to the software.
Now what we are interested in is not only to see all the packets, but also to
eavesdrop on the traffic without participating directly to any conversation.
This is what sniffing is all about.
2.2 - Architecture
To understand how sniffing works, let us simply sketch the Windows
architecture:
From the bottom to the top, we have:
- the ethernet coax, or the line modem
- then our PC is connected to the network using either an Ethernet Card, or a
serial card
- at the software level, we go through
- the kernel mode layers
- the user mode layers
- finally, our application
This looks like this:
Now we can sniff the packets at several levels:
- at the hardware level (1)
- by making a hardware wire tap
- by using special network card hardware with debugging features
- at the software level
- in Kernel mode (2 and 3)
- by writing new device drivers
- by using a Packet capture Ndis driver
- by using one of the many hooks provided by some Windows versions
- in User mode
- by calling the IpHelp Api or using Raw Sockets (4)
- by watching the packets when we read or write packets using Sockets
(5)
You can find detailed presentations about the different possibilities in the
Ndis.Com site. However this site offers no sources, since it is
linked to a commercial site (pcausa).
2.3 - Trials
I am mainly concerned here with using PACKET.DLL, and will not present the
other alternatives in detail. For those interested, let me just mention the
following points:
- writing a low-level VXD is the lowest level I ever went. I was lured into
this by a paper by Solar Eclipse. As I
remember it, he was loading a driver below the Windows TCP/IP layers (level
2 in our figure), grabbing the "To" and "From" addresses from e-mails and
happily exchanging them from one mail to the next. I had no reason to
install this kind of little devil to forge our own mails, but fetching the
packets at the serial level seemed interesting. It took me about a full week
to understand this driver business, and to adapt the Serial Port driver
using the Microsoft (free) assembler and link editor tools. It still was
some uncomfortable way of working so I stopped.
- the Ip Help Api is quite easy to use, and I found a nice
Delphi application from Dirk CLAESSENS as well at the Delphi Import Unit by
Jedi.
- the raw sockets only work on some Windows versions (XP), but I could not
succeed in spite of reading all available threads on the topic in Borland
NewsGroups
So this leaves us with the PACKET.DLL approach.
2.4 - PACKET.DLL
The Ndis PACKET.DLL has a long history:
- it seems that the Windows DDK (Device Driver Kit) contained as an example
the source code of a packet driver.
- I found in the late nineties a source code of a packet driver, written by
Sang-Eun Han, with the user application called "snowing".
You may find the .DLL (without the sources) on the ICS web site,
and the sources are still floating around on the web. However, this
"snowing" application uses a Windows 98 Vxd driver, and when I switched to
XP it was no longer useable.
If you are working on Windows 98, you can still use the "snowing" drivers,
which are somehow simpler than the WinPcap drivers used in this paper, but
the Delphi layers that we built on top of both are identical.
- the Politecnico di Torino dedicated a full web site to the
sniffing of packets for Windows, the package name being WinPCap. And
everything works correctly for Windows 98 to XP, or other versions. You
can find on their site low level drivers, as well as complete sniffing
application. Everything is in source code, but coded in C.
We are going to use their drivers in the rest of this paper.
Let me also mention that nearly ALL commercial or freeware sniffing tools in
the Windows world are based on Winpcap drivers.
We prefer to build the project in Delphi since we can
- build any display interface that we want
- integrate the sniffing in any Delphi application
You may read the paper about NDIS packet driver and
packet capture. A more detailed and technical presentation of
the capture using the Winpcap project is available, but
only in Italian.
2.5 - The Sniffer and the Analyzer
We are going to build two Delphi applications:
- the Sniffer, which fetches all the Ethernet packets and displays some simple
statistics and, optionally, saves the packet in a log on the disk
- the Analyzer which can perform an offline detailed content analysis of the
packets read from the log file
After the presentation of both projects, we will present some examples where
the tools were used.
3 - 1- A Delphi Sniffer
3.1 - Installing the drivers
To capture the packets, we must install a driver and a .DLL. We used the open
source ones from WinPCap.
The Politecnico di Torino projects wants to standardize the packet handling on
all Windows platforms. It offers:
- the low level drivers
- the capture layer
- some analysis tools
They chose to include the captures packets in a normalized envelope coming from
the Unix World. This envelope, called BPF (Berkley Packet Filter),
contains time stamps and similar informations and the corresponding header is
about 18 byte long. After the header, we find the "raw ethernet packet", which
is what we are going to use.
Since their goal is the use of this BPF format, they do not offer simple
download and installation of the drivers only.
I found that the simplest way to install without error the drivers was to
download the install WINPCAP_3_0.EXE (431K in June 2003), launch it, and then
work with the installed drivers. The more complete WINPDCAP_3_0.ZIP (849K)
contains in addition all kind of .EXE for packet capture, writing, analysis, as
well as help files and format descriptions. And you may download full sources
in WPcapSrc_3_0_A_3.ZIP (602K).
The installation places the following files on the disk:
- the driver: c:\windows\system32\drivers\npf.sys (30 K)
- the user .DLL: c:\windows\system32\packet.dll (56 K)
The wpcap.dll (204 K) which is the BPF library will not be used in our
projects.
Most of the firewall software will complain about this PACKET.DLL installed on
your system. The reason is that PACKET.DLL can put the PC in promiscuitous
mode, and this is not tolerated by some firewalls.
Having all the sources, you can try to write some parts in Delphi, but be
forewarned that this is not a simple business:
- the drivers must be build in the XP special format (not the old Windows 98
Vxd format)
- the product is able to detect the Windows platform, and the mere reading of
the ethernet card MAC address takes hundreds of lines.
The layers on top of the drivers are easy to write, and this is what were are
going to do now.
3.2 - Integrating PACKET.DLL into Delphi
To interface to PACKET.DLL, we need to build the Import UNIT. This has been
done by several developers, and the one I found was done by Lars Peter
Christiansen. His UNITs allow full Delphi integration of the BPF filtering,
so we simply took whatever was necessary for simply capturing the packets. We
kept the original UNIT organization and ended up with the following pieces:
- U_NDIS.PAS: some NDIS types and constants
- U_PACKET_FORMAT.PAS: the definition of the BPF envelope (required since the
driver return us pointers to this envelope)
- U_PACKET_32.PAS: the Delphi calls to PACKET.DLL
- U_PACKET_CAPTURE.PAS: a layer to adapt the capture to the different Windows
versions and perform some cleanup (freeing allocated memory for the packets
etc)
On top of Lars Peter Christiansen units we added the statistics collection and
protocol analysis units. This includes
- the sniffer thread
- the packet list class
- the protocol definitions
- the main capture form
3.3 - The sniffer thread
The packets are going to arrive at any time, so using a thread to call the
display and logging application is the obvious solution.
Our sniffer class has the following definition:
c_sniffer= Class(c_basic_object)
// -- pointer to the capture driver
m_pt_capture_info: t_pt_capture_info;
// -- the adapters found on the system
m_c_adapter_name_list: TstringList;
m_current_adapter_index: Integer;
// -- the listening thread
_m_c_sniffer_thread: c_sniffer_thread;
m_is_snooping: Boolean;
// -- the event called whenever a packet is received
m_on_sniffer_received_packet: Procedure (Data: pointer; recvbytes: Word) of Object ;
Constructor create_sniffer(p_name: String);
Function f_get_adapters(Var pv_error_string: string): boolean;
Function f_activate(var pv_error_string: string): boolean;
Function f_deactivate(var pv_error_string: string): boolean;
procedure sniffer_thread_did_terminate(Sender: tobject);
Destructor Destroy; override;
end; // c_sniffer
|
The main methods of this CLASS are the following (the error handling is not
shown):
function c_sniffer.f_get_adapters(var pv_error_string: string): boolean;
begin
Result:= false;
m_c_adapter_name_list.commatext:= pcap_GetAdapternames(',', pv_error_string);
if m_c_adapter_name_list.CommaText= ''
then Exit;
Result:= true;
end; // f_get_adapters
function c_sniffer.f_activate(var pv_error_string: string): boolean;
// -- f_activate sniff, start thread
begin
Result:= false;
// -- Open Driver and NetAdapter
// -- (..., promiscuous, timeout, )
m_pt_capture_info:= pcap_open_live(Pchar(m_c_adapter_name_list[m_current_adapter_index]),
k_default_snapshot_length, True, 100, pv_error_string);
// -- start the snooping thread
_m_c_sniffer_thread:= c_sniffer_thread.create(self);
_m_c_sniffer_thread.OnTerminate:= sniffer_thread_did_terminate;
_m_c_sniffer_thread.FreeOnTerminate:= False;
// -- now start the thread
_m_c_sniffer_thread.Resume;
m_is_snooping:= True;
Result:= true;
end; // f_activate
procedure c_sniffer.sniffer_thread_did_terminate(Sender: tobject);
begin
m_is_snooping:= false;
end; // sniffer_thread_did_terminate
function c_sniffer.f_deactivate(var pv_error_string: string): boolean;
begin
Result:= false;
// -- Stop Snooping Thread
_m_c_sniffer_thread.Terminate;
_m_c_sniffer_thread.WaitFor;
_m_c_sniffer_thread.Free;
_m_c_sniffer_thread:= nil;
// -- Release Driver Handle
Pcap_Close(m_pt_capture_info);
Result:= true;
end; // f_deactivate
|
The sniffer thread is defined by:
c_sniffer_thread= Class(Tthread)
private
m_c_sniffer: c_sniffer;
public
Constructor Create(p_c_sniffer: c_sniffer);
Destructor Destroy; override;
Procedure Execute; override;
end; // c_sniffer_thread
|
with the usual tThread methods:
procedure c_sniffer_thread.Execute;
begin
if m_c_sniffer= nil
then Exit;
// -- whenever a packet is detected, call our event
While Not Terminated do
Pcap_Read(m_c_sniffer.m_pt_capture_info, 0, capture_call_back, Pointer(m_c_sniffer));
end; // Execute
|
and this methods uses a (non-object) call-back, since the PACKET.DLL is not
object oriented:
procedure capture_call_back(p_c_sniffer: pointer; const p_pcap_header: Ppcap_pkthdr;
const p_pt_data: pchar);
begin
c_sniffer(p_c_sniffer).m_on_sniffer_received_packet(p_pt_data, p_pcap_header.len);
end; // capture_call_back
|
The unit organization is the following:
3.4 - The main program
Our main Form now simply creates a c_sniffer instance, fetches the adapter
names, and starts the capture:
g_c_sniffer:= c_sniffer.create_sniffer('sniffer');
// -- initialize the event handler
g_c_sniffer.m_on_sniffer_received_packet:= hande_received_packets;
// -- start the capture
g_c_sniffer.f_get_adapters(l_error_string);
g_c_sniffer.f_activate(l_error_string);
|
and the handler displays statistics and saves the packets in a log
procedure tForm1.handle_packet(p_pt_packet: pointer; p_packet_size: Word);
begin
// -- display statistics, packet content, log the packet ...
end; // handle_packet
|
3.5 - Packet Content analysis
The capture DLL only sends us a pointer to the BPF packet. We changed this into
a pointer to the raw Ethernet data. So the capture event gets an Ethernet
packet. What does it contain ? We get the answer by looking into the packet,
which is basically an analysis of Ethernet, Arp, Ppp, Ip data structures.
This packet content analysis can become quite involved, so we encapsulated in a
CLASS descending from c_sniffer, and responsible for:
- saving the packet in a log file
- collecting simple statistics (packet count and total incoming and outgoing
byte count)
- detailed protocol analysis (IP addresses, ports etc)
Basically:
- the Ethernet packet contains a header and a protocol (Arp, Ppp, Ip ...)
packet
- the protocol packet, say the Ip packet, contains a protocol header, and a
sub protocol packet (ICMP, UDP, TCP)
- and so on.
This can be presented like this:
Let us sketch the analysis for Ethernet and IP:
- we define a record specifying the content of an Ethernet packet
type t_ethernet_packet= packed record
m_ethernet_destination: t_MAC_address;
m_ethernet_source: t_MAC_address;
m_ethernet_protocol: array[0..1] of byte;
// -- variable size
m_ethernet_data: array[0..0] of byte;
end;
t_pt_ethernet_packet= ^t_ethernet_packet;
const k_ethernet_header_size= SizeOf(t_ethernet_packet)- 1;
// -- rfc1340
k_PPP_IPCP_protocol = $8021; // Internet Protocol Control Protocol
k_PPP_CCP_protocol = $80fd; // Compression Control Protocol
k_PPP_LCP_protocol = $c021; // PPP Link Control Protocol
k_PPP_PAP_protocol = $c023; // PPP Password Authentication Protocol
k_PPP_LQR_protocol = $c025; // PPP Link Quality Report
k_PPP_CHAP_protocol = $c223; // PPP Challenge Handshake Auth. Protocol
k_arp_protocol= $0806;
// -- rfc1340
k_ip_protocol= $0800;
|
- the handler receives a pointer to an Ethernet packet and depending on the
protocol word calls the protocol analysis procedure:
procedure c_packet_sniffer.analyze_packet(p_pt_ethernet_packet: t_pt_ethernet_packet; p_ethernet_packet_size: Integer);
// -- ... here the protocol analysis
var l_protocol_size: Integer;
l_protocol: Word;
begin // analyze_packet
with p_pt_ethernet_packet^ do
begin
l_protocol_size:= p_ethernet_packet_size- k_ethernet_header_size;
l_protocol:= f_swap_word(@ m_ethernet_protocol);
case l_protocol of
k_ARP_protocol :
add_packets_to_stats(m_direction= 'i', e_arp_packet, m_sub_protocol_size);
k_IP_protocol : analyze_ip_packet(t_pt_ip_packet(@ m_ethernet_data), l_protocol_size);
// -- ... other
end; // case
if Assigned(m_after_packet_arrived)
then m_after_packet_arrived(Self);
end; // with p_pt_ethernet_packet^ do
end; // analyze_packet
|
- let us assume that we received an IP packet. The IP packet format, defined
in u_ip_packet.pas is the following:
type t_ip_packet= packed record // 20 bytes+ data
m_version_and_header_length: Byte;
m_type_of_service: Byte;
m_packet_length: Word;
// -- identification of a datagram
m_datagram_identification: Word;
m_flag_and_offset: Word;
m_time_to_live: Byte;
m_ip_protocol: Byte;
m_check_sum: Word;
m_ip_source: t_IP_address;
m_ip_destination: t_IP_address;
// -- variable size
m_ip_data: array[0..0] of Byte;
end;
t_pt_ip_packet= ^t_ip_packet;
const // -- 20 bytes (ethernet+ ip= 34)
k_ip_header_size= SizeOf(t_ip_packet)- 1;
// -- the sub-protocol code
k_ip_icmp= 1;
k_ip_igmp= 2;
k_ip_tcp= 6;
k_ip_igp= 9;
k_ip_udp= 17;
|
- and the nested ip protocol procedure is the following:
procedure analyze_ip_packet(p_pt_ip_packet: t_pt_ip_packet; p_ip_packet_size: Integer);
// -- ... here the TCP/IP, TCP/UDP analysis procedures
var l_IP_sub_protocol_size: Integer;
begin // analyze_ip_packet
l_IP_sub_protocol_size:= p_ip_packet_size- k_ip_header_size;
with p_pt_ip_packet^ do
begin
m_IP_source_address:= f_IP_to_string(m_IP_source);
m_IP_destination_address:= f_IP_to_string(m_IP_destination);
case m_ip_protocol of
k_ip_tcp : analyze_ip_tcp_packet(t_pt_ip_tcp_packet(@ m_ip_data), l_IP_sub_protocol_size);
k_ip_udp : analyze_ip_udp_packet(t_pt_ip_udp_packet(@ m_ip_data), l_IP_sub_protocol_size);
// -- .. the other sub-protocols
end; // case
end; // with p_pt_ip_packet^
end; // analyze_ip_packet
|
You may find similar packet analysis on ICS web site, where
IngusPacket.Pas written by Jagad, F. Piette and D Claessens was analyzing the
"snowing" packets.
3.6 - The project organization:
The project unit organization is as follows:
Obviously this unit splitting might be considered exaggerated. You can easily
collapse all the Delphi part (the yellow and white boxes) into a single unit,
if the unit count is important for you.
3.7 - The capture application
Adding the display labels, a tListView and a Memo, we get the following
application:
To give you an idea of using this application, let us examine a simple call to
Google:
|
start the capture, by checking "stats", "list_packets" and clicking
"create" and "start":
|
|
launch Internet Explorer (or any other browser), and type
"http://www.google.com" in the address combo box, and hit Enter
|
|
p_packet_sniffer displays the following packets:
|
|
to have the statistics by protocol, click "stats_"
|
|
here are the protocol used:

|
4 - The packet analyzer
4.1 - The analysis project
The purpose of the p_packet_sniffer project is to give quick feedback about
the Ethernet traffic, and avoid any time consuming display which might loose
some packets.
If we want to analyze the content of the packets:
- we save the packets in a log file during the capture
- we use a separate application, p_analyze_packet to perform any content
analysis
4.2 - The organization
In this application, analysis time is no longer important. We therefore used
CLASSes to analyze the packets, instead of chasing pointers to get at packet
structure information.
I am not convinced that object creation and deletion is still important in our
age of huge memory capacities and lightning fast hard disks, but the display in
any kind of tMemo or, worse, tListView could become a problem. If you believe
that time is not critical for you, you can always integrate the following
analysis classes in the previous project.
To analyze our packets content, we will use classes for each protocol: there
will be a c_ethernet_packet, a c_ip_packet, a c_ip_tcp_packet and so on. The
easy way is to copy the data of each protocol in its protocol object:
This involves a lot of copying. So we prefered to build the classes with
attributes corresponding to the protocol and a pointer to the data in a single
data buffer (the buffer with the data loaded from the disk):
If this pointer technique does not suit you, it is easy enough to create
streams and use a stream (which is a pointer anyway) instead of the raw
pointer. This might even be useful when some packet content needs
pre-processing (PPP character conversion, for instance).
4.3 - The Analysis units
To give you an idea about the protocol classes, here are a couple of classes
and methods:
- the c_ethernet_packet is defined as:
c_ethernet_packet= class(c_basic_object)
public
m_id, m_ethernet_size: Integer;
m_hidden: Boolean;
m_pt_ethernet_packet: t_pt_ethernet_packet;
m_protocol: Word;
m_c_protocol_packet: c_protocol_packet;
Constructor create_ethernet_packet(p_name: String;
p_id, p_size: Integer;
p_pt_ethernet_packet: t_pt_ethernet_packet); Virtual;
function f_id: String;
function f_c_self: c_ethernet_packet;
function f_source_mac: String;
function f_destination_mac: String;
function f_direction: Char;
function f_id_and_direction: String;
function f_ethernet_hex: String;
function f_ethernet_detail: String;
function f_data_size: Integer; Virtual;
procedure display_ethernet_packet;
procedure display_ethernet_packet_hex;
procedure display_packet_only(p_hex: Boolean);
function f_display_protocol: String;
function f_display_data_hex: String;
Destructor Destroy; Override;
end; // c_ethernet_packet
|
- in the c_ethernet_packet constructor we examine the protocol byte and
create the relevant protocol class:
Constructor c_ethernet_packet.create_ethernet_packet(p_name: String;
p_id, p_size: Integer;
p_pt_ethernet_packet: t_pt_ethernet_packet);
var l_ethernet_data_size: Integer;
l_pt_protocol_data: Pointer;
begin
Inherited create_basic_object(p_name);
m_id:= p_id; m_ethernet_size:= p_size;
m_pt_ethernet_packet:= p_pt_ethernet_packet;
// -- the sub packet contained after the header
l_ethernet_data_size:= m_ethernet_size- k_ethernet_header_size;
l_pt_protocol_data:= @ m_pt_ethernet_packet^.m_ethernet_data;
m_protocol:= f_swap_word(@ m_pt_ethernet_packet^.m_ethernet_protocol);
case m_protocol of
k_ip_protocol : m_c_protocol_packet:= c_ip_packet.create_ip_packet('IP',
l_ethernet_data_size, t_pt_ip_packet(l_pt_protocol_data));
k_ARP_protocol : m_c_protocol_packet:= c_arp_packet.create_arp_packet('ARP',
l_ethernet_data_size, t_pt_arp_packet(l_pt_protocol_data));
// ... the other protocols
end; // case
end; // create_ethernet_packet
|
Therefore building the protocol packets is similar to the statistical analysis
built in p_packet_sniffer, but the data is now managed by Delphi classes, and
we have all the power to build lists, perform computations on those lists,
reconstruct data streams, filter packets bases on many critera. This is
standard Delphi programming
The overall organization is the following:
The blue boxes correspond to ancestor classes (classes grouping attributes of
descendent packet classes).
The full detail can be found in the attached source code.
4.4 - Demonstration
Let us just show some example of using the packet analyzer:
|
load the sources and compile
|
|
in the main tabsheet choose any previously saved log file. In our case, the
files are the files of the Google connection:
|
|
click on the log file you wish to analyze
|
|
select for instance the "session" button to see the packets sorted by IP
connection, then click on any IP address. In our case we chose the
64.231.161.104 address, and, going down the packet display found, for
instance, the HTTP "GET":
|
|
we can also examine the Hex content (by checking the "hex" check box), and
in addition display combinations of protocols. Just a last example, we
wanted to display the UDP content: we clicked the "packets" tab, and
selected UDP, with "hex":
so we find a DNS query
|
5 -
6 - Some sniffing examples
We used the packet capture and analysis tools on several occasions:
- first to see the accurate content of the Internet Explorer HTTP headers. For
our internal Internet Browser I had asked only for the .HTML pages and was
not getting many images or other files. So copying exactly what IE was
sending in the "Content-Type" solved the problem
- I also could examine the Cookie content used by some servers
- to upload our web pages, we wanted complete automation of the process. We
could have started with the Indy or the ICS components, or at least the
Delphi tClientSocket and tServerSocket. We chose instead to use the basic
Winsock library. Now writing the FTP client was not as simple as fetching
an .HTML page with HTTP: 2 sockets are required, and there are several
possible modes. When we were stuck in those protocol conversations, we
simply used the ICS FTP component and watched the request and the answers.
Writing the scripting layers on top of the basic FTP protocol was then a
piece of cake.
- we also used the sniffer to watch Interbase, and this is described in the
Sniffing Interbase Traffic paper.
This paper also presents a UNIT which totally encapsulates the capture
mechanism. With about 3 lines of code, the Interbase application displays
the capture statistics (packet count, bytes, line statistics etc).
7 - Improvements
We could add many bells and whistles to our two projects. For example:
- write the drivers in Delphi. We did this for the serial driver for
Windows 98, but balked at the effort under XP. Anyway, the drivers from
WinPcap are perfect for our task, so this is not a priority
- simplify the structure of the import DLLs
- we chose to isolate the different protocols in many units, and this could
also benefit from some grouping
- we did not present here
- the NetBios levels that we analyzed when we were using Windows 98. By
the same token, the PPP levels, and the Adsl protocols could be added
- we also started to build the sequence of TCP packets back, in effect
staring to implement the reception part of the protocol.
- we only considered reading the packets. Under XP, writing seems to be
possible, but was not investigated.
No doubt that you will find many possibilities to enhance the two projects we
presented here. You can send us a copy of your units (sources only, please) and
we might place them, with due credit to the author, on this site. Alternately
we may also place here links to sniffing applications (again, sources only).
8 - Download the Source Code
We placed all the sources for the projects in .ZIP files. Those files contain:
- the main program (.DPR, .DOF, .RES), the main form (.PAS, .DFM), and any
other auxiliary form
- any .TXT for parameters
- all units (.PAS) for units
Those .ZIP
- can be used from any folder (the pathes are RELATIVE)
- will not modify your PC in any way beyond the path where you placed the .ZIP
(no registry changes, no path creation etc).
To use the .ZIP:
- create or select any folder of your choice
- unzip the downloaded file
- using Delphi, compile and execute
To remove the .ZIP simply delete the folder.
Here are the files:
CAUTION : to use the p_packet_sniffer, you MUST donwload and install
NPF.SYS, PACKET.DLL, WPCAP.DLL from http://www.winpcap.it, as
explained above.
9 - Conclusion
The drivers and DLLs for capturing packets are freely available in source form.
Once installed, we can build Delphi units to watch, log or analyze those
packets rather easily.
The resulting capture and analysis tool can be used for education,
investigation or debugging purposes. In the companion paper
Sniffing Interbase Traffic, we present the
analysis of Interbase traffic.
10 - References
- tutorials about packet capture
- Serial Card driver:
Attacking Windows 9x with Loadable Kernel
Modules
Solar Eclipse
http://www.phreedom.org/article/
Explanation about loadable modules, along with/ assembler example
- NDIS
- description of Windows architecture and explanation about the different
possible hooks
http://www.pcausa.com
the commercial site
http://ndis.com
the tutorial site linked to the previous site
- msdn
http://msdn.microsoft.com/
MSDN Home > MSDN Library > Windows Development > Network Devices and
Protocols > Design Guide > Network Drivers > Network Architecture for
Kernel-Mode Drivers > Network Driver Environments
the Microsoft (very short) description of the NDIS architecture
- IpHlpApi.Dll)
- Delphi TCP/IP MONITOR - Dirk Claessens
http://users.pandora.be/dirk.claessens2 - netmon.zip
a Delphi source code project using IpHlpApi
- IpHlpApi header
ftp://delphi-jedi.org/api/IPHlpAPI.zip
the Delphi import library for IpHlpApi (not tested)
- packet libraries
- Snowing Sang-Eun Han - seh@brabo1.korea.ac.kr
http://widecomm.korea.ac.kr/~seh
dead link, but search using Google - the Windows 98 PACKET.DLL
- ICS
http://www.overbyte.be
ICS component suite home, where the "snowing" capture package can
still be found
- WinPcap: the Free Packet Capture Architecture for Windows
Politecnico di Torino
http://winpcap.polito.it/
The only working PACKET.DLL I found working on XP. And in source
The Delphi adaptation was performed by Lars Peter Christiansen (and
possibly by many other)
11 Other Papers with Source and Links
|
UML Patterns
|
|
the lexi editor
|
delphi source code of the Gof Editor: Composite, Decorator, Iterator, Strategy, Visitor, Command, with UML diagrams
|
|
factory and bridge patterns
|
presentation and Delphi sources for the Abstract Factory and Bridge patterns, used in the Lexi Document Editor case study from the GOF book
|
|
gof design patterns
|
delphi source code of the 23 Gof (GAMMA and other) patterns: Composite, Decorator, Iterator, Strategy, Visitor, Command
|
|
|
|
TCP/IP
|
|
tcp ip sniffer
|
project to capture and display the packets travelling on the Ethernet network of your PC.
|
|
sniffing interbase traffic
|
capture and analysis of Interbase packets. Creation of a database and test table, and comparison of the BDE vs Interbase Express Delphi components
|
|
socket programming
|
the simplest Client Server example of TCP / IP communication using Windows Sockets with Delphi
|
|
delphi socket architecture
|
the organization of the ScktComp unit, with UML diagrams and a simple Client Server file transfer example using tClientSocket and tServerSocket
|
|
|
|
Utilities
|
|
the coliget search engine
|
a Full Text Search unit allowing to find the files in a directory satisfying a complex string request (UML AND Delphi OR Patters)
|
|
|
|
Delphi utilities
|
|
delphi net bdsproj
|
structure and analysis of the .BDSPROJ file with the help of a small Delphi .XML parser
|
|
dccil bat generator
|
generation of the .BAT for the Delphi DCCIL command line compiler using the .BDSPROJ
|
|
dfm parser
|
a Delphi Project analyzing the .DFM file and building a memory representation. This can be used for transformations of the form components
|
|
dfm binary to text
|
a Delphi Project converting all .DFM file from a path from binary to ascii format
|
|
|
|
Database
|
|
database reverse engineering
|
Extraction of the Database Schema by analyzing the content of the application's .DFMs
|
|
sql parser
|
Parsing SQL requests in Delphi, starting from an EBNF grammar for SELECT, INSERT and UPDATE
|
|
ado net tutorial
|
a complete Ado Net architectural presentation, and projects for creating the Database, creating Tables, adding, deleting and updating rows, displaying the data in controls and DataGrids, using in memory DataSets, handling Views, updating the Tables with a DataGrid
|
|
turbo delphi interbase tutorial
|
develop database applications with Turbo Delphi and Interbase. Complete ADO Net architecture, and full projects to create the database, the Tables, fill the rows, display and update the values with DataGrids. Uses the BDP
|
|
|
|
Web
|
|
sql to html
|
converting SQL ascii request to HTML format
|
|
simple web server
|
a simple HTTP web Server and the corresponding HTTP web Browser, using our Client Server Socket library
|
|
simple cgi web server
|
a simple CGI Web Server which handles HTML <FORM> requests, mainly for debugging CGI Server extension purposes
|
|
cgi database browser
|
a CGI extension in order to display and modify a Table using a Web Browser
|
|
whois
|
a Whois Client who requests information about owners of IP adresses. Works in batch mode.
|
|
web downloader
|
an HTTP tool enabling to save on a local folder an HTML page with its associated images (.GIF, .JPEG, .PNG or other) for archieving or later off-line reading
|
|
web spider
|
a Web Spider allowing to download all pages from a site, with custom or GUI filtering and selection.
|
|
asp net log file
|
a logging CLASS allowing to monitor the Asp.Net events, mainly used for undesrtanding, debugging and journaling Asp.Net Web applications
|
|
asp net viewstate viewer
|
an ASP.NET utility displaying the content of the viewtate field which carries the request state between Internet Explorer and the IIS / CASSINI Servers
|
|
|
|
Graphic
|
|
delphi 3d designer
|
build a 3d volume list, display it in perspective and move the camera, the screen or the volumes with the mouse.
|
|
|
|
Controls
|
|
find memo
|
a tMemo with "find first", "find next", "sort", "save" capabilities
|
|
|
|
|
|
|
|
Other
|
|
valid delphi links
|
430 Delphi Web pages, sorted by category (Database, Xml, Web programming, TCP/IP etc), with special attention to source code availability
|
|
|
|