Title Sniffer technology principle and application, including programming methods and tools using Warton (original) Keyword Sniffer programming tool Ethereal, Sniffer Pro
First of all, I am coming to advertise today :) I haven't updated column for a long time, the key is to write something good, I am afraid that everyone will laugh! Although I haven't been to be over, I have seen others being smashed, hehe. Not to say, this seems to be normal in 9cbs! Today, I put this post, this is a special discussion of the topic development version: http://expert.9cbs.net/EXPERT/topic/2333/2333459.xml? Temp = .3382532, in fact, this post also There is no more in-depth thing, the key is that the topic is very popular. I sent this post to I hope more people can go to the special edition, participate in and organize discussions, but the result is not ideal. Kingzai: Sniffer Chinese translation is an olfactory detector, which is very wide in current network technology. Sniffer can be used as a diagnostic tool for network faults, or as a tool for hacker sniffing and listening. In the last two years, the Sniffer technology has new features. Traditional SNIFFER technology is passively listening to network communication, username, and passwords. The new SNIFFER technology has the characteristics of the mainly controlled communication data, and the SNIFFER technology is extended to a new field. In addition to the current network detection management, Sniffer technology has also begun to be applied in the field of information preservation. It can be said that Sniffer technology is a double-edged sword, how to better use it, understand some of its characteristics, will make this technology better for us. Sniffer's programming method is relatively universal, 1.WinPCap This is a relatively universal library. I believe that most people don't have to be too unfamiliar. 2.Raw Socket has supported this after 2000. Item features, 2000 Server has a network monitor based on Raw Socket 3.TDI, NDIS, SPI, Hook Socket technology. This technique is relatively large, which can be intercepted instead of just get a copy of the package. In general, it will generally be more than two. I have mentioned one here, but more needs everyone to add. The purpose of this topic is to see everyone to learn together, discuss Sniffer technology, let more people participate, let everyone know that this sector can bring you really want. Warton: libpcap is a good thing, Linux, Windows can be used under Windows, and the security systems such as many intrusion detection are used as the core. I have never used it, I don't know how it is cross-platform. To use the SPI, look at the XFilter's code and book, especially the book is good, but unfortunately, it has not used it. Raw Socket writes more than Sniffer, there are also a lot online code! Yesterday I saw 9CBS Home, there were a few articles about Sniffer, preserved, haven't come to see ... I will talk about the current common SNIFFER tools and their technical implementation! Two articles of the 9CBS homepage, everyone can look at it, there is still a few articles, temporarily can't find http://www.9cbs.net/develop/Article/21/21363.shtmhttp://www.9cbs.net /Develop/Article/21/21352.shtmhtp://www.9cbs.net/develop/Article/15/15919.shtm netsys2: 1) WinPCAP driver WinPCAP (Windows Packet Capture) is the Windows Platform Next free, public Network Access System. The purpose of issuing WinPCAP this project is to provide Win32 applications to access the network underlying ability.
It provides the following functions: 1> Capture the original datagram, including the data reported on the shared network and exchange / acceptance between each other; 2> Before the data is reported to the application, according to the custom The rule filters some special datagrams; 3> Send raw datagram on the network; 4> Collect statistics during network communication. The main function of WinPCAP is to send and receive raw datagrams independently of host protocols such as TCP-IP. That is, WinP CAP cannot block, filter or control the sending of other application datagrams, which is just the data report transmitted on the shared network. Therefore, it cannot be used for QoS schedule or personal firewall. At present, the main object developed by WinPCAP is Windows NT / 2000 / XP, which is mainly because only a small portion of the user who uses WinPCap is only using Windows 95/98 / Me, and M $ has also given up the development of Win9x. . Since this article related program T-ARP is also an NT / 2000 / XP user. In fact, the concept of 9X systems in WinPCap is very similar to the NT system, just a bit difference in some implementation, such as 9X only supports ANSI encoding, and the NT system advocates the use of Unicode encodes. ZZHONG2: There is a software called Sniffer Pro. It can be used for network management software. There are many functions to monitor network operation, data traffic for each network machine, real-time reflecting IP accesses IP and data between each machine. You can capture the filter, you can only grab the filter, such as the POP3 package, SMTP package, FTP package, etc., and can find the mailbox username and password, and FTP username and password. It also You can listen on the network using the switch, but you have to load it on the switch. There is also a simple listener called Passwordsniffer, you can take the mailbox username and password, and the ftp username and password, it can only use Hub The above two software can be uploaded to Xiaofeng to: http://www.chinesehack.org/ Warton: Libpcap's latest version is 0.7.2, download a lot of downloads (Linux / UNIX) WinPCAP's latest version is 3.0 Sourcecodes with WinPCAP: http: //download.pchome.net/php/dl.php? SID = 11474 Famous Software TCPDUMP and IDS Snort are based on libpcap, and the NMAP scanner is also libppcap to capture the target. The packet returned by the host. WinPCap provides two different levels of programming interfaces: a libpcap-based WPCAP.DL and the other is a lower packet.dll. For the general development of libpcap-compatible development with UNIX platforms, it is of course selection. The following libraries are related to LIPCAP: libnet1.0.2: Send a construction process of packets Libnids: Some frameworks for IDS LIBICMP: ICMP packets handle some famous snifper: TCPDump / Windump: Support multiple UNIX The latter supports Windows.
Based on libpCapsniffit: UNIX, Windows, Libpcapngrep: Libpcap, UnixWindows. You can use rule expressions, identify PPP, SLIP, and FDDI packets Snifer Pro / NetXray: Professional protocol analysis tools, is part of the network analysis scheme provided by NAI: IrislanexplorerNetmonitorCommview single-purpose 噢 口 口 口: Winsnifer, typical hacker tool, sniffing and analyzing FTP, POP3, HTTP, ICQ, SMTP, Telnet, IMAP, NNTP, etc. Password Sniffer for NethacKeriii dedicated sniffer: SMB sniffing L0PHTCRACK, SMPRELAYTCP Connection Session Snark: CommView, Iris, JuggerNautssl Snifting: SSLDUMP - SSLV3 / TLS Network Protocol Analysis Tool Ridius 控: A UDP-based argument accounting protocol, RADIUSNIFF is its representative PPTP sniff Controller: Anger, PPTP-SNIFF (Solaris) SNMP: SNMPSNIFF Switching Network Smeraper: etccon synthesis: DSNIFF Other exchange network sniffer: SNARP, Parasite sniffing countermeasures ......... Netsys2 : Guniffer, circulated on the network is a basic prototype: http://asp.6to23.com/nowcan/code/guniffer.zip void main (int Argc, char ** argv) {int ket erRorcode; char recvbuf [MAX_PACK_LEN] = { 0}; usage (); getcmdline (argc, argv) == cmd_param_help) exit (0); // Initializes Socket Wsadata Wsadata; IrrorCode = WsaStartup (MakeWord (2, 1), & WSADATA); Checksockerror (IrrorCode, " WSAStartup "); sockraw = socket (AF_INET, SOCK_RAW, IPPROTO_IP); Checksockerror (SockRaw," Socket "); // Get Normal IP Address Char Far Name [MAX_HOSTNAME_LAN]; iErrorCode = gethostname (name, MAX_HOSTNAME_LAN); CheckSockError (iErrorCode, "gethostname"); struct hostent FAR * pHostent; // Note that the following three, where the first one of the assigned pHostent pHostent = (struct hostent *) Malloc (Struct Hostent); // Memory, then let it equal return phostent = gethostByname (name); //, but the gethostbyname function is self-contained in the function within the function, so the last sentence is More, everything is fine after deleting the previous sentence. But this procedure has no problem with VC6 compile, I don't know why? Perhaps the compiler optimization of VC6 is played.
SockAddr_in sa; sa.sin_family = AF_INET; sa.sin_port = HTONS (6000); Memcpy (& sa.sin_addr.s_un.s_addr, phostent-> h_addr_list [0], phostent-> h_length); free (phostent); // due to The statement that allocates the memory has been deleted, so this sentence is also removed, otherwise an error. Thanks to the net friend heyuming to discover this problem. Irrorcode = Bind (SockRaw, (PsockAddr) & sa, sizeof (sa)); checksockerror (iERRORCODE, "Bind"); // Sets Sock_RAW to SiO_RCVALL to receive all IP packets DWORD DWBufferlen [10]; dword dwbufferinlen = 1; DWORD dwBytesReturned = 0; iErrorCode = WSAIoctl (SockRaw, SIO_RCVALL, & dwBufferInLen, sizeof (dwBufferInLen), & dwBufferLen, sizeof (dwBufferLen), & dwBytesReturned, NULL, NULL); CheckSockError (iErrorCode, "Ioctl"); // listening IP packets while (1) {memset (recvBuf, 0, sizeof (recvBuf)); iErrorCode = recv (SockRaw, recvBuf, sizeof (recvBuf), 0); CheckSockError (iErrorCode, "recv"); iErrorCode = DecodeIpPack (recvBuf, iErrorCode) Checksockerror (IrrorCode, "decode");}} It has 2 inconvenienties: 1) Cannot Select NIC 2) Read the data with dead loop mode, adapted to Windows window mode, there is a standing feel. Sevencat (): The last time I found some information, but the popularity is not prosperous, and I have been busy recently. I haven't going it yet. Http://expert.9cbs.net/expert/topic/2299/2299615.xml?temp =.2761499windows network package filtering technology (original: http://www.ndis.com/papers/winpktfilter.htm) 1, User -Mode network package filter 1, Winsock layered Service Provider refers to the documentation and examples on Microsoft Platform SDK (http://www.microsoft.com/msdownload/platformsdk/sdkupdate/) There are several Microsoft LSP examples, the latest (possibly The most bug-free is often found here. What need to be known is that the core TCPIP driver can be called via TDI, and it can be completely around Winsock, which is not a question in most cases. For example: QoS implementation can be on the Winsock LSP. However, if this is done, the program must look and operate each package, and cannot rely on Winsock LSP, they have to be implemented in a way to pick up the core state.
2, WIN2000 package filter interface WIN2000 packet filter interface provides a mechanism, which allows user programs or services to specify a series of "filtration principles", which will be implemented by low-level TCPIP. This filter is mainly Pass or DROP operations for the IP origin address, target address, port number (or port number range). Windows Developer's Journal "packet filtering with iphlpapi.dll" Author: Ton plooy, October, 2000, Volume 11, Number 10. Win2000 provides a better programmable control for TCPIP, including packet filtering. Unfortunately, the documentation about this new API is not easy to find. This article demonstrates how to block the package for a particular IP address or a specific TCP port. Link: http://www.wdj.com/ Top Example Download: ftp://ftp.wdj.com/pub/webzip/1110/plooy.ziphollis Solution: HTS W2K iPhook example demonstrated IP filtering and Its hook API contains original files, and free, requires HTSCPP runtime library (free), download address: http://www.hollistech.com/3 ,winsock replace DLL before using Winsock LSP, unique approach In order to replace Microsoft's Winsock DLL with your own DLL, if you go smoothly, your own DLL will receive the user's Winsock call request, and then call the original Winsoc K DLL to process. However, this is relatively laborious, with some difficulty is that Microsoft's Winsock DLL often has some unapproved internal functions, and a Winsock instead of at least some of the unusfined functions of at least the DLL. With the changes in the Windows system structure, some aspects have been strengthened, such as system file protection, which makes this technique becomes less feasible. In general, the use of Winsock DLL is not a bad idea. (Xfilter is using this technology, the original code may be circulated online, I have seen it before, Kernel-Mode network package filter 1, Transport Data Interface (TDI) This is mainly a direct TCPIP drive drive One layer of filtering is driven. The TDI drive on WinXP is a traditional NT-style driver that uses IRP-based APIs, there are two methods here. A, IoattachDevicexyz function family using core mode services implements one filtering on TDI. B. Filter the TDI drive IRP DISPATCH table. The IoattachDevicexyz function mentioned in many WinNT driver development. Both techniques need to know the WinNT drive development programming technology, and the TDI function is also quite understanding. 2, NDIS Intermediate Layer (IM) Specifically, see NDIS IM FAQ: http://www.pcausa.com/resources/ndisimfaq.htm3 ,win2000 Filter-Hook Please refer to DDK documentation, there can be only one event in the system. -HOOK exists, which makes this technology have serious restrictions. (Usually seen this is this) 4, Win2000 FireWall-Hook FireWall-Hook Driver function is a little in the document and is not available in some Win2000 versions.
Please refer to Microsoft's related documentation: http://msdn.microsoft.com/library/default.asp? URL = / library / en-us /network/hh/neetwork/firewall_3wfb.asp5,on-hooking (Fair firewall is used This technology, according to what I know, although I haven't seen the original code.) NDIS-hooking driver intercepts or calls "hook" some functions exported by NDIS packages. Although it is somewhat informal from the implementation, a systematic NDIS-Hooking filter will be very effective. In addition: Ndis-hooking filter drivers have the following benefits: A, easy to install (can be dynamically handled, but sometimes there is a problem, there are some cases now unknown.) B, support dial -ppp adapter. Ndis-hooking technology is very effective and practical under the 98 and ME systems. On these platforms, DDK documents and Provide D Services can help you help you Hook from Ndis Wrapper. Ndis-hooking technology is equally effective and practical on NT, 2000, and XP. This technique is very similar to the debugger of the core mode. The document supports less, and basically will not be certified by WHQL. PCAUSA provides an example of NDIS PIM driver that can run on an existing WIN platform (from 95 to x P). Address: http://www.pcausa.com/ndispim/default.htm Other: NetWork Actions and Process Information: How many people want to know how to connect between the operation and WIN process (that is, the application) For it, you may want to know which process sends or receives data on a specific IP port. Don't consider whether this technology is useful, or whether it is reliable, we believe that the core mode TCPIP drives the upper filter to process this problem. The filter drove the lower layer of the TCPIP does not see process information at all. It is important to note that some network service operations generate a new process attach to system processes. In this case, the process information cannot tell us which process is originally generated. Especially in the core mode WIN service (TDI customer), it is necessary to see the following information united State Patent 5,987,611; "System and methodology for managing Internet access on a per application basis for client computers connect to the internet" We I don't know the value of this patent, I don't know if he can use it on the package. For details, please refer to: http: // www /. Uspto.gov/patft/index.htmlhttp://www.pcausa.com/ ===================== ======================= DRVIPFLT specific parses, it is mentioned above (2-3 that this is true). Assume that everyone has a certain understanding of the driver framework.
IRP assignment procedure is as follows: NTSTATUS DrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {... switch (irpStack-> MajorFunction) {... case IRP_MJ_DEVICE_CONTROL: ioControlCode = irpStack-> Parameters.DeviceIoControl.IoControlCode; switch (ioControlCode) { // ioctl code to start filtering / / This can be sent from the user mode program. / / Directly use the DeviceIocontrol this function, just like this, you can use it, I think. // Deviceiocontrol (DriveHandle, Start_ip_hook, null, 0, null, 0, & bytereturned, Nu LL) case start_ip_hook: {// This should be the most important function. SetFilterFunction (cbFilterFunction); break;} // ioctl to stop filtering case STOP_IP_HOOK: {SetFilterFunction (NULL); break;} // ioctl to add a filter rule case ADD_FILTER: {if (inputBufferLength == sizeof (IPFilter)) {IPFilter * nf; nf = (IPFilter *) ioBuffer; AddFilterToList (nf);} break;} // ioctl to free filter rule list case CLEAR_FILTER: {ClearFilterList (); break;} default: Irp-> IoStatus.Status = STATUS_INVALID_PARAMETER; Break;} Break; ...} setfilterFunction (cbfilterfunction) may be the most important program. The specific is as follows: In fact, this approach is quite registered a callback function in the system. NTSTATUS SetFilterFunction (PacketFilterExtensionPtr filterFunction) {NTSTATUS status = STATUS_SUCCESS, waitStatus = STATUS_SUCCESS; UNICODE_STRING filterName; PDEVICE_OBJECT ipDeviceObject = NULL; PFILE_OBJECT ipFileObject = NULL; PF_SET_EXTENSION_HOOK_INFO filterData; KEVENT event; IO_STATUS_BLOCK ioStatus; PIRP irp; // first obtains a pointer device.
// first of all, we have to get a pointer to IpFilterDriver Device RtlInitUnicodeString (& filterName, DD_IPFLTRDRVR_DEVICE_NAME); status = IoGetDeviceObjectPointer (& filterName, STANDARD_RIGHTS_ALL, & ipFileObject, & ipDeviceObject); if (NT_SUCCESS (status)) {// some initialization, filled Filterdata. // the struct with functions parameters filterData.ExtensionPointer = filterFunction initialize; // we need initialize the event used later by the IpFilterDriver to signal us // when it finished its work KeInitializeEvent (& event, NotificationEvent, FALSE); // this is the most Important registration callback function process. DDK specifically about this is // IOCTL_PF_SET_EXTENSION_POINTER registers filter-hook callback functions to the IP filter driver // to inform the IP filter driver to call those filter hook callbacks for every IP packet // that is received or transmitted. Also, IOCTL_PF_SET_EXTENSION_POINTER Clears Filter-Hook // Callback Functions from The IP Filter Driver. (See it, the last sentence, registering new callback functions, just clearing the original clear, // So there is only one such driver in the system .) // we build the irp needed to establish fitler function of this place is just generating such IRP, not registered irp = IoBuildDeviceIoControlRequest (IOCTL_PF_SET_EXTENSION_POINTER, ipDeviceObject, (PVOID) & filterData, sizeof (PF_SET_EXTENSION_HOOK_INFO), NULL, 0, FALSE, & event , & Iostatus); if (IRP! = Null) {// We send the IRP // This place is true registration.
status = IoCallDriver (ipDeviceObject, irp); // and finally, we wait for "acknowledge" of IpDriverFilter if (status == STATUS_PENDING) {waitStatus = KeWaitForSingleObject (& event, Executive, KernelMode, FALSE, NULL); if (waitStatus =! STATUS_SUCCESS) {}} status = ioStatus.Status; (! NT_SUCCESS (status) if) {}} else {// if we cant allocate the space, we return the corresponding code error status = STATUS_INSUFFICIENT_RESOURCES;!} if (ipFileObject = NULL ) ObdereferenceObject; ipfileObject = null; ipDeviceObject = null;} Else Return status;} // The true filter function is this, which is passed in the earliest IrpDisPatch. // This function is something that the system passes a cladding and package content and packet length. You can do some processing, // If you want this package, return pf_forward, or you don't want to make the package If you return to PF_D ROP, you will stop it.
// Is not It sounds simple, PF_FORWARD_ACTION cbFilterFunction (IN unsigned char * PacketHeader, IN unsigned char * Packet, IN unsigned int PacketLength, IN unsigned int RecvInterfaceIndex, IN unsigned int SendInterfaceIndex, IN unsigned long RecvLinkNextHop, IN unsigned long SendLinkNextHop) { Ippacket * ipp; TCPHEADER * TCPH; udpheader * udph; int countRule = 0; struct filterlist * aux = first; // We "extract" The ip header ipp = (ippacket *) PacketHeader; // Dprintf ("Source:% x / ndestination:% x / nprotocol:% d ", IPP-> ipSource, IPP-> ipdestination, ipp-> ipprotocol); // TCP -> protocol = 6 // We accept all packets of established connections if (ipp-> ipprotocol == 6) {TCPH = (TCPHEADER *) Packet; // Dprintf ("Flags:% x / n", tcph-> flags); // if we havent the bit syn activate, we pass the packets if (! (TCPH-> FLAGS & 0X02)) Return Pf_forward;} // OtherWise, We Compare the Packet with our rules while (aux! = null) {// Dprintf ("Comparing with rule% d", countrule; // if Protocol is the Same .... IF (aux-> ipf.prot Ocol == 0 || ipp-> ipprotocol == aux-> ipf.protocol) {// WE LOOK IN SOURCE Address IF (AUX-> ipf.sourceIP! = 0 && (ipp-> ipsource & aux-> ipf. SourceMask! = aux-> ipf.sourceIP) {aux = aux-> next; countrule ; contract;} // we look in destination address if (aux-> ipf.destinationip! = 0 && (ipp-> ipdestination & aux -> ipf.destinationmask! = aux-> ipf.destinationip {aux = aux-> next; countrule ; continue;} // if we have a tcp packet, we look in ports // TCP, protocol = 6 IF ( IPP->
ipprotocol == 6) {if (aux-> ipf.sourcePort == 0 || TCPH-> Sourceport == aux-> ipf.sourceport) {if (aux-> ipf.destinationport == 0 || TCPH-> DestinationPort == aux-> ipf.destinationport) // puerto tcp de do do with the packet if (aux-> ipf.drop) Return PF_DROP; Else Return Pf_forward;}}} // UDP, Protocol = 17 else if (ipp-> ipprotocol == 17) {udph = (udpheader *) packet; if (aux-> ipf.sourcePort == 0 || UDPH-> Sourceport == aux-> ipf.sourceport) {if (AUX-> ipf.destinationport == 0 || UDPH-> DestinationPort == AUX-> ipf.destinationport) {// now we decided what to do with the packet if (aux-> ipf.drop) Return PF_DROP; ELSE Return Pf_forward;}}} else {// for Other Packet We DONT LOOK More and .... // Now We Decided What to do with the packet if (aux-> ipf.drop) Return PF_DROP; Else Return PF_FORWARD;} } // Compare with the next rule countrule ; aux = aux-> next;} // we accept all NOT Registered Return Pf_forward;} WinPCAP is also used by NDIS, registering yourself as an protocol processed drive. (I can see in the driverentry of the original code): The filter section of this drvipflt this code doesn't know if everyone looks familiar, yes, it is a package filter in the name of the Nu mege driver development package. It seems that foreigners also like to copy everywhere. Ruike: It is special to have a unique closure for WinPCAP, which is really easy to use, but it is really annoying, it is also a deadly defect that is only available for shared Ethernet, For data under exchanging networks, I don't have testing. I have been testing. Under the LAN for use, I can only listen to the data within this network segment, and I can't listen for data from other network segments, unless you put PROBE is connected to the switch before the switch is connected to the switch's console, but that's it is obvious.
Therefore, WinPCAP's application is still very limited! Kingzai: There are also many ways to implement the switching network 1. Place your captains on the gateway or proxy server, which caught the entire LAN. 2. For the switch to implement port mapping, map all the packets of the port to a monitoring machine. 3. Connect a HUB between the switch and the router, so that the data will be sent in a broadcast manner. 4. Implement ARP spoof, that is, the forwarding of the entire package is achieved on your machine, but it will reduce the efficiency of the entire local area network. Warton: Sniffing Countermeasures: Light Sniffing, I talk about the anti-sniffing:) 1. Check if the network card is set to a mixed mode (there are many tools to do, AntiSniff, Promiscan, S Entinel Wait) 2. Switching network sniffer (ARP spoof) such as ETTERCAP, can use the method of preventing ARP spoofing to treat 3.SSH encryption channel 4.ssl5.vpn6.pgp, etc., using NIC mixed mode Sniffer's software seems not much, so you should consider the feasible approach to switched networks: Mac flooding, mac duplicating, arp spoof, etc. It is not easy, welcome to provide interest in providing relevant information ,Ha ha! Netsys: Does anyone have used Raw Socket? Although the WinPCP is very large, Raw Socket allows you to directly Socket's native mechanism. In fact, the two issues I mention are very easy to solve. . Netsys2: For some of the mixed mode Sniffer, most of which use the way a special ARP package, the correct NIC does not respond, and the NIC in the mixed mode will respond. Of course, the ARP and IP are in the same level, so you can't complete it with Raw Socket, you need WinPCAP support work.
The following is a part of the code AnsiString msgStatus; extern TArpFuncParam wParams; int BuildARPPacket (PArpPacket ArpPacket, unsigned char * dst_etheraddr, unsigned char * src_etheraddr, int ar_op, unsigned char * ar_sha, unsigned char * ar_sip, unsigned char * ar_tha, unsigned char * ar_tip, unsigned short int ar_hw) {memcpy (& (ArpPacket-> eth_dst_addr), dst_etheraddr, ETH_ADD_LEN); memcpy (& (ArpPacket-> eth_src_addr), src_etheraddr, ETH_ADD_LEN); ArpPacket-> eth_type = htons (ETH_TYPE_ARP); ArpPacket-> ar_hrd = htons (ar_hw); ArpPacket-> ar_pro = htons (ARP_PRO_IP); ArpPacket-> ar_hln = ARP_ETH_ADD_SPACE; ArpPacket-> ar_pln = ARP_IP_ADD_SPACE; ArpPacket-> ar_op = htons (ar_op); memcpy (& (ArpPacket-> ar_sha), ar_sha, ARP_ETH_ADD_SPACE); memcpy (& (ArpPacket-> ar_spa), ar_sip, ARP_IP_ADD_SPACE); memcpy (& (ArpPacket-> ar_tha), ar_tha, ARP_ETH_ADD_SPACE); memcpy (& (ArpPacket-> ar_tpa), ar_tip, ARP_IP_ADD_SPACE); MEMSET (Arppacket-> Eth_Pad, 32, Eth_Padding_arp); Return (exit_success);} int openad apter (LPADAPTER * lpAdapter) {* lpAdapter = PacketOpenAdapter (wParams.AdapterList [wParams.SelectedAdapter]); if ((* lpAdapter) || ((* lpAdapter) -> hFile == INVALID_HANDLE_VALUE)!) {msgStatus = "Error: unable to open the driver ";. SHOWSTAT (msgStatus); return (EXIT_FAILURE);} return (EXIT_SUCCESS);} void CloseAdapter (lPADAPTER lpAdapter) {PacketCloseAdapter (lpAdapter);} void GetLocalMAC (lPADAPTER lpAdapter, unsigned char * ether_addr) { Ulong ioctlbufferLength = (SIZEOF (Packet_oid_data) SizeOf (Ulong) - 1); PPACKET_OID_DATA OIDDATA; OIDDATA = (Struct _Packet_OID_DATA *) Malloc (IOCTLBUFFERLENGTH);
OidData-> Oid = OID_802_3_CURRENT_ADDRESS; OidData-> Length = 6; if (PacketRequest (lpAdapter, FALSE, OidData) == FALSE) memcpy (ether_addr, 0, 6); else memcpy (ether_addr, OidData-> Data, 6); free (OidData);} int GetARPReply (lPPACKET lpPacket, unsigned char * iptarget, unsigned char * result) {unsigned short int ether_type; unsigned char ipsender [4]; unsigned int off = 0; unsigned int tlen; struct bpf_hdr * hdr; Char * pchar; char * buf; buf = (char *) lppacket-> buffer; hdr = (struct bpf_hdr *) (buf OFF); tlen = hdr-> bh_caplen; off = HDR-> BH_HDRLEN; PCHAR = ( char *) (buf off); off = Packet_WORDALIGN (off tlen); memcpy (& ether_type, pChar 12, 2); ether_type = ntohs (ether_type); if (ether_type == ETH_TYPE_ARP) {memcpy (ipsender, pChar 28, 4); IF (iptarget [0] == ipsender [0]) && (iptarget [1] == ipsender [1]) && (iptarget [2] == ipsender [2]) & (iptarget [3 ] == ipsender [3])) Memcpy (Result, PCHAR 22, 6); else return (EXIT_FAILURE);} else return (EXIT_FAILURE); return (EXIT_SUCCESS);} int CheckPROMode (LPADAPTER lpAdapter, unsigned char * iptarget, unsigned char * remotemac) {LPPACKET lpPacketRequest; LPPACKET lpPacketReply; char buffer [256000] ; TArpPacket ArpPacket; unsigned char magicpack [ETH_ADD_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE}; unsigned char mactarget [ARP_ETH_ADD_SPACE]; DWORD timestamp = 0; int numPacks = 0; / * Init fields * / memset ( MacTarget, 0, 6);
/ * Allocate PACKET structure for ARP Request packet * / if ((lpPacketRequest = PacketAllocatePacket ()) == NULL) {msgStatus = "Error: failed to allocate the LPPACKET structure .."; SHOWSTAT (msgStatus); return (EXIT_FAILURE); } / * Init packet structure * / memset (& ArpPacket, 0, sizeof (TArpPacket)); / * Build ARP Request packet * / BuildARPPacket (& ArpPacket, magicpack, wParams.srcMAC, ARP_OP_REQUEST, wParams.srcMAC, wParams.srcIPAdd, mactarget, iptarget, wParams.ar_hw); / * Init ARP Request packet * / PacketInitPacket (lpPacketRequest, & ArpPacket, sizeof (ArpPacket)); / * Set number of ARP Request packets to send * / if (PacketSetNumWrites (lpAdapter, 1) == FALSE ) {msgStatus = "Warning: unable to send more than one packet in a single write .."; SHOWSTAT (msgStatus);} / * Set hardware filter to directed mode * / if (PacketSetHwFilter (lpAdapter, NDIS_PACKET_TYPE_DIRECTED) == FALSE) {MsgStatus = "Warning: unable to set directed mode .."; showstat (msgstatus);} / * Set a 512K buffer in the driver * / if (PacketSetBuff (lpAdapter, 512000) == FALSE) {msgStatus = "Error: unable to set the kernel buffer .."; SHOWSTAT (msgStatus); PacketFreePacket (lpPacketRequest); return (EXIT_FAILURE );} / * SET A 1 Second Read Timeout * / if (PacketsetReadTimeout (LPADAPTER, -1) == false) {msgstatus = "WARNING: Unable to set the read tiemout .."; showstat (msgstatus);} / * Allocate Packet Structure for ARP Reply Packet * / IF ((LPPACKETREPLY = PacketAllocatePacket ()) == NULL) {msgstatus = "Error: failed to allocate the lppacket structure ..";
SHOWSTAT (msgStatus); PacketFreePacket (lpPacketRequest); return (EXIT_FAILURE);} / * Init ARP Reply packet * / PacketInitPacket (lpPacketReply, (char *) buffer, 256000); / * Allocate memory for remote MAC address * / timestamp = GetTickCount (); / * Main capture loop * / for (;;) {if (Numpacks
As for the ADSL Cable FTTB, my fttb is the equipment designed by Huawei, huh, but not only IP IP, only I and the switch two Mac (this time the Chinese is doing well), I don't want to find a third party, very safe, But it is not true, many people's networks are still very bad. Many encryption protocols can be used to improve security, but old POP3, SMTP, HTTP, FTP this protocol is widely used, and it is impossible to completely replace it in a short time. And encryption is also to be price, so for the high-aspiration, it will be encrypted. However, Sniffer is not to steal the password. I used to learn the network, look at the package, and later used as a network management tool , Analyze the health of the network, in fact, you know, you know, very likely Sniffer is on the network I need to detect, the stethoscope, listen everywhere, huh, so I use the switch, Sniffer is still useful , But not caught the password !! WinCap is simple, big 3 students don't be afraid, go to his website to see, have examples, VC6 compilation, BCB is also line, conversion of lib format, but write this program You'd better be familiar with the agreement first, many agreements have ready-made source code in Linux, mainly Struct, pay attention to the VC is not GCC, some C's advanced grammar, the compilation option should be noted, otherwise a Byte you will Do not get the right result. If you can't get the Sniffer, Win2000 Server also has a network package viewer, not strong than Sniffer, but simple things will start. The anti-sniffing and sniffing technology is actually very old, huh, but 9CBS is often Old. Be careful not to do bad things, there is a spear must have Shield sevencat: The mixed mode of the NIC seems to be set by NDIS. The following is a repost. Which UP is coming, I will pass it. A drive Open Source Author: gjpland see packet interception technology provides a lot of my dear friend, is where most of the preparation IM DRIVER NDIS intermediate layer of data packets between MINIPORT (NIC driver) and protocol drivers intercept. This is a technology provided by Microsoft but writing the filter interceptor is very complicated, and the installation is very troublesome. I briefly introduce a more efficient NDIS package intercept technology. Everyone knows that the NDIS protocol driver is to fill in a table of NDIS_PROTOCOL_CHARACTERISTICS and call NDIS API functions NDISREGisterProtocol for registration. Now let's pay attention to the table of NDIS_PROTOCOL_CHARACTERI stics, which exists in this table with the entry of all protocol drivers and underlying distribution functions. As SendHandler, ReceiveHandler, Bi NdadapterHandler, etc. When the network card has packet entry, it will pass through the table of the ReceiveHandle or the ReceivePacketHandler Notification Protocol Driver to enter, and the protocol driver is driven by the sendhandler or sendPacketshandler function. If you send a packet to the network, someone will strange programs not to call NDISSEND or NDISSENDPACKETS functions? Yes, this, but you can look at the definition of these two functions in Ndis.h's header files, they are all macro definitions, actually sent by SendHandler or SendPacketsHandler through this table. What we have to do now should be very clear, as long as we point the distribution function in the NDIS_PROTOCO L_CHARACTERISTICTICS table filled in each protocol program to its own function, we can successfully intercept the packet. So what is the table of each protocol driver? Too simple, look at the prototypes rendered by NDISREGISTERPROTOCOL.
struct _NDIS_PROTOCOL_BLOCK {PNDIS_OPEN_BLOCK OpenQueue; // queue of opens for this protocol REFERENCE Ref; // contains spinlock for OpenQueue UINT Length; // of this NDIS_PROTOCOL_BLOCK struct NDIS50_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics; // handler addresses struct _NDIS_PROTOCOL_BLOCK * NextProtocol; // Link to next ULONG MaxPatternSize; #if defined (NDIS_WRAPPER) // // Protocol filters // struct _NDIS_PROTOCOL_FILTER * ProtocolFilter [NdisMediumMax 1]; WORK_QUEUE_ITEM WorkItem; // Used during NdisRegisterProtocol to // notify protocols of existing drivers KMUTEX Mutex;. // For serialization of Bind / Unbind requests PKEVENT DeregEvent; // Used by NdisDeregisterProtocol #endif}; typedef struct _NDIS_PROTOCOL_BLOCK NDIS_PROTOCOL_BLOCK, * PNDIS_PROTOCOL_BLOCK; EXPORT VOID NdisRegisterProtocol (OUT PNDIS_STATUS Status, OUT PNDIS_PROTOCOL_BLOCK NdisProtocolHandle, / * note NDIS_HANDLE points PNDIS_PROTOCOL_BLOCK structure is not What is doubt? * / In pndis_protocol_characteristics protocolcharacteristic s, in uint characteristics; NDIS_PROTOCOL_BLOCK (protocol table) is NDIS to maintain a one-way link table that has been registered in all systems. Field NextProtocol points to the next protocol table. Fortunately, when we register a new agreement, NDIS always puts the newly registered Acjunctions on the header of the list and returns this table, so as long as we register a new protocol to register the list of returned linked tables You can easily traverse all protocol tables in the system. Now we hope to get the NDIS_PROTOCOL_CHARACTERISTICSTICS in front of us, how to hook the distribution function in the hanging table, I don't want to say more. By the way, NDISREGISTERPROTOCOL assigned by NDIS_PROTOCOL_BLOCK is NonPagedPool type. For core Driver, the core area memory is a linear memory area, and all core Driver is any address that can access the core memory area. What should be noted is that the pagination and non-paged memory are different from the IRQL level. Will someone will ask this way? Do you really intercept? If there is anything that the people are eager to write the program, they will be disappointed, because he will find what the results are not intercepted or even intercept some packets. why? Because the NDIS network driver and protocol driver is not called pNDIS_OPEN_BLOCK-> Proto colcharacteristics when sending and receiving a counting time.
How to do? It is necessary to introduce how binding between NDIS NIC drivers and protocol drivers, NDisRegisterProtocol After registering a protocol, NDIS will send functions to the table BindAdaPterHandler by calling tables, and notify the protocol to make Binding for each network card. Or when the system passes PNP to find a new network card, BindAdapterHandler will also call the protocol to Binding. In the binding call, the agreement will use NDisopenadapter to use NDisopenadapter to use NDisopenadapter to use NDisopenadapter to bind itself to the appropriate NIC. And return ndisbindinghandle.ndisbindingHandle? Ndisbin DingHandl actually points a pointer to the NDIS_OPEN_BLOCK table, then what is the use of the ndis_open_block table? When the protocol is committed, the channel transmitted channel is established between each bound network card and each protocol, and NDIS_OPEN_BLOCK is used to maintain this data channel.
struct _NDIS_OPEN_BLOCK {PNDIS_MAC_BLOCK MacHandle; // pointer to our MAC NDIS_HANDLE MacBindingHandle; // context when calling MacXX funcs PNDIS_ADAPTER_BLOCK AdapterHandle; // pointer to our adapter PNDIS_PROTOCOL_BLOCK ProtocolHandle; // pointer to our protocol NDIS_HANDLE ProtocolBindingContext; // context when calling ProtXX funcs PNDIS_OPEN_BLOCK AdapterNextOpen; // used by adapter's OpenQueue PNDIS_OPEN_BLOCK ProtocolNextOpen; // used by protocol's OpenQueue PFILE_OBJECT FileObject; // created by operating system BOOLEAN Closing; // TRUE when removing this struct BOOLEAN Unloading; // TRUE when processing unload BOOLEAN NoProtRsvdOnRcvPkt; / / Reflect the protocol_options NDIS_HANDLE CloseRequestHandle; // 0 indicates an internal close KSPIN_LOCK SpinLock; // guards Closing PNDIS_OPEN_BLOCK NextGlobalOpen; // // These are optimizations for getting to MAC routines They are not // necessary, but are here to save a. Dereference Through The Mac Block. // Send_Handler SendHandler; Tr ANSFER_DATA_HANDLER TransferDataHandler; // // These are optimizations for getting to PROTOCOL routines They are not // necessary, but are here to save a dereference through the PROTOCOL block // SEND_COMPLETE_HANDLER SendCompleteHandler;.. TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler; RECEIVE_HANDLER ReceiveHandler; RECEIVE_COMPLETE_HANDLER ReceiveCompleteHandler; / / // Extentions to the OPEN_BLOCK since Product 1. // RECEIVE_HANDLER PostNt31ReceiveHandler; RECEIVE_COMPLETE_HANDLER PostNt31ReceiveCompleteHandler; // // NDIS 4.0 extensions // RECEIVE_PACKET_HANDLER ReceivePacketHandler; SEND_PACKETS_HANDLER SendPacketsHandler; // // More NDIS 3.0 Cached Handlers // RESET_HANDLER ResetHandler;
Request_Handler Requesthandler; /////////////////////////////// Upcased name of the adapter we are bound to}; The above table structure can be clearly seen that this table is a one-way linked table and stores The same data transceiver distribution function as Pndis_Open_Block-> ProtocolCharacteristics, when the N-block is sent to the nth protocol, the NDIS_OPEN_BLOCK table created between the NDIS_OPEN_BLOCK table is called between the NDIS_OPEN_BLOCK table or the NDIS_OPEN_BLOCK table. SendpacketHandler. So we also need to process the distribution function in this table (hook). So how do you hook the NDIS_OPEN_BLOCK table between the protocol and the NIC. Let's go back to NDIS_PROTOCOL_ Block this table, in the NDIS_PROTOCOL_BLOCK table in the ndis_protocol_block OpenQueue; is the header of all the NDIS_OPEN_BLOCK of this protocol. Traverse it through AdapterNextopen, and then hook it. It can be intercepted smoothly. It is worth noting. 1. NDIS_OPEN_BLOCK NDIS_PIS_OPEN_BLOCK These structures Different NDIS versions are different, and the solution is under Windows 98 and Windows 95 (NDIS 3.1) using the definition of Ndis.h in Windows98DDK, under Windows Me (NDIS 5.0 or 4.0) Please use Windows 98DDK Definition in ndis.h NT (NDIS4.0) in NTDDK is expressed in this class, 2000 (NDIS5.0) 2. Do not repeat the hook the same function.
If you have any questions, you can pass QQ: 3955727 mail: gjpland@netese.com //// Protocol Wrapper Version 1.05 // Author: gjp // email: gjpland@netese.com///include "ndishook.h" #include "hookrule. h "#pragma pack (push) #pragma pack (1) typedef struct _HOOK_CONTEXT_STRUCT {// runtime code ubyte code1_0x58; // 0x58 | pop eax | pop caller IP from stack to eax ubyte code2_0x68; // 0x68 | push IMM | push our hook context address struct _HOOK_CONTEXT_STRUCT * m_pHookContext; // point this ubyte code3_0x50; // 0x50 | push eax | push caller IP from eax to stack ubyte code4_0xE9; // 0xE9 | jmp HookProc | jump our hook proc udword m_pHookProcOffset; // our context data PVOID m_pOriginalProc; PVOID m_pHookProc; PVOID m_pBindAdaptHandle; PVOID m_pProtocolContent; PVOID * m_ppOriginPtr; struct _HOOK_CONTEXT_STRUCT * m_pHookNext;} HOOK_CONTEXT_STRUCT; #pragma pack (pop) HOOK_CONTEXT_STRUCT * m_pOurAllOfHookContext = NULL; dword m_IsFilterEnabled = FALSE; NDIS_HANDLE m_ourPacketPoolHandle = NULL; NDIS_HANDLE m_ourBufferPoolHandle = NULL; PNDIS_PACKET m_ourPacketHandle = NULL; PNDIS_BUFFER m_ourBufferHandle = NULL; PVOID m_ourBuffer = NULL; void ReadPacket (PNDIS_PACKET Packet, PVOID pBuffer, udword dwBufSize); uword wswap (uword value); void HookUnload (void) {ReleaseHookFunc ( ); if (m_ourBufferHandle) {NdisFreeBuffer (m_ourBufferHandle); m_ourBufferHandle = NULL;} if (m_ourBuffer) {NdisFreeMemory (m_ourBuffer, MAX_PACKET_SIZE, 0); m_ourBuffer = NULL;} if (m_ourPacketHandle) {NdisFreePacket (m_ourPacketHandle); m_ourPacketHandle = NULL; } If (m_ourbufferpoolhandle) {ndisfreebufferpool (m_ourbufferpoolhandle);
m_ourBufferPoolHandle = NULL;} if (m_ourPacketPoolHandle) {NdisFreePacketPool (m_ourPacketPoolHandle); m_ourPacketPoolHandle = NULL;} return;} dword HookInit (void) {NTSTATUS status; m_ourPacketPoolHandle = NULL; NdisAllocatePacketPool (& status, & m_ourPacketPoolHandle, 0xFFF, 0x10); if (status ! = NDIS_STATUS_SUCCESS) return FALSE; m_ourBufferPoolHandle = NULL; NdisAllocateBufferPool (& status, & m_ourBufferPoolHandle, 0x10);! if (status = NDIS_STATUS_SUCCESS) return FALSE; m_ourBuffer = NULL; status = NdisAllocateMemoryWithTag (& m_ourBuffer, MAX_PACKET_SIZE, 'NAMW'); if (status ! = NDIS_STATUS_SUCCESS) return FALSE; m_ourBufferHandle = NULL; NdisAllocateBuffer (& status, & m_ourBufferHandle, m_ourBufferPoolHandle, m_ourBuff er, MAX_PACKET_SIZE);! if (status = NDIS_STATUS_SUCCESS) return FALSE; m_ourPacketHandle = NULL; NdisAllocatePacket (& status, & m_ourPacketHandle, m_ourPacketPoolHandle); if ( Status! = ndis_status_success) Return False; NdischainBufferatFront (M_OrpacketHandle, M_ou rBufferHandle); return TRUE;} typedef struct _NDIS41_PROTOCOL_CHARACTERISTICS {#ifdef __cplusplus NDIS40_PROTOCOL_CHARACTERISTICS Ndis40Chars; #else NDIS40_PROTOCOL_CHARACTERISTICS; #endif // // Start of NDIS 4.1 extensions // CO_SEND_COMPLETE_HANDLER CoSendCompleteHandler;. CO_STATUS_HANDLER CoStatusHandler; CO_RECEIVE_PACKET_HANDLER CoReceivePacketHandler; CO_REQUEST_HANDLER CoRequestHandler; CO_REQUEST_COMPLETE_HANDLER CoRequestCompleteHandler; } Ndis41_protocol_characteristics; DWORD HOOKPROTOCOL (VOID) {// default ndis version is 5.0 ndis_protocol_characteristics outpc; ndis_string protoname = ndis_string_const ("
HdFw_Slot "); NDIS_STATUS Status; NDIS_HANDLE ourProtocolHandle = NULL; byte * ProtocolChain; dword offset; dword len; // NDIS_PROTOCOL_BLOCK * pNdisBlock = NULL; // pNdisBlock = pNdisBlock-> NextProtocol; // pNdisBlock-> NextProtocol = NULL; memset ( & ourNPC, 0, sizeof (NDIS_PROTOCOL_CHARACTERISTICS)); if (m_dwMajorVersion == 0x03) {len = sizeof (NDIS30_PROTOCOL_CHARACTERISTICS); // We must need at least ndis version 3.10 ourNPC.MajorNdisVersion = 0x03; ourNPC.MinorNdisVersion = 0x0A;} else if (m_dwMajorVersion == 0x04) {len = sizeof (NDIS40_PROTOCOL_CHARACTERISTICS); ourNPC.MajorNdisVersion = 0x04; ourNPC.MinorNdisVersion = 0x00;} else {// treat as version 5.0 len = sizeof (NDIS50_PROTOCOL_CHARACTERISTICS); ourNPC.MajorNdisVersion = 0x05; ourNPC. MinorNdisVersion = 0x00;} ourNPC.Name = protoName; ourNPC.OpenAdapterCompleteHandler = PtOpenAdapterComplete; ourNPC.CloseAdapterCompleteHandler = PtCloseAdapterComplete; ourNPC.SendCompleteHandl er = PtSendComplete; ourNPC.TransferDataCompleteHandler = PtTransferDataComplete; ourNPC.ResetCompleteHandler = PtResetComplete; ourNPC.RequestCompleteHandler = PtRequestComplete; ourNPC.ReceiveHandler = PtReceive; ourNPC.ReceiveCompleteHandler = PtReceiveComplete; ourNPC.StatusHandler = PtStatus; ourNPC.StatusCompleteHandler = PtStatusComplete; ourNPC.BindAdapterHandler = PTBINDADAPTER; outpc.unbindadapterHandler = ptunbindadapter; outpc.unloadhandler = ptunload;
ourNPC.ReceivePacketHandler = PtReceivePacket; ourNPC.PnPEventHandler = PtPNPHandler; NdisRegisterProtocol (& Status, & ourProtocolHandle, & ourNPC, len); if (NT_SUCCESS (Status) || ourProtocolHandle == NULL!) return FALSE; // NdisRegisterProtocol return hand reference of NDIS_PROTOCOL_BLOCK; ProtocolChain = (byte *) ourProtocolHandle; while (1) {DebugInfoCount ; // Obtain pointer to next protocol link if (m_dwMajorVersion == 0x03) offset = 4;. else if (m_dwMajorVersion == 0x04) {if (m_dwMinorVersion == 0x01) offset = 0x8C; else offset = 0x60;} else if (m_dwMajorVersion == 0x05) // NDIS_PROTOCOL_BLOCK-> NextProtocol offset = 0x10; else // Error break; ProtocolChain = ((byte **) (ProtocolChain offset)) [0 ]; if (ProtocolChain == NULL) break; HookFuncBlock (ProtocolChain);} if (! m_dwMajorVersion = 4) NdisDeregisterProtocol (& Status, ourProtocolHandle); else {// ((byte *) ourProtocolHandle) [0x0C] = 0x01; // NDISDEREGISTERPROTOCOL & Status, ourProtocolHandle);} return TRUE;} // ProtocolContent // Version NextChain offset NDIS_PROTOCOL_CHARACTERISTICS offset BindingAdaptHandle offset // NDIS 3.XX 0x04 0x14 0x08 // NDIS 4.XX 0x60 0x14 0x00 // NDIS 4.01 0x8C 0x14 0x00 // NDIS 5.xx 0x10 0x14 0x00 / / ----- Void HookProtocolsendPackets (in hook_context_struct * pourContext, in ndis_handle miniportadaptercontext, in ppndis_packet packetarray, in uint numberofpackets);
NDIS_STATUS HookProtocolWanSend (IN HOOK_CONTEXT_STRUCT * pOurContext, IN NDIS_HANDLE MacBindingHandle, IN NDIS_HANDLE LinkHandle, IN PVOID Packet); NDIS_STATUS HookProtocolSend (IN HOOK_CONTEXT_STRUCT * pOurContext, IN NDIS_HANDLE MacBindingHandle, IN PNDIS_PACKET Packet); NDIS_STATUS HookProtocolReceive (IN HOOK_CONTEXT_STRUCT * pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookaheadBufferSize, IN UINT PacketSize); NDIS_STATUS HookWanReceive (IN HOOK_CONTEXT_STRUCT * pOurContext, IN NDIS_HANDLE NdisLinkHandle, IN PUCHAR Packet, IN ULONG PacketSize); INT HookProtocolReceivePacket (IN Hook_context_struct * pourcontext, in ndis_handle protocolbindingcontext, in pndis_packet packet; void hookbindadapterhandler (in HOOK_CONTEXT_STRUCT * pOurContext, OUT PNDIS_STATUS Status, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2); VOID HookSendComplete (IN HOOK_CONTEXT_STRUCT * pOurContext, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status); void ReleaseHookFunc (void ) {HOOK_CONTEXT_STRUCT * pHookContext, * pNext; pHookContext = m_pOurAllOfHookContext; m_pOurAllOfHookContext = NULL; while (pHookContext) {pNext = pHookContext-> m_pHookNext; pHookContext-> m_ppOriginPtr [0] = pHookContext-> m_pOriginalProc; ExFreePool (pHookContext); pHookContext = pNext ;
} Return;} HOOK_CONTEXT_STRUCT * IsHookedNdisFunc (PVOID pAddr) {HOOK_CONTEXT_STRUCT * pHookContext; pHookContext = m_pOurAllOfHookContext; while (pHookContext) {if (pHookContext == pAddr) break; pHookContext = pHookContext-> m_pHookNext;} return pHookContext;} HOOK_CONTEXT_STRUCT * IsHookedNdisFuncEx ( PVOID * pAddr) {HOOK_CONTEXT_STRUCT * pHookContext; pHookContext = m_pOurAllOfHookContext; while (pHookContext) {if (pHookContext-> m_ppOriginPtr == pAddr) break; pHookContext = pHookContext-> m_pHookNext;} return pHookContext;} HOOK_CONTEXT_STRUCT * HookNdisFunc (PVOID pHookProc, PVOID * ppOrigProc, PVOID pBindAdaptHandle, PVOID pProtocolContent) {HOOK_CONTEXT_STRUCT * pHookContext; PVOID OrgFunc; pHookContext = IsHookedNdisFunc (ppOrigProc [0]); if (pHookContext) OrgFunc = pHookContext-> m_pOriginalProc; else OrgFunc = ppOrigProc [0]; if (OrgFunc = = NULL) RETURN NULL; PhookContext = IshookedndisfunceX (PPORIGPROC); if (PhoOKContext) Return PhookContext; PhoOKContext = ExallocatePo olWithTag (NonPagedPool, sizeof (HOOK_CONTEXT_STRUCT), 'HCSP'); if (pHookContext == NULL) return NULL; memset (pHookContext, 0, sizeof (HOOK_CONTEXT_STRUCT)); pHookContext-> code1_0x58 = 0x58; pHookContext-> code2_0x68 = 0x68; pHookContext-> code3_0x50 = 0x50; pHookContext-> code4_0xE9 = 0xE9; pHookContext-> m_pHookContext = pHookContext; pHookContext-> m_pHookProcOffset = ((udword) pHookProc) - (((udword) & pHookContext-> m_pHookProcOffset) sizeof (udword)); PhookContext-> m_pbindadapthandle = pbindadapthandle; phookcontext-> m_pprotocolcontent = pprotocolcontent; phookcontext->
m_pOriginalProc = OrgFunc; // ppOrigProc [0]; pHookContext-> m_ppOriginPtr = ppOrigProc; pHookContext-> m_pHookProc = pHookProc; pHookContext-> m_pHookNext = m_pOurAllOfHookContext; m_pOurAllOfHookContext = pHookContext; ppOrigProc [0] = pHookContext; return pHookContext;} typedef struct _NDIS40_OPEN_BLOCK {PNDIS_MAC_BLOCK MacHandle; // pointer to our MAC NDIS_HANDLE MacBindingHandle; // context when calling MacXX funcs PNDIS_ADAPTER_BLOCK AdapterHandle; // pointer to our adapter PNDIS_PROTOCOL_BLOCK ProtocolHandle; // pointer to our protocol NDIS_HANDLE ProtocolBindingContext; // context when calling ProtXX funcs PNDIS_OPEN_BLOCK AdapterNextOpen ; // used by adapter's OpenQueue PNDIS_OPEN_BLOCK ProtocolNextOpen; // used by protocol's OpenQueue PFILE_OBJECT FileObject; // created by operating system BOOLEAN Closing; // TRUE when removing this struct BOOLEAN Unloading; // TRUE when processing unload NDIS_HANDLE Clo seRequestHandle; // 0 indicates an internal close KSPIN_LOCK SpinLock; // guards Closing PNDIS_OPEN_BLOCK NextGlobalOpen;. // // These are optimizations for getting to MAC routines They are not // necessary, but are here to save a dereference through the MAC block . // SEND_HANDLER SendHandler; TRANSFER_DATA_HANDLER TransferDataHandler; // // These are optimizations for getting to PROTOCOL routines They are not // necessary, but are here to save a dereference through the PROTOCOL block // SEND_COMPLETE_HANDLER SendCompleteHandler;.. TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler; RECEIVE_HANDLER ReceiveHandler; Receive_Complete_Handler ReceiveCompleteHandler;
// // Extentions to the OPEN_BLOCK since Product 1. // RECEIVE_HANDLER PostNt31ReceiveHandler; RECEIVE_COMPLETE_HANDLER PostNt31ReceiveCompleteHandler; // // NDIS 4.0 extensions // RECEIVE_PACKET_HANDLER ReceivePacketHandler; SEND_PACKETS_HANDLER SendPacketsHandler; // // Needed for PnP // UNICODE_STRING AdapterName; // Upcased name of the adapter we are bound to} NDIS40_OPEN_BLOCK, * PNDIS40_OPEN_BLOCK; void HookFuncBlock (byte * ProtocolContent) {PNDIS_PROTOCOL_CHARACTERISTICS pProChar; dword IsWan; NDIS_STRING WanString = NDIS_STRING_CONST ( "NDISWAN"); NDIS_STRING DeviceWanString = NDIS_STRING_CONST ( "file: // DEVICE / / NDISWAN "); NDIS_STRING TcpipString = NDIS_STRING_CONST (" Tcpip "); NDIS_STRING TcpArpString = NDIS_STRING_CONST (" TCPIP_WANARP "); NDIS_STRING RasArpString = NDIS_STRING_CONST (" RASARP "); if (ProtocolContent == NULL) return; // Get pointer to NDIS_PROTOCOL_CHARACTERISTICS From protocol content pprochar = (pndis_protocol_characteristics) (Protocolcon) tent 0x14); if (KeGetCurrentIrql () == PASSIVE_LEVEL) {// Check protocol name whether is Wan Lan protocol so that we can correctly hook our function if (RtlCompareUnicodeString (& pProChar-> Name, & WanString, TRUE!) ||! RtlCompareUnicodeString (& pProChar-> Name, & DeviceWanString, TRUE)) {IsWan = 1;} else IsWan = 0; // We r only interest in following protocol if ((RtlCompareUnicodeString (& pProChar-> Name, & TcpipString, TRUE) ||!! RTLcompareunicodestring (& PPROCHAR-> Name, & tcparpstring, true) ||! RtlcompareunicodeString (& PPROCHAR-> Name, & Rasarpstring, true))) {return;
}} Else IsWan = 0; // if (IsWan!) {HookNdisFunc (HookProtocolReceive, (PVOID *) & pProChar-> ReceiveHandler, NULL, ProtocolContent); // {{added by gjp 6.24 // __asm int 3; // HookNdisFunc (HookSendComplete, (PVOID *) & pProChar-> SendCompleteHandler, NULL, ProtocolContent); //}}} else HookNdisFunc (HookWanReceive, (PVOID *) & pProChar-> WanReceiveHandler, NULL, ProtocolContent); if (pProChar-> MajorNdisVersion> 0x03) {HookNdisFunc (HookProtocolReceivePacket, (PVOID *) & pProChar-> ReceivePacketHandler, NULL, ProtocolContent); HookNdisFunc (HookBindAdapterHandler, (PVOID *) & pProChar-> BindAdapterHandler, NULL, ProtocolContent);} zihan: Guniffer I did modify implemented thread, It is also better. It is BCB made // --------------------------------------- ------------------------------------ #include
} // ----------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------- Void __fastcall tsniffer :: execute () {// ---- Place Thread code Here --- - // Listening IP packets snifferinit (); while (! Terminated) {receivedata ();} form1-> listview1-> additem ("thread end, stop interception ...", 0);} void Tsniffer :: SnifferInit () {// initialization SOCKET WSADATA wsaData; iErrorCode = WSAStartup (MAKEWORD (2,1), & wsaData); CheckSockError (iErrorCode, "WSAStartup"); SockRaw = socket (AF_INET, SOCK_RAW, IPPROTO_IP); CheckSockError (SockRaw, " socket "); // Get the local IP address of the char FAR name [MAX_HOSTNAME_LAN]; iErrorCode = gethostname (name, MAX_HOSTNAME_LAN); CheckSockError (iErrorCode," gethostname "); struct hostent FAR * pHostent; pHostent = (struct hostent *) malloc (sizeof (struct hostent)); pHostent = gethostbyname (name); SOCKADDR_IN sa; sa.sin_family = AF_INET; sa.sin_port = htons (6000); memcpy (& h_addr_list sa.sin_addr.S_un.S_addr, pHostent-> [0] , phostent-> h_length; free (phostent); IrrorCode = Bind (SockRaw, (PSockAddr) & sa, sizeof (sa)); CheckSockError (iErrorCode, "bind"); // set to SOCK_RAW SIO_RCVALL, in order to receive all IP packets LPVOID dwBufferLen [10]; DWORD dwBufferInLen = 1; DWORD dwBytesReturned = 0; iErrorCode = WSAIoctl ( SockRaw, SIO_RCVALL, & dwBufferInLen, sizeof (dwBufferInLen), & dwBufferLen, sizeof (dwBufferLen), & dwBytesReturned, NULL, NULL); CheckSockError (iErrorCode, "Ioctl");} // IP unpack program int TSniffer :: DecodeIpPack (char * buf , int ip_header * pipheader; sockaddr_in sasource, sadest; pipheader = (ip_header *) BUF; // protocol screener iProtocol = pipheader-> proto;
strncpy (szProtocol, CheckProtocol (iProtocol), MAX_PROTO_TEXT_LEN); if ((iProtocol == IPPROTO_TCP) && (MParamTcp)!) return true; if (! (iProtocol == IPPROTO_UDP) && (MParamUdp)) return true; if ((iProtocol == IPPROTO_ICMP) && (MParamIcmp)) return true;! // source address saSource.sin_addr.s_addr = pIpheader-> sourceIP; strncpy (szSourceIP, inet_ntoa (saSource.sin_addr), MAX_ADDR_LEN); if (strFromIpFilter) if (strcmp ( strFromIpFilter, szSourceIP)) return true; // destination address saDest.sin_addr.s_addr = pIpheader-> destIP; strncpy (szDestIP, inet_ntoa (saDest.sin_addr), MAX_ADDR_LEN); if (strDestIpFilter) if (strcmp (strDestIpFilter, szDestIP)) Return true; ittl = pipheader-> ttl; // calculate the length IIPHLEN = SIZEOF (Pipheader-> h_lenver & 0xf); / / According to the protocol type, the corresponding function Switch (iProtocol) { case IPPROTO_TCP: DecodeTcpPack (buf iIphLen, iBufSize); break; case IPPROTO_UDP: DecodeUdpPack (buf iIphLen, iBufSize); break; case IPPROTO_ICMP: DecodeIcmpPack (buf iIphLen, iBufSiz e); Break; default: Break;} Return true;} // protocol identification program char * Tsniffer :: CheckProtocol (int iprotocol) {for (int i = 0; i
/ / If the filter sensitive string determines if the IF (strsnsitive) IF is included ((strstr (tcpdata, strsensitive)) == null) Return true; / / to filter the port isourcePort = NTOHS (ptcpheader-> t_sport); IDestport = NTOHS (PTCPHEADER-> TH_DPORT); IF (iPortFilter) && (isourceport! = iportfilter) && (IDestport! = iportfilter) Return true; // Output // Sprintf (OtherInfo, "% s", szprotocol); // Sprintf (OtherInfo, "% 15S:% 5D ->% 15S:% 5D", SzsourceIP, ISOOOPORT, SZDestip, IDestport); // Sprintf (OtherInfo, "TTL =% 3D", ITTL); ReceiveInfo-> SZProtocol = Szprotocol ; ReceiveInfo-> szSourceIP = szSourceIP; ReceiveInfo-> szDestIP = szDestIP; ReceiveInfo-> iSourcePort = iSourcePort; ReceiveInfo-> iDestPort = iDestPort; ReceiveInfo-> iTTL = iTTL; // Analyzing TCP flag bit unsigned char FlagMask = 1; for ( i = 0; i <6; i ) {if (ptcpheader-> th_flag) & flagmask) {// sprintf (OtherInfo, "% C", tcpflag [i]); ReceiveInfo-> Tcpflag [i] = tcpflag [ I];} else { // Sprintf (OtherInfo, "-"); receiveInfo-> tcpflag [i] = '-';} flagmask = flagmask << 1;} // sprintf (OtherInfo, "Bytes =% 4D / N", IBUFSIZE); ReceiveInfo-> ibufsize = ibufsize; / / For packets greater than 40 bytes (IP_HEADER TCP_HEADER = 40) IF ((ibufsize> 40)) {// analysis TCP data segment IF ((! STRSENSITIVE) || (TCPDATA, STRSENSITIVE)))) {// sprintf (OtherInfo, "[DATA] / N"); // Sprintf (OtherInfo, "% S% S", OtherInfo, TCPDATA);
// sprintf (OtherInfo, "% S / N [Data end] / n / n / n", OtherInfo); ReceiveInfo-> receivedata = tcpdata;}} // form1-> memo1-> lines-> add (OtherInfo) ; AddReceiveData (ReceiveInfo); delete ReceiveInfo; return true;} // UDP unpack program int TSniffer :: DecodeUdpPack (char * UdpBuf, int iBufSize) {UDP_HEADER * pUdpHeader; pUdpHeader = (UDP_HEADER *) UdpBuf; int iSourcePort = ntohs ( pUdpHeader-> uh_sport); int iDestPort = ntohs (pUdpHeader-> uh_dport); RECEIVEINFO * ReceiveInfo = new RECEIVEINFO; // port filter if (iPortFilter) if ((iSourcePort = iPortFilter!) && (iDestPort = iPortFilter!)) Return true; // printf ("% s", szprotocol); // printf ("% 15s:% 5D ->% 15S:% 5D", szsourceip, isourceport, szdestip, idestport); // printf ("TTL = % 3D ", ITTL); // Printf (" LEN =% 4D ", NTOHS (Pudpheader-> UH_LEN); // Printf (" Bytes =% 4D ", IBUFSIZE); // Printf (" / n ") ReceiveInfo-> szprotocol = szprotocol; receiveInfo-> szsourceip = szsourceip; ReceiveInfo-> isourceport = isourceport; ReceiveInfo-> szDestIP = szDestIP; ReceiveInfo-> iDestPort = iDestPort; ReceiveInfo-> iTTL = iTTL; ReceiveInfo-> Length = ntohs (pUdpHeader-> uh_len); ReceiveInfo-> iBufSize = iBufSize; // length greater than 28 bytes for Packet for data analysis (IP_HEADER UDP_HEADER> 28) IF ((ibufsize> 28)) {// printf ("[DATA] / N"); // UDP header length is 8 char * udpdata = udpbuf 8; // Analyze the UDP data segment ReceiveInfo-> receivedata = udpdata; TstringStream * DataStringStream = New TstringStream (null);
try {DataStringStream-> Write (UdpData, sizeof (UdpData)); // DataStringStream-> CopyFrom (UdpData, sizeof (UdpData))} ReceiveInfo-> ReceiveUdpData = DataStringStream-> DataString;} __finally {delete DataStringStream;} for (unsigned INT i = 0; i <(ibufsize-sizeof (udp_header)); i ) {// if (! (i% 8)) Sprintf (OtherInfo, "% S / N", OtherInfo; // Memset (OtherInfo, 0, Strlen (OtherInfo); IF (UDPData [i]> 33) && (udpdata [i] <122)) // Sprintf (OtherInfo, "% C", udpdata [i]); ELSE // Sprintf (Udpdata, "[% 3X]", ABS (udpdata [i])); udpdata [i] = '_';} // printf ("/ n [data end] / n / n / n");} AddReceiveData (ReceiveInfo); delete receiveInfo; Return true;} // ICMP unpackler INT Tsniffer :: decodeicmppack (char * icmpbuf, int ibufsize) {icmp_header * picmpheader; pIcmpHeader = (ICMP_HEADER *) IcmpBuf; int iIcmpType = pIcmpHeader-> i_type; int iIcmpCode = pIcmpHeader-> i_code; RECEIVEINFO * ReceiveInfo = new RECEIVEINFO; // type filter if (! (iPortFilter) && (iIcmpType = iPortFilter)) Return true; // printf ("% s", szprotocol); // printf ("% 15 s type% D ->% 15S code% D", szsourceip, iicmptype, szdestip, iicmpcode; // printf ("% 15s ->% 15s ", szsourceip, szdestip; // printf (" TTL =% 3D ", ITTL); // Printf (" Type% 2D,% D ", Iicmptype, IicmpCode); //printf (" bytes = % 4D ", IBUFSIZE); // Printf (" / n ");
ReceiveInfo-> szProtocol = szProtocol; ReceiveInfo-> szSourceIP = szSourceIP; ReceiveInfo-> iIcmpType = iIcmpType; ReceiveInfo-> szDestIP = szDestIP; ReceiveInfo-> iIcmpCode = iIcmpCode; ReceiveInfo-> iTTL = iTTL; ReceiveInfo-> iBufSize = iBufSize; / / For data analysis of packets containing data segments, IF ((ibufsize> 28)) {char * icmpdata = ICMPBUF 4; // Analyze ICMP Data Section // Printf ("[DATA]"); //// For (unsigned INT i = 0; i <(ibufsize-sizeof (ICMP_HEADER)); i ) // {// IF (! (i% 8)) Printf ("/ n"); // IF ((ICMPDATA [ I]> 33) && (ICMPDATA [I] <122) // Printf ("% 3C [% 3X]", ICMPDATA [I], ICMPDATA [I]); // else printf ("[% 3X]" , ABS (ICMPDATA [I])); //} // printf ("/ n [data end] / n / n / n"); receiveInfo-> receivedata = ICMPDATA;} addreceiveData (ReceiveInfo); Delete ReceiveInfo; Return True;} // SOCK error handler Void Tsniffer :: ChecksockerRr (int irecode, char * perroormsg) {if (ierrorcode == socket_error) {// printf ("% s error:% d / n", perroormsg, getLastError )); Form1-> ListView1-> AddItem (pErrorMsg, 0); closesocket (SockRaw); exit (0);}} void TSniffer :: AddReceiveData (RECEIVEINFO * ReceiveInfo) {TListItem * Item; Item = Form1-> ListView1-> Items- > Add (); item-> caption = receiveInfo-> szprotocol; item-> Subitems-> add (receiveInfo-> szsource); item-> Subitems-> add (ITTOSTR (ReceiveInfo-> isourceport); item-> Subitems -> Add (ReceiveInfo-> Szdestip); item-> Subitems-> Add (INTTOSTR (ReceiveInfo-> Idestport); item-> Subitems->
Add (ReceiveInfo-> ITTL); item-> Subitems-> Add (ReceiveInfo-> ibufsize)); item-> Subitems-> add (receiveInfo-> tcpflag); item-> substers-> add ( INTSTOSTR (ReceiveInfo-> Length); item-> Subitems-> add (receiveInfo-> iicmpty); item-> subs-> add (receiveInfo-> iicmpcode); try {ipiem-> Subitems-> add (receiveInfo-> ReceiveData); item-> Subitems-> Add (ReceiveInfo-> receive indeuda);} catch (...) {}} void Tsniffer :: removedata () {MEMSET (Recvbuf, 0, sizeof (recvbuf); iERRORCODE = Recv (SockRaw, Recvbuf, 0); Checksockerror (IrrorCode, "RECV"); IrrorCode = DecodeipPack (Recvbuf, IerrorCode); ChecksockerRr (IrrorCode, "decode");} header file // ----- -------------------------------------------------- -------------------- #ifndef Snifferthreadh # define sniffReadh // ---------------------- -------------------------------------------------- --- # include
// 3-bit flag bit Unsigned char TTL; // 8-bit survival time TTL unsigned char proto; // 8-bit protocol (TCP, UDP, or other) unsigned short checksum; // 16 bits IP header checksum unsigned int sourceip; // 32 Bit source IP address unsigned int desip; // 32 bit ip address} ip_header; typef struct _tcphdr // Defines TCP header {ushort th_sport; // 16-bit source port USHORT TH_DPORT; / / 16-bit destination port unsigned INT TH_SEQ; // 32-bit serial number unsigned int th_ack; // 32 bit confirmation number unsigned char th_lenres; // 4 top length / 6 reserved word unsigned char th_flag; // 6 bit flag bit ushort t_win; // 16 bits Window size ushort th_sum; // 16-bit check and ushort tr_urp; // 16-bit emergency data offset} TCP_HEPEDEF STRUCT _UDPHDR / / Define UDP header {UNSIGNED SHORT UH_SPORT; / / 16-bit source port UNSIGNED SHORT UH_DPORT; // 16-bit destination port unsigned short uh_len; // 16-bit length UNSigned short uh_sum; // 16-bit checksum} udp_header; typedef struct _icphdr // Define ICMP header {BYTE I_TYPE; // 8-bit type BYTE I_CODE; / / 8-bit code ushort i_cksum; // 16-bit check and usort i_id; // identification number (general process number as an identification number) Ushort i_seq; // message serial number Ulong timestamp; // Timestamp} ICMP_HEADER; typedef Struct _protomap / / Define sub-protocol mapping table {int ProtoNum; char ProtoText [MAX_PROTO_TEXT_LEN];} PROTOMAP; typedef struct _receiveinfo {char * szProtocol; char * szSourceIP; int iSourcePort; char * szDestIP; int iDestPort; int iTTL; int Length; char TcpFlag [ 6]; int iBufSize; char iIcmpType; char iIcmpCode; char * ReceiveData; AnsiString ReceiveUdpData;} RECEIVEINFO; PROTOMAP ProtoMap [MAX_PROTO_NUM] = {// sub-protocol mapping table assignment {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, "}}; class tsniffer: public tthread {private: INT decodeippack (char *, int); // ip unpacking function int decodetcppck (char *, int); // TCP unpacking function int decodeudppack (char *, int); // UDP unpacking function int decodeicmppack (char * , int); // ICMP unpack function void CheckSockError (int, char *); // error handler char * CheckProtocol (int); // check agreement void SnifferInit (); void AddReceiveData (RECEIVEINFO * ReceiveInfo); void ReceiveData (); protected: void __fastcall (); public: socket sockraw; bool mpaMtcp; // Follow TCP packet BOOL MPARMUDP; // Follow UDP packet BOOL MPARAMP; // Follow ICMP Packet Bool MParamDecode; // Decoding char TCPFLAG [6]; // Defines TCP flag char * strfromipfilter; // Source IP address filter char * strDestipfilter; // destination address filter char * strSensitive; // Sensitive string INT I PortFilter; // port filtering int iProtocol, iTTL; char szProtocol [MAX_PROTO_TEXT_LEN]; char szSourceIP [MAX_ADDR_LEN], szDestIP [MAX_ADDR_LEN]; char OtherInfo [100]; int iErrorCode; char RecvBuf [MAX_PACK_LEN]; __fastcall TSniffer (bool CreateSuspended); }; // ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------- # endif lovemagg: Recommend Ethereal 0.9.14 to everyone, it also calls WinPCap3.0, now Version supports data files for various captain software,