学了一天tdi,整个框架看的还不是太明了,做了个简单的tdi hook的框架
主要代码如下
DRIVER_OBJECT RealTDIDriverObject;
typedef struct forcontext
{
PVOID context_con;
PVOID context_routine;
}context_org,*pcontext_org;//保存环境
extern
NTKERNELAPI
NTSTATUS
ObReferenceObjectByName (
IN PUNICODE_STRING ObjectName,
IN ULONG Attributes,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID *Object
);
extern POBJECT_TYPE *IoDriverObjectType;
NTSTATUS HookTDI(void)
{
NTSTATUS Status;
UNICODE_STRING usDriverName;
PDRIVER_OBJECT DriverObjectToHookPtr;
int i;
RtlInitUnicodeString(&usDriverName,L"//Driver//Tcpip");
Status =
ObReferenceObjectByName(&usDriverName,OBJ_CASE_INSENSITIVE,NULL,0,*IoDriverObjectType,KernelMode,NULL,&DriverObjectToHookPtr);
if(Status != STATUS_SUCCESS) return Status;
for(i = 0;i < IRP_MJ_MAXIMUM_FUNCTION;i++) {
RealTDIDriverObject.MajorFunction[i] =
DriverObjectToHookPtr->MajorFunction[i];
DriverObjectToHookPtr->MajorFunction[i] = TDIDeviceDispatch;//hook 调用函数 并保存元函数
}
DbgPrint("success/n");
return STATUS_SUCCESS;
}
NTSTATUS TDIDeviceDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
NTSTATUS Status;
PIO_STACK_LOCATION StackLocationPtr;
char *buf,*pos;
int len,size;
PVOID orgcontext;
orgcontext = (PVOID)ExAllocatePool(PagedPool, sizeof(context_org));
DbgPrint("in tdi/n");
if(Irp == NULL) return STATUS_SUCCESS;
StackLocationPtr = IoGetCurrentIrpStackLocation(Irp);
if(StackLocationPtr->CompletionRoutine != NULL)
{
DbgPrint("StackLocationPtr->CompletionRoutine 0x%08x/n",StackLocationPtr->CompletionRoutine);
DbgPrint("StackLocationPtr->Context 0x%08x/n",StackLocationPtr->Context);
((pcontext_org)orgcontext)->context_con = StackLocationPtr->Context;
((pcontext_org)orgcontext)->context_routine = StackLocationPtr->CompletionRoutine;
//由于系统的多线程性 回调函数的时候有可能经过这里 必须完整地保存环境
StackLocationPtr->Context = orgcontext;
}
else StackLocationPtr->Context = NULL;
DbgPrint("0x%08x/n",TDICompletionRoutine);
StackLocationPtr->CompletionRoutine =
(PIO_COMPLETION_ROUTINE)TDICompletionRoutine;
DbgPrint("in tdi 4/n");
if(StackLocationPtr->MajorFunction==IRP_MJ_INTERNAL_DEVICE_CONTROL)
{
if(StackLocationPtr->MinorFunction == TDI_RECEIVE)
{
if(Irp->MdlAddress!=NULL){
buf = (char *)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
if (buf != NULL)
{
len = StackLocationPtr->Parameters.DeviceIoControl.OutputBufferLength;
size = len+1;
//。。。。。。。。。。。。。。。。。操作
}
}
}
}
StackLocationPtr->Control = SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR |
SL_INVOKE_ON_CANCEL;
DbgPrint("in tdi 5/n");
Status =
RealTDIDriverObject.MajorFunction[StackLocationPtr->MajorFunction](DeviceObject,Irp);
DbgPrint("in tdi 6/n");
return Status;
}
NTSTATUS TDICompletionRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp,PVOID
Context)
{
PIO_COMPLETION_ROUTINE RealCompletionRoutine;
PIO_STACK_LOCATION isp;
DbgPrint("in routine/n");
if(!Context)
return STATUS_SUCCESS;
RealCompletionRoutine = (PIO_COMPLETION_ROUTINE)(((pcontext_org)Context)->context_routine);
isp = IoGetNextIrpStackLocation(Irp);
if(RealCompletionRoutine != NULL)
{
DbgPrint("isp->CompletionRoutine 0x%08x/n",isp->CompletionRoutine);
DbgPrint("isp->Context 0x%08x/n",isp->Context);
isp->CompletionRoutine = ((pcontext_org)Context)->context_routine;
isp->Context = ((pcontext_org)Context)->context_con;
//在回调函数中把环境恢复
ExFreePool(Context);
return RealCompletionRoutine(DeviceObject,Irp,isp->Context);
}
else {
DbgPrint("context0/n");
return STATUS_SUCCESS;
}
}
NTSTATUS ReleaseTDIDevices(void)
{
NTSTATUS Status;
UNICODE_STRING usDriverName;
PDRIVER_OBJECT DriverObjectToHookPtr;
UINT i;
RtlInitUnicodeString(&usDriverName,L"//Driver//Tcpip");
Status =
ObReferenceObjectByName(&usDriverName,OBJ_CASE_INSENSITIVE,NULL,0,IoDriverObjectType,KernelMode,NULL,&DriverObjectToHookPtr);
if(Status != STATUS_SUCCESS) return Status;
for(i = 0;i < IRP_MJ_MAXIMUM_FUNCTION;i++)
DriverObjectToHookPtr->MajorFunction[i] =
RealTDIDriverObject.MajorFunction[i];
return STATUS_SUCCESS;
}