📄 vdfltip.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 + -