Sniffer technology principle and application, including programming methods and tools (2)
Oh, not only IP IP, only I and the switch two Mac (this Chinese people do good), I don't want to find a third party, it is safe, but it is not all safe. Many people's network is still very bad. Many encryption protocols can be used to improve security, but old POP3, SMTP, HTTP, FTP is widely used, and it is impossible to replace it in a short time, and encryption is also available, so for high-aspiration It will be encrypted. However, Sniffer is not to give you the secret code. I used to learn the network, look at the package, and then used as a network management tool, analyze the health of the network, in fact, you know It is very likely that Sniffer is connected to 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, there are examples, VC6 compilation, BCB is also line, convert this format, but you better first familiar with the agreement, many agreements have in Linux The ready-made source code is mainly Struct. When transplantation, pay attention to the GCC, some C's advanced grammar, the compilation option should be noted, otherwise you will not get the correct result. If you can't get Sniffer, Win2000 Server also has a network package viewer, not strong than Sniffer, but simple things will be started quickly. The anti-sniffing and sniffing technology are actually very old, huh, but 9CBS is often Old. Be careful not to do bad things, there must be 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_characteristics, which has the entry of all protocol drivers and underlying distribution functions in this table. Such as SendHandler, ReceiveHandler, BindAdapterHandler, etc. When the network card has a packet entry, the ReceiveHandle or the ReceivePacketHandler Notification Protocol driver has a packet of the protocol to enter, and the protocol driver is driven to the NIC through the SendHandler or SendPacketshandler function. The packet is on the network. Some people will strange the program clearly not calling the NDISSEND or NDISSENDPACKETS function? 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. Now what we have to do should be very clear, as long as we can point the distribution function in the NDIS_PROTOCOL_CHARACTICS table fill in each protocol program to your 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 Protocolcharacteristics, in UINT CharacteristicsLength; NDIS_PROTOCOL_BLOCK (protocol table) is NDIS to maintain a unidirectional 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 you should pay attention to is the pagination and non-paged memory at different IRQL levels. 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 card driver and protocol driver is not called pNDIS_OPEN_BLOCK-> Protocolcharacteristics 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? NDISBINDINGHANDL actually points a pointer to the NDIS_OPEN_BLOCK table, then what is the use of the ndis_open_block table? When the agreement is smoothly bound, the channels of data transfer are established between each bound NIC 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; trave NSFER_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; all the top of the protocol all NDIS_OPEN_BLOCK heads. 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.
There is a problem with 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_ourBuffer, 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_OrBufferhan dle); 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; } Outpc.name = protoname; urbc.openadaptercompletehandler = ptopenadaptercomplete; otpc.closeadaptercompletehandler = ptcloseadaptercomplete; otsepc.sendcompletehandler = ptsend Complete; ourNPC.TransferDataCompleteHandler = PtTransferDataComplete; ourNPC.ResetCompleteHandler = PtResetComplete; ourNPC.RequestCompleteHandler = PtRequestComplete; ourNPC.ReceiveHandler = PtReceive; ourNPC.ReceiveCompleteHandler = PtReceiveComplete; ourNPC.StatusHandler = PtStatus; ourNPC.StatusCompleteHandler = PtStatusComplete; ourNPC.BindAdapterHandler = PtBindAdapter; Ournpc.unbindadapterHandler = ptunbindadapter; outpc.unloadhandler = ptunload; outpc.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, OurproColhandle;} 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_co NTEXT_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 = ExallocatePoolwithtag (NonPagedPo ol, 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 CloseRequestHandle; // 0 indicates an interna l 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 ( "// 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 (protocolcontent 0x14); i f (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; (!! (RtlCompareUnicodeString (& pProChar-> name, & TcpipString, TRUE)! // We r only interest in following protocol if || 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 by a thread, is also relatively easy to use 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); IerrorCode = 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 IBUFSIZE) {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, iBufSize); 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 (ortho); 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-> szdes tIP = szDestIP; ReceiveInfo-> iDestPort = iDestPort; ReceiveInfo-> iTTL = iTTL; ReceiveInfo-> Length = ntohs (pUdpHeader-> uh_len); ReceiveInfo-> iBufSize = iBufSize; // for the packet length is greater than 28 bytes of data Analysis (IP_HEADER UDP_HEADER> 28) IF ((ibufsize> 28)) {// printf ("[data] / n"); // UDP header length is 8 char * udpdata = udpbuf 8; / / Analyze UDP Data Section ReceiveInfo-> ReceiveData = Udpdata; TstringStream * DataStringStream = New TstringStream (NULL);