⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdfltip.c

📁 一个截取网络包的驱动。它与DDK文档正是NDIS中间驱动不同
💻 C
字号:
////////////////////////////////////////////////////////////
//		Win2K HOOK 主文件
//

#include <ntddk.h>
#include <ndis.h>
//#include <pfhook.h>

#include "../FilterPkt.c"
#include "VDFltIp.h"

//进程回调函数,当进程退出时关闭g_hStopProcHandle
VOID ProcessCallback(
	IN HANDLE  hParentId, 
	IN HANDLE  hProcessId, 
	IN BOOLEAN bCreate
	)
{
	if(hProcessId==g_hVDialProcID && bCreate==FALSE)
	{
		DbgPrint("VDial g_hVDialProcID=%X Exit.\n",g_hVDialProcID);
		ZwClose(g_hStopProcHandle);
		g_hStopProcHandle=NULL;
		g_StopProcEvent=NULL;
		g_hVDialProcID=NULL;
		memset(&g_CurStopProc,0,sizeof(g_CurStopProc));
	}
}

#define dprintf(x)

NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DrvUnload(IN PDRIVER_OBJECT DriverObject);

#define NT_DEVICE_NAME L"\\Device\\VDFltIp"
#define DOS_DEVICE_NAME L"\\DosDevices\\VDFltIp"

PVOID m_NdisBaseAddress = NULL;
NDIS_REGISTER_PROTOCOL			m_pW2kNdisRegisterProtocol		= NULL;
NDIS_DEREGISTER_PROTOCOL		m_pW2kNdisDeregisterProtocol	= NULL;
NDIS_OPENADAPTER				m_pW2kNdisOpenAdapter			= NULL;
NDIS_CLOSEADAPTER				m_pW2kNdisCloseAdapter			= NULL;

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; 

// 得到Ndis.sys在内存中的基地址(虚拟地址)
BOOLEAN GetNdisModuleAddress()
{
	BOOLEAN bReturn = FALSE;
	ULONG nSize, i, nCount, nLength;
	PULONG pBuffer;
	PSYSTEM_MODULE_INFORMATION pModule;

	ZwQuerySystemInformation(11, &nSize, 0, &nSize);
	pBuffer = (PULONG)ExAllocatePool(NonPagedPool, nSize);
	ZwQuerySystemInformation(11, pBuffer, nSize, 0);

	nCount = *pBuffer;
	pModule = (PSYSTEM_MODULE_INFORMATION)(pBuffer + 1);

	for(i = 0; i < nCount; i++)
	{
		nLength = strlen(pModule[i].Name);
		if(nLength >= 8 
			&& _stricmp(pModule[i].Name + (nLength - 8), "ndis.sys") == 0)
		{
			m_NdisBaseAddress = pModule[i].BaseAddress;
			bReturn = TRUE;
			break;
		}
	}

	ExFreePool(pBuffer);
	return bReturn;
}

unsigned long CR0VALUE = 0;

void DisableProtection() 
{
	__asm
	{
		mov eax,cr0 
		mov CR0VALUE,eax 
		and eax,0fffeffffh 
		mov cr0,eax 
	}
}

void EnableProtection()
{
	__asm
	{
		mov eax,CR0VALUE 
		mov cr0,eax 
	}
}

//钩名字为Name的函数
PVOID HookFunction(PVOID pBaseAddress, PCSTR Name, PVOID InFunc, ULONG* OutFunc)
{
	PIMAGE_DOS_HEADER pDosHeader = NULL;
	PIMAGE_NT_HEADERS pNtHeader = NULL;
	PIMAGE_DATA_DIRECTORY pDirectory = NULL;
	PIMAGE_EXPORT_DIRECTORY pExports = NULL;
	ULONG nSize, Address, i;
	PULONG pFunctions = NULL;
	PSHORT pOrdinals = NULL;
	PULONG pNames = NULL;
	PVOID pFunction = NULL;
	ULONG Ordinal = 0;

	if(pBaseAddress == NULL)
		return NULL;

	pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;
	pNtHeader = (PIMAGE_NT_HEADERS)((PCHAR)pBaseAddress + pDosHeader->e_lfanew);
	pDirectory = pNtHeader->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT;

	nSize = pDirectory->Size;
	Address = pDirectory->VirtualAddress;

	pExports = (PIMAGE_EXPORT_DIRECTORY)((PCHAR)pBaseAddress + Address);

	pFunctions = (PULONG)((PCHAR)pBaseAddress + pExports->AddressOfFunctions);
	pOrdinals  = (PSHORT)((PCHAR)pBaseAddress + pExports->AddressOfNameOrdinals);
	pNames	   = (PULONG)((PCHAR)pBaseAddress + pExports->AddressOfNames);

	for(i = 0; i < pExports->NumberOfNames; i++)
	{
		Ordinal = pOrdinals[i];
		if(pFunctions[Ordinal] < Address || pFunctions[Ordinal] >= Address + nSize)
		{
			if(strcmp((PSTR)((PCHAR)pBaseAddress + pNames[i]), Name) == 0)
			{
				pFunction = (PCHAR)pBaseAddress + pFunctions[Ordinal];
				*OutFunc = (ULONG)pFunction;
				DisableProtection();
				pFunctions[Ordinal] = (ULONG)((ULONG)InFunc - (ULONG)pBaseAddress);
				EnableProtection();
				break;
			}
		}
	}

	return pFunction;
}

void WToB(WCHAR *wstr,CHAR *str,int len)
{
	int i;
	for(i=0;i<len && i<(MAX_PROTONAME-1);i++)
	{
		str[i]=(char)wstr[i];
	}
	str[i]=0;
}

VOID NDIS_API
W2K_NdisRegisterProtocol(
    OUT PNDIS_STATUS  Status,
    OUT PNDIS_HANDLE  NdisProtocolHandle,
    IN PNDIS_PROTOCOL_CHARACTERISTICS  ProtocolCharacteristics,
    IN UINT  CharacteristicsLength)
{
	SProtoHandle *pProtoHandle=AllocProtoHandle();
	char szProtoName[MAX_PROTONAME];

	if(pProtoHandle==NULL)
	{
		m_pW2kNdisRegisterProtocol(Status,NdisProtocolHandle,
			ProtocolCharacteristics,CharacteristicsLength);
		return;
	}

	WToB(ProtocolCharacteristics->Name.Buffer,szProtoName,ProtocolCharacteristics->Name.Length);

	DbgPrint("\n!!!!!W2K_NdisRegisterProtocol %s\n",szProtoName);

	strlwr(szProtoName);
//	strcpy(pProtoHandle->Name,szProtoName);

	HookProtoProc(&pProtoHandle->pOpenAdapterComplete,
		(void**)&ProtocolCharacteristics->OpenAdapterCompleteHandler,
		XF_OpenAdapterComplete,pProtoHandle);

//	if( strcmp(szProtoName,"\\DEVICE\\NDISWAN")==0 ||
//		strcmp(szProtoName,"TCPIP_WANARP")==0 )
	if(strstr(szProtoName,"ndiswan"))
	{
		pProtoHandle->bWan=1;

//		HookProtoProc(&pProtoHandle->pWanSendComplete,
//			(void**)&ProtocolCharacteristics->WanSendCompleteHandler,
//			XF_WanSendComplete,pProtoHandle);

		HookProtoProc(&pProtoHandle->pWanReceive,
			(void**)&ProtocolCharacteristics->WanReceiveHandler,
			XF_WanReceive,pProtoHandle);
	}
	else
	{
		pProtoHandle->bWan=0;

		HookProtoProc(&pProtoHandle->pSendComplete,
			(void**)&ProtocolCharacteristics->SendCompleteHandler,
			XF_SendComplete,pProtoHandle);

		HookProtoProc(&pProtoHandle->pReceive,
			(void**)&ProtocolCharacteristics->ReceiveHandler,
			XF_Receive,pProtoHandle);
	}

	HookProtoProc(&pProtoHandle->pStatusComplete,
		(void**)&ProtocolCharacteristics->StatusCompleteHandler,
		XF_StatusComplete,pProtoHandle);
	HookProtoProc(&pProtoHandle->pStatus,
		(void**)&ProtocolCharacteristics->StatusHandler,
		XF_Status,pProtoHandle);
	if(ProtocolCharacteristics->MajorNdisVersion >= 4 )
	{
		HookProtoProc(&pProtoHandle->pReceivePacket,
			(void**)&ProtocolCharacteristics->ReceivePacketHandler,
			XF_ReceivePacket,pProtoHandle);
		HookProtoProc(&pProtoHandle->pPnPEvent,
			(void**)&ProtocolCharacteristics->PnPEventHandler,
			XF_PnPEvent,pProtoHandle);
	}

	m_pW2kNdisRegisterProtocol(Status,NdisProtocolHandle,
		ProtocolCharacteristics,CharacteristicsLength);

	pProtoHandle->ProtoHandle=*NdisProtocolHandle;
	if(strcmp(szProtoName,"tcpip")==0)
	{
		g_TcpIpHandle=*NdisProtocolHandle;
	}
}

VOID NDIS_API
W2K_NdisDeregisterProtocol(
    OUT PNDIS_STATUS  Status,
    IN NDIS_HANDLE  NdisProtocolHandle
    )
{
	DbgPrint("!!!!!W2K_NdisDeregisterProtocol\n");

	m_pW2kNdisDeregisterProtocol(Status,NdisProtocolHandle);

	DelProtoHandle(NdisProtocolHandle);
}

VOID NDIS_API
W2K_NdisOpenAdapter(
    OUT PNDIS_STATUS  Status,
    OUT PNDIS_STATUS  OpenErrorStatus,
    OUT PNDIS_HANDLE  NdisBindingHandle,
    OUT PUINT  SelectedMediumIndex,
    IN PNDIS_MEDIUM  MediumArray,
    IN UINT  MediumArraySize,
    IN NDIS_HANDLE  NdisProtocolHandle,
    IN NDIS_HANDLE  ProtocolBindingContext,
    IN PNDIS_STRING  AdapterName,
    IN UINT  OpenOptions,
    IN PSTRING  AddressingInformation  OPTIONAL
	)
{
	XF_NdisOpenAdapter(
		Status,
		OpenErrorStatus,
		NdisBindingHandle,
		SelectedMediumIndex,
		MediumArray,
		MediumArraySize,
		NdisProtocolHandle,
		ProtocolBindingContext,
		AdapterName,
		OpenOptions,
		AddressingInformation,
		m_pW2kNdisOpenAdapter);
}

VOID NDIS_API
W2K_NdisCloseAdapter(
    OUT PNDIS_STATUS            Status,
    IN  NDIS_HANDLE             NdisBindingHandle
	)
{
	DbgPrint("!!!!!W2K_NdisCloseAdapter\n");

	m_pW2kNdisCloseAdapter(Status,NdisBindingHandle);

	DelAdapterHandle(NdisBindingHandle);
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
	
    PDEVICE_OBJECT         deviceObject        = NULL;
    NTSTATUS               ntStatus;
    UNICODE_STRING         deviceNameUnicodeString;
    UNICODE_STRING         deviceLinkUnicodeString;
	
    RtlInitUnicodeString(&deviceNameUnicodeString, NT_DEVICE_NAME);
	
	PsGetVersion(&g_uMajVer,&g_uMinVer,0,0);

    ntStatus = IoCreateDevice(DriverObject, 0,
		&deviceNameUnicodeString, FILE_DEVICE_VDFltIp,
		0, FALSE, &deviceObject);
	
    if ( NT_SUCCESS(ntStatus) )
    {
        RtlInitUnicodeString(&deviceLinkUnicodeString, DOS_DEVICE_NAME);
		
        ntStatus = IoCreateSymbolicLink(&deviceLinkUnicodeString, &deviceNameUnicodeString);
		
        if ( !NT_SUCCESS(ntStatus) )
        {
            dprintf("VDFltIp.SYS: IoCreateSymbolicLink failed\n");
        }
		
        DriverObject->MajorFunction[IRP_MJ_CREATE]         =
			DriverObject->MajorFunction[IRP_MJ_CLOSE]          =
			DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DrvDispatch;
        DriverObject->DriverUnload                         = DrvUnload;
    }
	
	
    if ( !NT_SUCCESS(ntStatus) )
    {
        if (deviceObject) IoDeleteDevice(deviceObject);
    }

	InitFilter();

	if(GetNdisModuleAddress() && m_NdisBaseAddress != NULL)
	{
		HookFunction(m_NdisBaseAddress, "NdisRegisterProtocol",
			W2K_NdisRegisterProtocol, (ULONG*)&m_pW2kNdisRegisterProtocol);

		HookFunction(m_NdisBaseAddress, "NdisDeregisterProtocol",
			W2K_NdisDeregisterProtocol, (ULONG*)&m_pW2kNdisDeregisterProtocol);

		HookFunction(m_NdisBaseAddress, "NdisOpenAdapter",
			W2K_NdisOpenAdapter, (ULONG*)&m_pW2kNdisOpenAdapter);

		HookFunction(m_NdisBaseAddress, "NdisCloseAdapter",
			W2K_NdisCloseAdapter, (ULONG*)&m_pW2kNdisCloseAdapter);
	}

	PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);

	if(g_uMajVer==5 && g_uMinVer>2) GetProcessNameOffset();

	return ntStatus;
}


NTSTATUS DrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
	
    PIO_STACK_LOCATION  irpStack;
    NTSTATUS            ntStatus=STATUS_SUCCESS;
	
    Irp->IoStatus.Information = 0;
	
    irpStack = IoGetCurrentIrpStackLocation(Irp);
	
    switch (irpStack->MajorFunction)
    {
    case IRP_MJ_CREATE:
		
        dprintf("VDFltIp.SYS: IRP_MJ_CREATE\n");
		
        break;
		
    case IRP_MJ_CLOSE:
		
        dprintf("VDFltIp.SYS: IRP_MJ_CLOSE\n");
		
        break;
		
    case IRP_MJ_DEVICE_CONTROL:
		
        dprintf("VDFltIp.SYS: IRP_MJ_DEVICE_CONTROL\n");
		
		DevCtrl(
			irpStack->Parameters.DeviceIoControl.IoControlCode,
			Irp->AssociatedIrp.SystemBuffer,
			Irp->AssociatedIrp.SystemBuffer,
			&Irp->IoStatus.Information);
		
        break;
    }
	
	
    //
    // DON'T get cute and try to use the status field of
    // the irp in the return status.  That IRP IS GONE as
    // soon as you call IoCompleteRequest.
    //
	
    Irp->IoStatus.Status=ntStatus;
	
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
	
    return ntStatus;
}

VOID DrvUnload(IN PDRIVER_OBJECT DriverObject)
{
	UNICODE_STRING         deviceLinkUnicodeString;
	
	RtlInitUnicodeString(&deviceLinkUnicodeString, DOS_DEVICE_NAME);
	
	IoDeleteSymbolicLink(&deviceLinkUnicodeString);
	
	IoDeleteDevice(DriverObject->DeviceObject);
	
	DbgPrint("VDFltIp.SYS: unloading\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -