Click here to Skip to main content
15,894,343 members
Articles / Desktop Programming / Windows Forms

NDIS MONITOR .NET 32-bit v1.00

Rate me:
Please Sign up or sign in to vote.
4.81/5 (36 votes)
27 Apr 20078 min read 176.4K   9.9K   90  
NDIS Monitor allows to catch and log the exchange of packet data between NDIS miniport drivers and network protocol modules that occurs in kernel space.
/***************************************************************************************
  *
  * NdisHook.h - Header File for NDIS Hooking Functions Module
  *
  * Copyright (c)2003 Vito Plantamura. All Rights Reserved.
  *
***************************************************************************************/

#pragma once

//========================
// Required Header Files.
//========================

#ifdef VPCKNT_SYSMODULE

#define NDIS_WRAPPER
#include <ntddk.h>
typedef PVOID		NDIS_STATS;
#include <ndis.h>

#endif

//==========================
// Some needed definitions.
//==========================

#ifdef VPCKNT_SYSMODULE

typedef ULONG		DWORD;
typedef UCHAR		BYTE;
typedef BOOLEAN		BOOL;

#endif

//===========
// Includes.
//===========

#include "..\Include\IOCTLs.h"

//==============
// Definitions.
//==============

// internal

#define TEMPORARY_MEMORYBUFFER_SIZE			( 1 * 1024 * 1024 )

// public

#define STUBSLIST_BUFFER_MAXSIZE			( 128 * 1024 )
#define PROTOCOLLIST_BUFFER_MAXSIZE			( sizeof( NT_PROTOCOL_LIST ) + TEMPORARY_MEMORYBUFFER_SIZE * 2 )

//=============================
// NDIS Structures Definition.
//=============================

#ifdef VPCKNT_SYSMODULE
#pragma pack(push, 1)

	typedef struct _NDIS50_PROTOCOL_BLOCK
	{
		struct _NDIS_OPEN_BLOCK*					OpenQueue;
		BYTE										Reserved[ 0xC ];
		struct _NDIS50_PROTOCOL_BLOCK*				NextProtocol;
		struct _NDIS50_PROTOCOL_CHARACTERISTICS		ProtocolCharacteristics;

	} NDIS50_PROTOCOL_BLOCK, *PNDIS50_PROTOCOL_BLOCK;

#pragma pack(pop)
#endif

//================================================================================================
// Structures used for representing the list of system installed Protocols and relative Adapters.
//================================================================================================

// --- Structures:

#pragma pack(push, 1)

	typedef struct _NT_PROTOCOL_LIST
	{
		// ...Info...

		DWORD				dwProtocolsNum;
		DWORD				dwOpenAdaptersNum;

		// ...Data...

			//
			// x List of NT_PROTOCOL(s) follows.
			// x List of NT_OPEN_ADAPTER(s) follows.
			//

	} NT_PROTOCOL_LIST, *PNT_PROTOCOL_LIST;

	// // //

	typedef struct _NT_PROTOCOL
	{
		DWORD					dwOrdinal;

#ifdef VPCKNT_SYSMODULE
		NDIS_HANDLE				hHandle;
		BYTE*					pbWorkItemHeader;
		UINT					uiWorkItemHeaderSize;
		DWORD					dwWorkItemID;
		PVOID					pvWorkItemPacketRef;
		DWORD					dwWorkItemAsyncOpAdapterOrd;
		DWORD					dwWorkItemPacketSerial;
#else
		DWORD					dwReserved[ 7 ];
#endif

		WCHAR					szName[ 256 ];

	} NT_PROTOCOL, *PNT_PROTOCOL;

	// // //

	typedef struct _NT_OPEN_ADAPTER
	{
		DWORD					dwOrdinal;
		DWORD					dwProtocolOrd;
#ifdef VPCKNT_SYSMODULE
		NDIS_OPEN_BLOCK*		pobBlockPtr;
		NDIS_MINIPORT_BLOCK*	pmbMiniportPtr;
#else
		DWORD					dwReserved1;
		DWORD					dwReserved2;
#endif
		WCHAR					szName[ 256 ];

#ifdef VPCKNT_SYSMODULE
		SEND_HANDLER				Original_SendHandler;
		RECEIVE_HANDLER				Original_ReceiveHandler;
		RECEIVE_HANDLER				Original_PostNt31ReceiveHandler;
		SEND_PACKETS_HANDLER		Original_SendPacketsHandler;
		TRANSFER_DATA_HANDLER		Original_TransferDataHandler;
		RECEIVE_PACKET_HANDLER		Original_ReceivePacketHandler;
		NDIS_M_TD_COMPLETE_HANDLER	Original_TDCompleteHandler; // # WARNING #: this is taken from the _NDIS_MINIPORT_BLOCK str, not from the _NDIS_OPEN_BLOCK str. This structure represents a NIC miniport driver and can be associated to more than one protocol !!
#else
		DWORD					dwReserved3;
		DWORD					dwReserved4;
		DWORD					dwReserved5;
		DWORD					dwReserved6;
		DWORD					dwReserved7;
		DWORD					dwReserved8;
		DWORD					dwReserved9;
#endif

		PVOID					Stub_SendHandler;
		PVOID					Stub_ReceiveHandler;
		PVOID					Stub_PostNt31ReceiveHandler;
		PVOID					Stub_SendPacketsHandler;
		PVOID					Stub_TransferDataHandler;
		PVOID					Stub_ReceivePacketHandler;
		PVOID					Stub_TDCompleteHandler;

	} NT_OPEN_ADAPTER, *PNT_OPEN_ADAPTER;

#pragma pack(pop)

// --- Related Definitions:

#define SENDHANDLER_FNID				0
#define RECEIVEHANDLER_FNID				1
#define POSTNT31RECEIVEHANDLER_FNID		2
#define SENDPACKETSHANDLER_FNID			3
#define TRANSFERDATAHANDLER_FNID		4
#define RECEIVEPACKETHANDLER_FNID		5
#define TDCOMPLETEHANDLER_FNID			6

//==============================================
// Structures used when patching Ndis Handlers.
//==============================================

#pragma pack(push, 1)

	typedef struct _NDISHOOK_HANDLER_STUB
	{
		BYTE			bPushImm32Opcode;	// It is 0x68.
		DWORD			dwOperationID;		// Identifier of the stub.
		BYTE			bJmpRel32Opcode;	// It is 0xE9.
		DWORD			dwJmpDisplacement;	// Relative address.

		BYTE			bPad[ 0x6 ];		// PAD: 0, 0, 0, 0, 0, 0

	} NDISHOOK_HANDLER_STUB, *PNDISHOOK_HANDLER_STUB;

#pragma pack(pop)

//======================
// Function Prototypes.
//======================

#ifdef VPCKNT_SYSMODULE

NTSTATUS RegisterFakeProtocol( OUT PNDIS_HANDLE phProtocolHandle, IN PUCHAR pszProtocolName );
NTSTATUS DeregisterFakeProtocol( IN NDIS_HANDLE hProtocolHandle );

DWORD GetNdisVersion ( void );
	// ### GetNdisVersion Return Value Note --> 0xFFFFFFFF when the NDIS Version cannot be determined. ###

NTSTATUS VerifyNdisVersionCompatibility ();

NDIS_HANDLE GetNextProtocol( IN NDIS_HANDLE hProtocolHandle );

NDIS_OPEN_BLOCK* GetOpenQueue( IN NDIS_HANDLE hProtocolHandle );
NDIS_OPEN_BLOCK* GetNextOpen( IN NDIS_OPEN_BLOCK* pnobOpenBlock );
NDIS50_PROTOCOL_CHARACTERISTICS* GetProtocolCharacteristics( IN NDIS_HANDLE hProtocolHandle );

NTSTATUS HookInstalledProtocols( OUT PNT_PROTOCOL_LIST* ppplProtocolList, OUT PNDISHOOK_HANDLER_STUB* ppnhhsStubs, OUT DWORD* pdwStubsNum, IN NDIS_HANDLE hFakeProtocolHandle );
NTSTATUS UnhookInstalledProtocols( PNT_PROTOCOL pntpProtocols, DWORD dwProtocolsSize, PNT_OPEN_ADAPTER pntoaAdapters, DWORD dwAdaptersSize );

NDIS_STATUS __cdecl New_SendHandler( IN OUT DWORD HookPrivateStorage, IN OUT DWORD CallingFnRetAddress, IN OUT NDIS_HANDLE MacBindingHandle, IN OUT PNDIS_PACKET Packet );
NDIS_STATUS __cdecl New_ReceiveHandler( IN OUT DWORD HookPrivateStorage, IN OUT DWORD CallingFnRetAddress, IN OUT NDIS_HANDLE ProtocolBindingContext, IN OUT NDIS_HANDLE MacReceiveContext, IN OUT PVOID HeaderBuffer, IN OUT UINT HeaderBufferSize, IN OUT PVOID LookAheadBuffer, IN OUT UINT LookaheadBufferSize, IN OUT UINT PacketSize );
NDIS_STATUS __cdecl New_PostNt31ReceiveHandler( IN OUT DWORD HookPrivateStorage, IN OUT DWORD CallingFnRetAddress, IN OUT NDIS_HANDLE ProtocolBindingContext, IN OUT NDIS_HANDLE MacReceiveContext, IN OUT PVOID HeaderBuffer, IN OUT UINT HeaderBufferSize, IN OUT PVOID LookAheadBuffer, IN OUT UINT LookaheadBufferSize, IN OUT UINT PacketSize );
VOID __cdecl New_SendPacketsHandler( IN OUT DWORD HookPrivateStorage, IN OUT DWORD CallingFnRetAddress, IN OUT NDIS_HANDLE MiniportAdapterContext, IN OUT PPNDIS_PACKET PacketArray, IN OUT UINT NumberOfPackets );
NDIS_STATUS __cdecl New_TransferDataHandler( IN OUT DWORD HookPrivateStorage, IN OUT DWORD CallingFnRetAddress, IN OUT NDIS_HANDLE MacBindingHandle, IN OUT NDIS_HANDLE MacReceiveContext, IN OUT UINT ByteOffset, IN OUT UINT BytesToTransfer, IN OUT PNDIS_PACKET Packet, IN OUT PUINT BytesTransferred );
VOID __cdecl New_TDCompleteHandler( IN OUT DWORD HookPrivateStorage, IN OUT DWORD CallingFnRetAddress, IN OUT NDIS_HANDLE MiniportAdapterHandle, IN OUT PNDIS_PACKET Packet, IN OUT NDIS_STATUS Status, IN OUT UINT BytesTransferred );
INT __cdecl New_ReceivePacketHandler( IN OUT DWORD HookPrivateStorage, IN OUT DWORD CallingFnRetAddress, IN OUT NDIS_HANDLE ProtocolBindingContext, IN OUT PNDIS_PACKET Packet );

BOOLEAN Intercept_SendHandler( IN PNT_PROTOCOL pnpProtocol, IN PNT_OPEN_ADAPTER pnoaAdapter, OUT NDIS_STATUS* pRetStatus, IN OUT NDIS_HANDLE* pMacBindingHandle, IN OUT PNDIS_PACKET* pPacket );
BOOLEAN Intercept_ReceiveHandler( IN PNT_PROTOCOL pnpProtocol, IN PNT_OPEN_ADAPTER pnoaAdapter, OUT NDIS_STATUS* pRetStatus, IN OUT NDIS_HANDLE* pProtocolBindingContext, IN OUT NDIS_HANDLE* pMacReceiveContext, IN OUT PVOID* pHeaderBuffer, IN OUT UINT* pHeaderBufferSize, IN OUT PVOID* pLookAheadBuffer, IN OUT UINT* pLookaheadBufferSize, IN OUT UINT* pPacketSize, IN RECEIVE_HANDLER pfnOriginal );
BOOLEAN Intercept_PostNt31ReceiveHandler( IN PNT_PROTOCOL pnpProtocol, IN PNT_OPEN_ADAPTER pnoaAdapter, OUT NDIS_STATUS* pRetStatus, IN OUT NDIS_HANDLE* pProtocolBindingContext, IN OUT NDIS_HANDLE* pMacReceiveContext, IN OUT PVOID* pHeaderBuffer, IN OUT UINT* pHeaderBufferSize, IN OUT PVOID* pLookAheadBuffer, IN OUT UINT* pLookaheadBufferSize, IN OUT UINT* pPacketSize, IN RECEIVE_HANDLER pfnOriginal );
BOOLEAN Intercept_SendPacketsHandler( IN PNT_PROTOCOL pnpProtocol, IN PNT_OPEN_ADAPTER pnoaAdapter, IN OUT NDIS_HANDLE* pMiniportAdapterContext, IN OUT PPNDIS_PACKET* pPacketArray, IN OUT UINT* pNumberOfPackets );
BOOLEAN Intercept_TransferDataHandler( IN PNT_PROTOCOL pnpProtocol, IN PNT_OPEN_ADAPTER pnoaAdapter, OUT NDIS_STATUS* pRetStatus, IN OUT NDIS_HANDLE* pMacBindingHandle, IN OUT NDIS_HANDLE* pMacReceiveContext, IN OUT UINT* pByteOffset, IN OUT UINT* pBytesToTransfer, IN OUT PNDIS_PACKET* pPacket, IN OUT PUINT* pBytesTransferred, IN TRANSFER_DATA_HANDLER pfnOriginal );
BOOLEAN Intercept_TDCompleteHandler( IN PNT_PROTOCOL pnpProtocol, IN PNT_OPEN_ADAPTER pnoaAdapter, IN OUT NDIS_HANDLE* pMiniportAdapterHandle, IN OUT PNDIS_PACKET* pPacket, IN OUT NDIS_STATUS* pStatus, IN OUT UINT* pBytesTransferred );
BOOLEAN Intercept_ReceivePacketHandler( IN PNT_PROTOCOL pnpProtocol, IN PNT_OPEN_ADAPTER pnoaAdapter, OUT INT* pRetStatus, IN OUT NDIS_HANDLE* pProtocolBindingContext, IN OUT PNDIS_PACKET* pPacket, IN RECEIVE_PACKET_HANDLER pfnOriginal );

VOID QueuePacket( IN PNT_OPEN_ADAPTER pnoaAdapter, IN BYTE* pbData, IN DWORD dwDataSize, BYTE bDirection, DWORD dwSerial );
BOOL RetrievePacket( OUT NEXT_PACKET* pOut, OUT HOOK_STATS* pStats );

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Italy Italy
Vito is a former videogame programmer. Now, Vito is the founder and CEO of VPC Technologies, a company that specializes in online services. VPC Technologies also provides consulting, developing and training services to several italian companies and government agencies in the field of kernel, component, enterprise and tridimensional software, for the Microsoft Windows platform.

Vito has attended as a speaker several italian conferences and events on development and security, such as the Microsoft Security Roadshow 2006.

Vito is the man behind GoToTerminal, a secure, reliable and innovative web technology to control remote Microsoft Windows, Telnet and VNC servers over the internet. He is also the author of BugChecker, an independent research project to create the only clone of SoftICE to date, NDIS Monitor, MapGen and Image Downloader.

For more information, you can visit Vito Plantamura's technical website at www.VitoPlantamura.com.

Comments and Discussions