NTSTATUS GetDrvObjectByName(char *pszDrvName, PULONG pDrvObject) { NTSTATUS status=STATUS_SUCCESS; ANSI_STRING ansiDev, ansFileDev; UNICODE_STRING uniObjName, uniFileDev; char dev[256]={0}; char sym[256]={0}; char fileDev[256]={0}; char fileSym[256]={0}; //驱动对象 PDRIVER_OBJECT pDrvObj=NULL; //清零指针内容 *pDrvObject = 0; //非空则转Unicode驱动名 if (pszDrvName[0] != '\0') { strcpy(dev, "\\Driver\\"); // "\Driver\xxx.sys" strcat(dev, pszDrvName); strcpy(fileDev, "\\FileSystem\\"); //"\FileSystem\xxx.sys" strcat(fileDev, pszDrvName); //去除后缀名(减去后4个字符,"\Driver\xxx") RtlMoveMemory(sym, dev, strlen(dev)-4); //去除后缀名(减去后4个字符,"\FileSystem\xxx") RtlMoveMemory(fileSym, fileDev, strlen(dev)-4); RtlInitAnsiString(&ansiDev, sym); RtlInitAnsiString(&ansFileDev, fileSym); //转Unicode对象名 RtlAnsiStringToUnicodeString(&uniObjName, &ansiDev, TRUE); //转Unicode对象名 RtlAnsiStringToUnicodeString(&uniFileDev, &ansFileDev, TRUE); } //引用对象通过名字("\Driver\xxx") status=ObReferenceObjectByName(&uniObjName, OBJ_CASE_INSENSITIVE, NULL, FILE_ALL_ACCESS, IoDriverObjectType, KernelMode, NULL, (PVOID *)&pDrvObj); if ( !NT_SUCCESS(status) ) { //引用对象通过名字("\FileSystem\xxx") status=ObReferenceObjectByName(&uniFileDev, OBJ_CASE_INSENSITIVE, NULL, FILE_ALL_ACCESS, IoDriverObjectType, KernelMode, NULL, (PVOID *)&pDrvObj); if ( !NT_SUCCESS(status) ) { // DbgPrint("ObReferenceObjectByName(\"\\Driver\\xxx or \\FileSystem\\xxx\") Failed! Status: 驱动名:%ws \t 0x%x\n", uniObjName.Buffer, status); return status; } } // DbgPrint("驱动名:%ws \t 驱动对象:0x%08X\n", uniObjName.Buffer, pDrvObj); *pDrvObject=(ULONG)pDrvObj; //解除对象引用 ObDereferenceObject(pDrvObj); return status; }
/* hook/unhook driver */ NTSTATUS hook_tcpip(DRIVER_OBJECT *old_DriverObject, BOOLEAN b_hook) { UNICODE_STRING drv_name; NTSTATUS status; PDRIVER_OBJECT new_DriverObject; int i; RtlInitUnicodeString(&drv_name, L"\\Driver\\Tcpip"); status = ObReferenceObjectByName(&drv_name, OBJ_CASE_INSENSITIVE, NULL, 0, IoDriverObjectType, KernelMode, NULL, &new_DriverObject); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] hook_driver: ObReferenceObjectByName\n")); return status; } for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { if (b_hook) { old_DriverObject->MajorFunction[i] = new_DriverObject->MajorFunction[i]; new_DriverObject->MajorFunction[i] = DeviceDispatch; } else new_DriverObject->MajorFunction[i] = old_DriverObject->MajorFunction[i]; } return STATUS_SUCCESS; }
NTSTATUS ClearFilters(WCHAR* wzDriverName,ULONG_PTR DeviceObject) { UNICODE_STRING uniDriverName; PDRIVER_OBJECT DriverObject; PDEVICE_OBJECT CurrentDevice; NTSTATUS Status; RtlInitUnicodeString(&uniDriverName, wzDriverName); Status = ObReferenceObjectByName(&uniDriverName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, (PVOID*)&DriverObject); if (!NT_SUCCESS(Status)) return ; if(!DriverObject) return ; CurrentDevice = DriverObject->DeviceObject; while(CurrentDevice != NULL ) { if ((ULONG_PTR)CurrentDevice->AttachedDevice == DeviceObject) { CurrentDevice->AttachedDevice = ((PDEVICE_OBJECT)DeviceObject)->AttachedDevice; } CurrentDevice = CurrentDevice->NextDevice; } ObDereferenceObject(DriverObject); return Status; }
NTSTATUS GetFilterDriverByDriverName(WCHAR *wzDriverName, PFILTER_DRIVER FilterDriverInfor, FILTER_TYPE Type) { NTSTATUS Status = STATUS_UNSUCCESSFUL; UNICODE_STRING uniDriverName; PDRIVER_OBJECT DriverObject = NULL; POBJECT_TYPE DriverObjectType = *IoDriverObjectType; if (!DriverObjectType) { return Status; } RtlInitUnicodeString(&uniDriverName, wzDriverName); Status = ObReferenceObjectByName( &uniDriverName, OBJ_CASE_INSENSITIVE, NULL, 0, DriverObjectType, KernelMode, NULL, (PVOID*)&DriverObject); if (NT_SUCCESS(Status) && DriverObject) { PDEVICE_OBJECT DeviceObject = NULL; for ( DeviceObject = DriverObject->DeviceObject; DeviceObject; DeviceObject = DeviceObject->NextDevice ) { PDRIVER_OBJECT AttachedDriverObject = DeviceObject->DriverObject; PDEVICE_OBJECT AttachDeviceObject = NULL; for ( AttachDeviceObject = DeviceObject->AttachedDevice; AttachDeviceObject; AttachDeviceObject = AttachDeviceObject->AttachedDevice ) { Status = AddFilterInfo( AttachDeviceObject, AttachedDriverObject, FilterDriverInfor, Type ); AttachedDriverObject = AttachDeviceObject->DriverObject; } } ObfDereferenceObject(DriverObject); } return Status; }
NTSTATUS mydrvEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath){ UNREFERENCED_PARAMETER(pRegPath); UNICODE_STRING uKbdClassDrv; NTSTATUS status = STATUS_UNSUCCESSFUL; DbgPrint("Keyboard Filter Driver - DriverEntry\nCompiled at " __TIME__ " on " __DATE__ "\n"); //DbgPrint("sizeof(DEVICE_EXTENSION): %llu", sizeof(KBDFNFLT_DEVICE_EXTENSION)); //DbgPrint("offset, size: %llu, %llu", FIELD_OFFSET(KBDFNFLT_DEVICE_EXTENSION, pKeyboardDevice), FIELD_SIZE(KBDFNFLT_DEVICE_EXTENSION, pKeyboardDevice)); //DbgPrint("offset, size: %llu, %llu", FIELD_OFFSET(KBDFNFLT_DEVICE_EXTENSION, pKbdClassDrv), FIELD_SIZE(KBDFNFLT_DEVICE_EXTENSION, pKbdClassDrv)); //DbgPrint("offset, size: %llu, %llu", FIELD_OFFSET(KBDFNFLT_DEVICE_EXTENSION, pDevObjString), FIELD_SIZE(KBDFNFLT_DEVICE_EXTENSION, pDevObjString)); //DbgPrint("offset, size: %llu, %llu", FIELD_OFFSET(KBDFNFLT_DEVICE_EXTENSION, kState), FIELD_SIZE(KBDFNFLT_DEVICE_EXTENSION, kState)); //DbgPrint("offset, size: %llu, %llu", FIELD_OFFSET(KBDFNFLT_DEVICE_EXTENSION, workitem), 0);//FIELD_SIZE(KBDFNFLT_DEVICE_EXTENSION, workitem)); ///////////////////////////////////////////////////////////////////////////////////////// // Fill in IRP dispatch table in the DriverObject to handle I/O Request Packets (IRPs) ///////////////////////////////////////////////////////////////////////////////////////// // For a filter driver, we want pass down ALL IRP_MJ_XX requests to the driver which // we are hooking except for those we are interested in modifying. for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) #pragma warning(suppress: 28168) pDrvObj->MajorFunction[i] = dispatchPassDown; DbgPrint("Filled dispatch table with generic pass down routine...\n"); //Explicitly fill in the IRP's we want to hook pDrvObj->MajorFunction[IRP_MJ_READ] = dispatchRead; //Create a keyboard device object PDEVICE_OBJECT pKbdFnFltDevice = NULL; status = IoCreateDevice(pDrvObj, sizeof(KBDFNFLT_DEVICE_EXTENSION) + IoSizeofWorkItem(), NULL, //no name FILE_DEVICE_KEYBOARD, 0, TRUE, &pKbdFnFltDevice); //Make sure the device was created ok if (status) return status; RtlInitUnicodeString(&uKbdClassDrv, KBDCLASS_NAME); status = ObReferenceObjectByName(&uKbdClassDrv, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, 0, IoDriverObjectType, KernelMode, NULL, &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->pKbdClassDrv); if (status){ IoDeleteDevice(pKbdFnFltDevice); return status; } GUID kbdDevClass = GUID_CLASS_KEYBOARD; PIO_WORKITEM pWorkitem = (PIO_WORKITEM)&((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->workitem; IoInitializeWorkItem(pKbdFnFltDevice, pWorkitem); ((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->pWorkitem = pWorkitem; //PIO_WORKITEM pWorkitem = ExAllocatePoolWithTag(NonPagedPool, IoSizeofWorkItem(), g_poolTag); //if (!pWorkitem){ // //} DbgPrint("%p", &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->pKeyboardDevice); DbgPrint("%p", &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->pKbdClassDrv); DbgPrint("%p", &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->pDevObjString); DbgPrint("%p", &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->keyState); DbgPrint("%p", &((PKBDFNFLT_DEVICE_EXTENSION)pKbdFnFltDevice->DeviceExtension)->workitem); //IoInitializeWorkItem(&pKbdFnFltDevice) //PVOID pNotificationEntry = NULL; status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, &kbdDevClass, pDrvObj, keyboardAddedOrRemoved, pKbdFnFltDevice, &g_pNotificationEntry); if (status){ DbgPrint("something went wrong %lX", status); IoUninitializeWorkItem(pWorkitem); IoDeleteDevice(pKbdFnFltDevice); return status; } //Go ahead and hook the keyboard now //status = hookKeyboard(pDrvObj); //if (status){ // DbgPrint("something went wrong%lX", status); // return status; //} DbgPrint("Hooked IRP_MJ_READ routine...\n"); // Set the DriverUnload procedure pDrvObj->DriverUnload = mydrvUnload; DbgPrint("Set DriverUnload function pointer...\n"); DbgPrint("Exiting Driver Entry......\n"); return STATUS_SUCCESS; }
BOOLEAN obtest( void ) { ULONG i; HANDLE Handles[ 2 ]; NTSTATUS Status; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectTypeAName, "ObjectTypeA" ); RtlInitString( &ObjectTypeBName, "ObjectTypeB" ); RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); ObjectTypeInitializer.ValidAccessMask = -1; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.MaintainHandleCount = TRUE; ObjectTypeInitializer.DumpProcedure = DumpAProc; ObjectTypeInitializer.OpenProcedure = OpenAProc; ObjectTypeInitializer.CloseProcedure = CloseAProc; ObjectTypeInitializer.DeleteProcedure = DeleteAProc; ObjectTypeInitializer.ParseProcedure = ParseAProc; ObCreateObjectType( &ObjectTypeAName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObjectTypeA ); ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.MaintainHandleCount = FALSE; ObjectTypeInitializer.GenericMapping = MyGenericMapping; ObjectTypeInitializer.DumpProcedure = DumpBProc; ObjectTypeInitializer.OpenProcedure = NULL; ObjectTypeInitializer.CloseProcedure = NULL; ObjectTypeInitializer.DeleteProcedure = DeleteBProc; ObjectTypeInitializer.ParseProcedure = NULL; ObCreateObjectType( &ObjectTypeBName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObjectTypeB ); ObpDumpTypes( NULL ); RtlInitString( &DirectoryName, "\\MyObjects" ); InitializeObjectAttributes( &DirectoryObjA, &DirectoryName, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, NULL ); NtCreateDirectoryObject( &DirectoryHandle, 0, &DirectoryObjA ); NtClose( DirectoryHandle ); RtlInitString( &ObjectAName, "\\myobjects\\ObjectA" ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAName, OBJ_CASE_INSENSITIVE, NULL, NULL ); RtlInitString( &ObjectBName, "\\myobjects\\ObjectB" ); InitializeObjectAttributes( &ObjectBObjA, &ObjectBName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = ObCreateObject( KernelMode, ObjectTypeA, &ObjectAObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEA ), 0L, 0L, (PVOID *)&ObjectBodyA ); ObjectA = (POBJECTTYPEA)ObjectBodyA; ObjectA->TypeALength = sizeof( *ObjectA ); for (i=0; i<4; i++) { ObjectA->Stuff[i] = i+1; } KeInitializeEvent( &ObjectA->Event, NotificationEvent, TRUE ); Status = ObCreateObject( KernelMode, ObjectTypeB, &ObjectBObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEB ), 0L, 0L, (PVOID *)&ObjectBodyB ); ObjectB = (POBJECTTYPEB)ObjectBodyB; ObjectB->TypeBLength = sizeof( *ObjectB ); for (i=0; i<16; i++) { ObjectB->Stuff[i] = i+1; } KeInitializeSemaphore ( &ObjectB->Semaphore, 2L, 2L ); Status = ObInsertObject( ObjectBodyA, SYNCHRONIZE | 0x3, NULL, 1, &ObjectBodyA, &ObjectHandleA1 ); DbgPrint( "Status: %lx ObjectBodyA: %lx ObjectHandleA1: %lx\n", Status, ObjectBodyA, ObjectHandleA1 ); Status = ObInsertObject( ObjectBodyB, SYNCHRONIZE | 0x1, NULL, 1, &ObjectBodyB, &ObjectHandleB1 ); DbgPrint( "Status: %lx ObjectBodyB: %lx ObjectHandleB1: %lx\n", Status, ObjectBodyB, ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectAName, "\\MyObjects\\ObjectA" ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAName, OBJ_OPENIF, NULL, NULL ); Status = ObCreateObject( KernelMode, ObjectTypeA, &ObjectAObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEA ), 0L, 0L, (PVOID *)&ObjectBodyA1 ); Status = ObInsertObject( ObjectBodyA1, SYNCHRONIZE | 0x3, NULL, 1, &ObjectBodyA2, &ObjectHandleA2 ); DbgPrint( "Status: %lx ObjectBodyA1: %lx ObjectBodyA2: %lx ObjectHandleA2: %lx\n", Status, ObjectBodyA1, ObjectBodyA2, ObjectHandleA2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); NtClose( ObjectHandleA2 ); ObDereferenceObject( ObjectBodyA2 ); // ObInsertObject,ObjectPointerBias NtWaitForSingleObject( ObjectHandleB1, TRUE, NULL ); Handles[ 0 ] = ObjectHandleA1; Handles[ 1 ] = ObjectHandleB1; NtWaitForMultipleObjects( 2, Handles, WaitAny, TRUE, NULL ); ObReferenceObjectByHandle( ObjectHandleA1, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB1, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByPointer( ObjectBodyA, 0L, ObjectTypeA, KernelMode ); ObReferenceObjectByPointer( ObjectBodyB, 0L, ObjectTypeB, KernelMode ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectAPathName, "\\MyObjects\\ObjectA" ); RtlInitString( &ObjectBPathName, "\\MyObjects\\ObjectB" ); ObReferenceObjectByName( &ObjectAPathName, OBJ_CASE_INSENSITIVE, 0L, ObjectTypeA, KernelMode, NULL, &ObjectBodyA ); ObReferenceObjectByName( &ObjectBPathName, OBJ_CASE_INSENSITIVE, 0L, ObjectTypeB, KernelMode, NULL, &ObjectBodyB ); DbgPrint( "Reference Name %s = %lx\n", ObjectAPathName.Buffer, ObjectBodyA ); DbgPrint( "Reference Name %s = %lx\n", ObjectBPathName.Buffer, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObDereferenceObject( ObjectBodyA ); // ObInsertObject,ObjectPointerBias ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByPointer ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByName ObDereferenceObject( ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAPathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObOpenObjectByName( &ObjectAObjA, 0L, NULL, ObjectTypeA, KernelMode, NULL, &ObjectHandleA2 ); InitializeObjectAttributes( &ObjectBObjA, &ObjectBPathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObOpenObjectByName( &ObjectBObjA, 0L, NULL, ObjectTypeB, KernelMode, NULL, &ObjectHandleB2 ); DbgPrint( "Open Object Name %s = %lx\n", ObjectAPathName.Buffer, ObjectHandleA2 ); DbgPrint( "Open Object Name %s = %lx\n", ObjectBPathName.Buffer, ObjectHandleB2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); NtClose( ObjectHandleA1 ); NtClose( ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByHandle( ObjectHandleA2, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB2, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA2, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB2, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObOpenObjectByPointer( ObjectBodyA, OBJ_CASE_INSENSITIVE, 0L, NULL, ObjectTypeA, KernelMode, &ObjectHandleA1 ); ObOpenObjectByPointer( ObjectBodyB, OBJ_CASE_INSENSITIVE, 0L, NULL, ObjectTypeB, KernelMode, &ObjectHandleB1 ); DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyA, ObjectHandleA1 ); DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyB, ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByHandle( ObjectHandleA1, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB1, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); NtClose( ObjectHandleA1 ); NtClose( ObjectHandleB1 ); NtClose( ObjectHandleA2 ); NtClose( ObjectHandleB2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); TestFunction = NULL; return( TRUE ); }
NTSTATUS GetAllDiskObjects() /*++ Routine Description: Enumeration all disk devices Arguments: None Return Value: None --*/ { NTSTATUS Status; PDRIVER_OBJECT pDiskObject; PDEVICE_OBJECT pDeviceObjectTemp; UNICODE_STRING DestinationString; DWORD dwDeviceNumber; DWORD dwRetLength; POBJECT_NAME_INFORMATION pNameBuffer; WCHAR *pNameTemp; PDISK_OBJ pDisk; PDISK_GEOMETRY pDiskGeometry; BOOLEAN bIsFound = FALSE; PDEVICE_EXTENSION pDevExtn = (PDEVICE_EXTENSION)gp_DevObj->DeviceExtension; /* All Disk Objects are created by disk.sys driver*/ RtlInitUnicodeString(&DestinationString, L"\\Driver\\Disk"); // Not a documented function in DDK, see import definition in sector.h if (ObReferenceObjectByName(&DestinationString, 64, 0, 0, *IoDriverObjectType, KernelMode, 0, &pDiskObject) >= 0) { pDeviceObjectTemp = pDiskObject->DeviceObject; dwDeviceNumber = 0; if (pDeviceObjectTemp) { pDiskGeometry = ExAllocatePool(NonPagedPool, sizeof(DISK_GEOMETRY)); if (!pDiskGeometry) { return STATUS_INSUFFICIENT_RESOURCES; } do { //Each time memset the geometry structure to zero memset(pDiskGeometry, 0x00, sizeof(DISK_GEOMETRY)); // DeviceType 7 corresponds to FILE_DISK_DEVICE Type Device Object and // It should have name too that's why Flags is check for 0x40 (DO_DEVICE_HAS_NAME ) //DbgPrint("DeviceType: %d", pDeviceObjectTemp->DeviceType); if (pDeviceObjectTemp->DeviceType == 7 && (pDeviceObjectTemp->Flags & 0x40)) { ObQueryNameString(pDeviceObjectTemp, NULL, 0, &dwRetLength); pNameBuffer = (POBJECT_NAME_INFORMATION) ExAllocatePoolWithTag(PagedPool, dwRetLength, ' sFI'); if (!pNameBuffer) { ExFreePool(pDiskGeometry); return STATUS_INSUFFICIENT_RESOURCES; } if (ObQueryNameString(pDeviceObjectTemp, pNameBuffer, dwRetLength, &dwRetLength) == STATUS_SUCCESS && pNameBuffer->Name.Buffer) { //DbgPrint("pNameBuffer->Name.Buffer: %ws", pNameBuffer->Name.Buffer); pDisk = ExAllocatePool(PagedPool, sizeof(DISK_OBJ)); if (!pDisk) { ExFreePool(pDiskGeometry); ExFreePool(pNameBuffer); return STATUS_INSUFFICIENT_RESOURCES; } for (pNameTemp = pNameBuffer->Name.Buffer + wcslen(pNameBuffer->Name.Buffer); pNameTemp > pNameBuffer->Name.Buffer; pNameTemp--) { //DbgPrint("pNameTemp: %ws", pNameTemp); if (!_wcsnicmp(pNameTemp, L"\\DR", 3)) { pDisk->bIsRawDiskObj = TRUE; bIsFound = TRUE; break; } else if (!_wcsnicmp(pNameTemp, L"\\DP(", 4)) { pDisk->bIsRawDiskObj = FALSE; bIsFound = TRUE; break; } } if (bIsFound) { pDisk->dwDiskOrdinal = (USHORT)pNameBuffer-> Name.Buffer[wcslen(pNameBuffer->Name.Buffer)-1] - (USHORT) L'0'; pDisk->pDiskDevObj = pDeviceObjectTemp; ExInterlockedInsertTailList(&pDevExtn->list_head, &pDisk->list, &pDevExtn->list_lock); Status = GetGeometry(pDisk->pDiskDevObj, pDiskGeometry); if (!NT_SUCCESS(Status)) { pDisk->bGeometryFound = FALSE; } else { pDisk->bGeometryFound = TRUE; pDisk->ulSectorSize = pDiskGeometry->BytesPerSector; } } //end of if (bIsFound) }//end of if (ObQueryNameString ...) ExFreePoolWithTag(pNameBuffer, 0); }//end of if (pDeviceObjectTemp->DeviceType == 7 ...) pDeviceObjectTemp = pDeviceObjectTemp->NextDevice; } while (pDeviceObjectTemp); // end of while ExFreePool(pDiskGeometry); //Free pDiskGeometry } } return STATUS_SUCCESS; }
/* * @implemented */ NTSTATUS NTAPI NtSecureConnectPort(OUT PHANDLE PortHandle, IN PUNICODE_STRING PortName, IN PSECURITY_QUALITY_OF_SERVICE Qos, IN OUT PPORT_VIEW ClientView OPTIONAL, IN PSID ServerSid OPTIONAL, IN OUT PREMOTE_PORT_VIEW ServerView OPTIONAL, OUT PULONG MaxMessageLength OPTIONAL, IN OUT PVOID ConnectionInformation OPTIONAL, IN OUT PULONG ConnectionInformationLength OPTIONAL) { ULONG ConnectionInfoLength = 0; PLPCP_PORT_OBJECT Port, ClientPort; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); NTSTATUS Status = STATUS_SUCCESS; HANDLE Handle; PVOID SectionToMap; PLPCP_MESSAGE Message; PLPCP_CONNECTION_MESSAGE ConnectMessage; PETHREAD Thread = PsGetCurrentThread(); ULONG PortMessageLength; LARGE_INTEGER SectionOffset; PTOKEN Token; PTOKEN_USER TokenUserInfo; PAGED_CODE(); LPCTRACE(LPC_CONNECT_DEBUG, "Name: %wZ. Qos: %p. Views: %p/%p. Sid: %p\n", PortName, Qos, ClientView, ServerView, ServerSid); /* Validate client view */ if ((ClientView) && (ClientView->Length != sizeof(PORT_VIEW))) { /* Fail */ return STATUS_INVALID_PARAMETER; } /* Validate server view */ if ((ServerView) && (ServerView->Length != sizeof(REMOTE_PORT_VIEW))) { /* Fail */ return STATUS_INVALID_PARAMETER; } /* Check if caller sent connection information length */ if (ConnectionInformationLength) { /* Retrieve the input length */ ConnectionInfoLength = *ConnectionInformationLength; } /* Get the port */ Status = ObReferenceObjectByName(PortName, 0, NULL, PORT_CONNECT, LpcPortObjectType, PreviousMode, NULL, (PVOID *)&Port); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to reference port '%wZ': 0x%lx\n", PortName, Status); return Status; } /* This has to be a connection port */ if ((Port->Flags & LPCP_PORT_TYPE_MASK) != LPCP_CONNECTION_PORT) { /* It isn't, so fail */ ObDereferenceObject(Port); return STATUS_INVALID_PORT_HANDLE; } /* Check if we have a SID */ if (ServerSid) { /* Make sure that we have a server */ if (Port->ServerProcess) { /* Get its token and query user information */ Token = PsReferencePrimaryToken(Port->ServerProcess); //Status = SeQueryInformationToken(Token, TokenUser, (PVOID*)&TokenUserInfo); // FIXME: Need SeQueryInformationToken Status = STATUS_SUCCESS; TokenUserInfo = ExAllocatePoolWithTag(PagedPool, sizeof(TOKEN_USER), TAG_SE); TokenUserInfo->User.Sid = ServerSid; PsDereferencePrimaryToken(Token); /* Check for success */ if (NT_SUCCESS(Status)) { /* Compare the SIDs */ if (!RtlEqualSid(ServerSid, TokenUserInfo->User.Sid)) { /* Fail */ Status = STATUS_SERVER_SID_MISMATCH; } /* Free token information */ ExFreePoolWithTag(TokenUserInfo, TAG_SE); } } else { /* Invalid SID */ Status = STATUS_SERVER_SID_MISMATCH; } /* Check if SID failed */ if (!NT_SUCCESS(Status)) { /* Quit */ ObDereferenceObject(Port); return Status; } } /* Create the client port */ Status = ObCreateObject(PreviousMode, LpcPortObjectType, NULL, PreviousMode, NULL, sizeof(LPCP_PORT_OBJECT), 0, 0, (PVOID *)&ClientPort); if (!NT_SUCCESS(Status)) { /* Failed, dereference the server port and return */ ObDereferenceObject(Port); return Status; } /* Setup the client port */ RtlZeroMemory(ClientPort, sizeof(LPCP_PORT_OBJECT)); ClientPort->Flags = LPCP_CLIENT_PORT; ClientPort->ConnectionPort = Port; ClientPort->MaxMessageLength = Port->MaxMessageLength; ClientPort->SecurityQos = *Qos; InitializeListHead(&ClientPort->LpcReplyChainHead); InitializeListHead(&ClientPort->LpcDataInfoChainHead); /* Check if we have dynamic security */ if (Qos->ContextTrackingMode == SECURITY_DYNAMIC_TRACKING) { /* Remember that */ ClientPort->Flags |= LPCP_SECURITY_DYNAMIC; } else { /* Create our own client security */ Status = SeCreateClientSecurity(Thread, Qos, FALSE, &ClientPort->StaticSecurity); if (!NT_SUCCESS(Status)) { /* Security failed, dereference and return */ ObDereferenceObject(ClientPort); return Status; } } /* Initialize the port queue */ Status = LpcpInitializePortQueue(ClientPort); if (!NT_SUCCESS(Status)) { /* Failed */ ObDereferenceObject(ClientPort); return Status; } /* Check if we have a client view */ if (ClientView) { /* Get the section handle */ Status = ObReferenceObjectByHandle(ClientView->SectionHandle, SECTION_MAP_READ | SECTION_MAP_WRITE, MmSectionObjectType, PreviousMode, (PVOID*)&SectionToMap, NULL); if (!NT_SUCCESS(Status)) { /* Fail */ ObDereferenceObject(Port); return Status; } /* Set the section offset */ SectionOffset.QuadPart = ClientView->SectionOffset; /* Map it */ Status = MmMapViewOfSection(SectionToMap, PsGetCurrentProcess(), &ClientPort->ClientSectionBase, 0, 0, &SectionOffset, &ClientView->ViewSize, ViewUnmap, 0, PAGE_READWRITE); /* Update the offset */ ClientView->SectionOffset = SectionOffset.LowPart; /* Check for failure */ if (!NT_SUCCESS(Status)) { /* Fail */ ObDereferenceObject(SectionToMap); ObDereferenceObject(Port); return Status; } /* Update the base */ ClientView->ViewBase = ClientPort->ClientSectionBase; /* Reference and remember the process */ ClientPort->MappingProcess = PsGetCurrentProcess(); ObReferenceObject(ClientPort->MappingProcess); } else { /* No section */ SectionToMap = NULL; } /* Normalize connection information */ if (ConnectionInfoLength > Port->MaxConnectionInfoLength) { /* Use the port's maximum allowed value */ ConnectionInfoLength = Port->MaxConnectionInfoLength; } /* Allocate a message from the port zone */ Message = LpcpAllocateFromPortZone(); if (!Message) { /* Fail if we couldn't allocate a message */ if (SectionToMap) ObDereferenceObject(SectionToMap); ObDereferenceObject(ClientPort); return STATUS_NO_MEMORY; } /* Set pointer to the connection message and fill in the CID */ ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1); Message->Request.ClientId = Thread->Cid; /* Check if we have a client view */ if (ClientView) { /* Set the view size */ Message->Request.ClientViewSize = ClientView->ViewSize; /* Copy the client view and clear the server view */ RtlCopyMemory(&ConnectMessage->ClientView, ClientView, sizeof(PORT_VIEW)); RtlZeroMemory(&ConnectMessage->ServerView, sizeof(REMOTE_PORT_VIEW)); } else { /* Set the size to 0 and clear the connect message */ Message->Request.ClientViewSize = 0; RtlZeroMemory(ConnectMessage, sizeof(LPCP_CONNECTION_MESSAGE)); } /* Set the section and client port. Port is NULL for now */ ConnectMessage->ClientPort = NULL; ConnectMessage->SectionToMap = SectionToMap; /* Set the data for the connection request message */ Message->Request.u1.s1.DataLength = (CSHORT)ConnectionInfoLength + sizeof(LPCP_CONNECTION_MESSAGE); Message->Request.u1.s1.TotalLength = sizeof(LPCP_MESSAGE) + Message->Request.u1.s1.DataLength; Message->Request.u2.s2.Type = LPC_CONNECTION_REQUEST; /* Check if we have connection information */ if (ConnectionInformation) { /* Copy it in */ RtlCopyMemory(ConnectMessage + 1, ConnectionInformation, ConnectionInfoLength); } /* Acquire the port lock */ KeAcquireGuardedMutex(&LpcpLock); /* Check if someone already deleted the port name */ if (Port->Flags & LPCP_NAME_DELETED) { /* Fail the request */ Status = STATUS_OBJECT_NAME_NOT_FOUND; } else { /* Associate no thread yet */ Message->RepliedToThread = NULL; /* Generate the Message ID and set it */ Message->Request.MessageId = LpcpNextMessageId++; if (!LpcpNextMessageId) LpcpNextMessageId = 1; Thread->LpcReplyMessageId = Message->Request.MessageId; /* Insert the message into the queue and thread chain */ InsertTailList(&Port->MsgQueue.ReceiveHead, &Message->Entry); InsertTailList(&Port->LpcReplyChainHead, &Thread->LpcReplyChain); Thread->LpcReplyMessage = Message; /* Now we can finally reference the client port and link it*/ ObReferenceObject(ClientPort); ConnectMessage->ClientPort = ClientPort; /* Enter a critical region */ KeEnterCriticalRegion(); } /* Add another reference to the port */ ObReferenceObject(Port); /* Release the lock */ KeReleaseGuardedMutex(&LpcpLock); /* Check for success */ if (NT_SUCCESS(Status)) { LPCTRACE(LPC_CONNECT_DEBUG, "Messages: %p/%p. Ports: %p/%p. Status: %lx\n", Message, ConnectMessage, Port, ClientPort, Status); /* If this is a waitable port, set the event */ if (Port->Flags & LPCP_WAITABLE_PORT) KeSetEvent(&Port->WaitEvent, 1, FALSE); /* Release the queue semaphore and leave the critical region */ LpcpCompleteWait(Port->MsgQueue.Semaphore); KeLeaveCriticalRegion(); /* Now wait for a reply */ LpcpConnectWait(&Thread->LpcReplySemaphore, PreviousMode); } /* Check for failure */ if (!NT_SUCCESS(Status)) goto Cleanup; /* Free the connection message */ SectionToMap = LpcpFreeConMsg(&Message, &ConnectMessage, Thread); /* Check if we got a message back */ if (Message) { /* Check for new return length */ if ((Message->Request.u1.s1.DataLength - sizeof(LPCP_CONNECTION_MESSAGE)) < ConnectionInfoLength) { /* Set new normalized connection length */ ConnectionInfoLength = Message->Request.u1.s1.DataLength - sizeof(LPCP_CONNECTION_MESSAGE); } /* Check if we had connection information */ if (ConnectionInformation) { /* Check if we had a length pointer */ if (ConnectionInformationLength) { /* Return the length */ *ConnectionInformationLength = ConnectionInfoLength; } /* Return the connection information */ RtlCopyMemory(ConnectionInformation, ConnectMessage + 1, ConnectionInfoLength ); } /* Make sure we had a connected port */ if (ClientPort->ConnectedPort) { /* Get the message length before the port might get killed */ PortMessageLength = Port->MaxMessageLength; /* Insert the client port */ Status = ObInsertObject(ClientPort, NULL, PORT_ALL_ACCESS, 0, (PVOID *)NULL, &Handle); if (NT_SUCCESS(Status)) { /* Return the handle */ *PortHandle = Handle; LPCTRACE(LPC_CONNECT_DEBUG, "Handle: %p. Length: %lx\n", Handle, PortMessageLength); /* Check if maximum length was requested */ if (MaxMessageLength) *MaxMessageLength = PortMessageLength; /* Check if we had a client view */ if (ClientView) { /* Copy it back */ RtlCopyMemory(ClientView, &ConnectMessage->ClientView, sizeof(PORT_VIEW)); } /* Check if we had a server view */ if (ServerView) { /* Copy it back */ RtlCopyMemory(ServerView, &ConnectMessage->ServerView, sizeof(REMOTE_PORT_VIEW)); } } } else { /* No connection port, we failed */ if (SectionToMap) ObDereferenceObject(SectionToMap); /* Acquire the lock */ KeAcquireGuardedMutex(&LpcpLock); /* Check if it's because the name got deleted */ if (!(ClientPort->ConnectionPort) || (Port->Flags & LPCP_NAME_DELETED)) { /* Set the correct status */ Status = STATUS_OBJECT_NAME_NOT_FOUND; } else { /* Otherwise, the caller refused us */ Status = STATUS_PORT_CONNECTION_REFUSED; } /* Release the lock */ KeReleaseGuardedMutex(&LpcpLock); /* Kill the port */ ObDereferenceObject(ClientPort); } /* Free the message */ LpcpFreeToPortZone(Message, 0); } else { /* No reply message, fail */ if (SectionToMap) ObDereferenceObject(SectionToMap); ObDereferenceObject(ClientPort); Status = STATUS_PORT_CONNECTION_REFUSED; } /* Return status */ ObDereferenceObject(Port); return Status; Cleanup: /* We failed, free the message */ SectionToMap = LpcpFreeConMsg(&Message, &ConnectMessage, Thread); /* Check if the semaphore got signaled */ if (KeReadStateSemaphore(&Thread->LpcReplySemaphore)) { /* Wait on it */ KeWaitForSingleObject(&Thread->LpcReplySemaphore, WrExecutive, KernelMode, FALSE, NULL); } /* Check if we had a message and free it */ if (Message) LpcpFreeToPortZone(Message, 0); /* Dereference other objects */ if (SectionToMap) ObDereferenceObject(SectionToMap); ObDereferenceObject(ClientPort); /* Return status */ ObDereferenceObject(Port); return Status; }
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryPath) { UNICODE_STRING uDriverName = {0}; NTSTATUS status = 0; PDRIVER_OBJECT pDiskDriv = NULL; PDEVICE_OBJECT pHdDevice = NULL; PCHAR pBuf = NULL; LARGE_INTEGER offset = {0}; PDEVICE_OBJECT pDevice = NULL; PDEVICE_EXTENSION pDevExt = NULL; DWORD bufsize = 0; pDriverObj->DriverUnload = Unload; DbgPrint("[ Loading .. ]\n", pDriverObj); /** <INIT> **/ DbgPrint("Initialization.."); RtlInitUnicodeString(&uDriverName, L"\\Driver\\Disk"); status = IoCreateDevice(pDriverObj, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &pDevice); if(!NT_SUCCESS(status)) { ExFreePoolWithTag(pBuf, 't4pz'); DbgPrint("\n[!] Error at IoCreateDevice() : 0x%x.\n", status); return STATUS_UNSUCCESSFUL; } pDevExt = (PDEVICE_EXTENSION)pDevice->DeviceExtension; RtlSecureZeroMemory(pDevExt, sizeof(DEVICE_EXTENSION)); DbgPrint("[OK] -> 0x%x.\n", pDevExt); /** </INIT> **/ /** <RAW DISK DEVICE POINTER> **/ DbgPrint("Retrieving \\Driver\\Disk.sys' driver object pointer.."); status = ObReferenceObjectByName(&uDriverName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, 0, &pDiskDriv ); if(!NT_SUCCESS(status)) { DbgPrint("\n[!] Error at ObReferenceObjectsByName() : 0x%x.\n", status); return STATUS_UNSUCCESSFUL; } DbgPrint("[OK] -> 0x%x.\n", pDiskDriv); pHdDevice = pDiskDriv->DeviceObject; DbgPrint("HardDisk 0 device pointer : 0x%x\n", pHdDevice); /** </RAW DISK DEVICE POINTER> **/ /** <DISK GEOMETRY> **/ DbgPrint("Trying to obtain disk geometry..\n"); if(FindDiskGeometry(pHdDevice, &pDevExt->diskGeometry) == FALSE) { DbgPrint("\n[!] Error at FindDiskGeometry().\n"); return STATUS_UNSUCCESSFUL; } DbgPrint("[OK]\nYou have %d%d cylinders\nA cylinders is composed of %d tracks\nA Track is composed of %d sectors\nA Sector is composed of %d bytes.\n", pDevExt->diskGeometry.Cylinders.HighPart, pDevExt->diskGeometry.Cylinders.LowPart, pDevExt->diskGeometry.TracksPerCylinder, pDevExt->diskGeometry.SectorsPerTrack, pDevExt->diskGeometry.BytesPerSector); bufsize = pDevExt->diskGeometry.BytesPerSector; /** </DISK GEOMETRY> **/ /** <ALLOCATION> **/ DbgPrint("Allocating memory.."); pBuf = ExAllocatePoolWithTag(NonPagedPool, bufsize, 't4pz'); if(pBuf == NULL) { DbgPrint("\n[!] Error at ExAllocatePoolWithTag().\n"); return STATUS_UNSUCCESSFUL; } RtlSecureZeroMemory(pBuf, BUFSIZE); pDevExt->pBuf = pBuf; DbgPrint("[OK] -> 0x%x\n", pBuf); /** <ALLOCATION> **/ /** <READ REQUEST> **/ DbgPrint("Making a read request..\n"); status = MakeReadWriteRequest(pHdDevice, IRP_MJ_READ, pBuf, bufsize, &offset); if(!NT_SUCCESS(status)) { ExFreePoolWithTag(pBuf, 't4pz'); DbgPrint("[!] Error at MakeReadWriteRequest().\n"); return STATUS_UNSUCCESSFUL; } DbgPrint("[OK] -> 0x%x.\n", pBuf); //RtlSecureZeroMemory(pBuf, bufsize); /** </ READ REQUEST> **/ return STATUS_SUCCESS; }
NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath ) { NTSTATUS Status; UNICODE_STRING KbdDriverName; ULONG Idx; PDEVICE_OBJECT DeviceObject; UNREFERENCED_PARAMETER(RegistryPath); DPF(( "*** %s.sys Loaded ***\n", __MODULE__ )); DriverObject->DriverUnload = DriverUnload; // store the filters driver object g_FilterDriverObject = DriverObject; RtlInitUnicodeString ( &KbdDriverName, DRIVER_NAME_KBDCLASS ); // Using the name KbdDriverName obtain a pointer to the driver // object and store it in g_OriginalDriverObject Status = ObReferenceObjectByName ( &KbdDriverName, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, &g_OriginalDriverObject ); if ( ! NT_SUCCESS(Status) ) { DPF(("%s!%s ObReferenceObjectByName(%wZ) : FAIL=%08x\n" , __MODULE__, __FUNCTION__, &KbdDriverName, Status )); goto Exit; } DPF(( "%s!%s g_OriginalDriverObject=%p\n", __MODULE__, __FUNCTION__, g_OriginalDriverObject )); // Step #1 : Copy all the dispatch routines (IRP_MJ_CREATE - IRP_MJ_PNP) pointer // from the keyboard driver object to the filter driver object // Save the original IRP_MJ_READ dispatch routine into g_OriginalDispatchRead // and setup HookDispatchRead() as the new dispatch routine g_OriginalDispatchRead = g_FilterDriverObject->MajorFunction[IRP_MJ_READ]; g_FilterDriverObject->MajorFunction[IRP_MJ_READ] = HookDispatchRead; // Step #2 : For all the device objects created by the keyboard class driver // -force them to point to the filter driver's driver object // -increment their StackSize field return STATUS_SUCCESS; Exit : if ( g_OriginalDriverObject ) { // Dereference the original driver object (ObDereferenceObject()) ObDereferenceObject ( g_OriginalDriverObject ); g_OriginalDriverObject = NULL; } return Status; } // DriverEntry()
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath) { for(int i_Dispatch = 0; i_Dispatch < IRP_MJ_MAXIMUM_FUNCTION; i_Dispatch++) { pDriverObject->MajorFunction[i_Dispatch] = DriverCommonDispatch; } pDriverObject->MajorFunction[IRP_MJ_POWER] = DriverPower; pDriverObject->MajorFunction[IRP_MJ_PNP] = DriverPNP; pDriverObject->MajorFunction[IRP_MJ_READ] = DriverRead; pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverControl; pDriverObject->DriverUnload = DriverUnload; //打开kbdclass驱动对象 PDRIVER_OBJECT tDriObjKdbclass; UNICODE_STRING tKbdclassName; RtlInitUnicodeString(&tKbdclassName,L"\\Driver\\Kbdclass"); NTSTATUS tStatus = ObReferenceObjectByName(&tKbdclassName,OBJ_CASE_INSENSITIVE,0,FILE_ALL_ACCESS,IoDeviceObjectType,KernelMode,0,(PVOID*)&tDriObjKdbclass); if(false == NT_SUCCESS(tStatus)) { return STATUS_UNSUCCESSFUL; } else { ObDereferenceObject(tDriObjKdbclass); } //创建并绑定设备 bool tAttch = false; PDEVICE_OBJECT tTargetDevObj = tDriObjKdbclass->DeviceObject; //kbdclass下的设备对象 while(0 != tTargetDevObj) { tAttch = true; PDEVICE_OBJECT tMyDeviceObject; tStatus = IoCreateDevice(pDriverObject,sizeof(MYDEVICE_EXTENSION),0,tTargetDevObj->DeviceType,tTargetDevObj->Characteristics,FALSE,&tMyDeviceObject); if(false == NT_SUCCESS(tStatus)) { return STATUS_UNSUCCESSFUL; //之前的设备要不要删掉? } tMyDeviceObject->Flags |= tTargetDevObj->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE); PMYDEVICE_EXTENSION tDevExtend = (PMYDEVICE_EXTENSION)tMyDeviceObject->DeviceExtension; tDevExtend->LowDeviceObj = IoAttachDeviceToDeviceStack(tMyDeviceObject,tTargetDevObj); if(0 == tDevExtend->LowDeviceObj) { IoDeleteDevice(tMyDeviceObject); return STATUS_UNSUCCESSFUL; } tMyDeviceObject->Flags = tMyDeviceObject->Flags & ~DO_DEVICE_INITIALIZING; tTargetDevObj = tTargetDevObj->NextDevice; } if(false == tAttch) { return STATUS_UNSUCCESSFUL; } //创建主控设备 UNICODE_STRING tMasterDevObjName; RtlInitUnicodeString(&tMasterDevObjName,__T(DEVICE_NAME_KBDFILTER)); tStatus = IoCreateDevice(pDriverObject,sizeof(MYDEVICE_EXTENSION),&tMasterDevObjName,FILE_DEVICE_UNKNOWN,0,FALSE,&g_MasterDeviceObj); if(false == NT_SUCCESS(tStatus)) { return STATUS_UNSUCCESSFUL; } UNICODE_STRING tMasterDevObjSymbol; RtlInitUnicodeString(&tMasterDevObjSymbol,__T(DEVICE_NAME_KBDFILTER_SYMBOL)); tStatus = IoCreateSymbolicLink(&tMasterDevObjSymbol,&tMasterDevObjName); if(false == NT_SUCCESS(tStatus)) { return STATUS_UNSUCCESSFUL; } g_MasterDeviceObj->Flags |= (DO_BUFFERED_IO | DO_DIRECT_IO); return STATUS_SUCCESS; }
NTSTATUS HotKeyKrnlAttachDevices( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status = 0; UNICODE_STRING uniNtNameString; PDEVICE_EXTENSION devExt; PDEVICE_OBJECT pFilterDeviceObject = NULL; PDEVICE_OBJECT pTargetDeviceObject = NULL; PDEVICE_OBJECT pLowerDeviceObject = NULL; PDRIVER_OBJECT KbdDriverObject = NULL; extern POBJECT_TYPE *IoDriverObjectType; // Exported by ntoskrnl.exe, shit ! // ref kbdclass driver object RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME); status = ObReferenceObjectByName(&uniNtNameString, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, &KbdDriverObject); if(!NT_SUCCESS(status)) { KdPrint(("[shadow] ObReferenceObjectByName failed,cann't access Kbdclass.\n")); return status; } else { ObDereferenceObject(KbdDriverObject); } // 绑定该驱动对象中的所有设备对象 pTargetDeviceObject = KbdDriverObject->DeviceObject; while (pTargetDeviceObject) { // 创建过滤设备 status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, pTargetDeviceObject->DeviceType, pTargetDeviceObject->Characteristics, FALSE, &pFilterDeviceObject); if (!NT_SUCCESS(status)) { KdPrint(("[shadow] IoCreateDevice(filter device) failed.\n")); return status; } // 绑定 if(!(pLowerDeviceObject = IoAttachDeviceToDeviceStack(pFilterDeviceObject, pTargetDeviceObject))) { KdPrint(("[shadow] IoAttachDeviceToDeviceStack failed.\n")); IoDeleteDevice(pFilterDeviceObject); pFilterDeviceObject = NULL; return status; } devExt = (PDEVICE_EXTENSION)(pFilterDeviceObject->DeviceExtension); RtlZeroMemory(devExt, sizeof(DEVICE_EXTENSION)); devExt->NodeSize = sizeof(DEVICE_EXTENSION); devExt->pFilterDeviceObject = pFilterDeviceObject; devExt->TargetDeviceObject = pTargetDeviceObject; devExt->LowerDeviceObject = pLowerDeviceObject; pFilterDeviceObject->DeviceType = pLowerDeviceObject->DeviceType; pFilterDeviceObject->Characteristics = pLowerDeviceObject->Characteristics; pFilterDeviceObject->StackSize = pLowerDeviceObject->StackSize+1; pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE); pTargetDeviceObject = pTargetDeviceObject->NextDevice; } return status; }
VOID TDIThread(PVOID pData) { PVOID eventArray[2]; const ULONG ulNumEvents = sizeof(eventArray)/sizeof(eventArray[0]); NTSTATUS status; LARGE_INTEGER liTimeout; UNICODE_STRING drv_name; ULONG ulTotalTime = 0; RtlInitUnicodeString(&drv_name, L"\\Driver\\Tcpip"); // Start event is Initialized externally to avoid race conditions KeInitializeEvent(&g_TDIThreadShutdownEvent, NotificationEvent, FALSE); eventArray[0] = &g_TDIThreadShutdownEvent; eventArray[1] = &g_TDIThreadStartEvent; status = KeWaitForMultipleObjects(ulNumEvents, eventArray, WaitAny, Executive, KernelMode, FALSE, NULL, NULL); switch(status) { case 0: // Shutdown! PsTerminateSystemThread(STATUS_SUCCESS); return; case 1: break; default: DBGOUT(("TDI Thread KeWaitForMultipleObjects failed! ErrorCode %08X", status)); PsTerminateSystemThread(STATUS_UNSUCCESSFUL); return; } // Timeouts are in units of 100 nanoseconds. // Negative timeout values are treated as relative time. liTimeout.QuadPart = (long)TDI_RETRY_TIMER * (1000 * 1000 * 10 * -1); DBGOUT(("TDI Thread Initialized! Will loop every %d seconds looking for TCPIP Driver", TDI_RETRY_TIMER)); while(1) { status = KeWaitForSingleObject(&g_TDIThreadShutdownEvent, Executive, KernelMode, FALSE, &liTimeout); DBGOUT(("KeWaitForSingleObject returned 0x%08X", status)); switch(status) { case 0: // Shutdown event! thread_exit: PsTerminateSystemThread(STATUS_SUCCESS); return; case STATUS_TIMEOUT: // Data on our pipe { // See if TCPIP.sys is loaded yet: status = ObReferenceObjectByName(&drv_name, OBJ_CASE_INSENSITIVE, NULL, 0, IoDriverObjectType, KernelMode, NULL, &g_pTCPIPDriverObject); if(status == STATUS_SUCCESS) { DBGOUT(("TDI Driver Hooked!")); status = InitTDIHook(); if(status != STATUS_SUCCESS) DBGOUT(("Unable to Initialize TDI Hook Driver!")); goto thread_exit; } else { DBGOUT(("Did not find TCPIP.sys driver. Going to sleep")); ulTotalTime += TDI_RETRY_TIMER; if(ulTotalTime < TDI_INIT_TIMEOUT) continue; else { // ERROR OUT DBGOUT(("Never found TCPIP Driver after %d seconds. Failing!!!", TDI_INIT_TIMEOUT)); goto thread_exit; } } } break; default: DBGOUT(("Unknown status from KeWaitForSingleObject! Status: 0x%08X\n", status)); goto thread_exit; } } }