一段文件删除代码(动态加载驱动)

来源:互联网 发布:神仙劫羽翼进阶数据 编辑:程序博客网 时间:2024/05/09 17:27
#include <ntddk.h>#define NT_DEVICE_NAME                L"\\Device\\SuperKill"#define DOS_DEVICE_NAME               L"\\DosDevices\\SuperKill"VOID SKillUnloadDriver(   IN PDRIVER_OBJECT    DriverObject   ){PDEVICE_OBJECT    deviceObject = DriverObject->DeviceObject;UNICODE_STRING    uniSymLink;RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);IoDeleteSymbolicLink(&uniSymLink);IoDeleteDevice(deviceObject);}HANDLESkillIoOpenFile(IN PCWSTR FileName,IN ACCESS_MASK DesiredAccess,IN ULONG ShareAccess){NTSTATUS              ntStatus;UNICODE_STRING        uniFileName;OBJECT_ATTRIBUTES     objectAttributes;HANDLE                ntFileHandle;IO_STATUS_BLOCK       ioStatus;if (KeGetCurrentIrql() > PASSIVE_LEVEL){return 0;}RtlInitUnicodeString(&uniFileName, FileName);InitializeObjectAttributes(&objectAttributes, &uniFileName,OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);ntStatus = IoCreateFile(&ntFileHandle,DesiredAccess,&objectAttributes,&ioStatus,0,FILE_ATTRIBUTE_NORMAL,ShareAccess,FILE_OPEN,0,NULL,0,0,NULL,IO_NO_PARAMETER_CHECKING);if (!NT_SUCCESS(ntStatus)){return 0;}return ntFileHandle;}NTSTATUSSkillSetFileCompletion(   IN PDEVICE_OBJECT DeviceObject,   IN PIRP Irp,   IN PVOID Context   ){Irp->UserIosb->Status = Irp->IoStatus.Status;Irp->UserIosb->Information = Irp->IoStatus.Information;KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE);IoFreeIrp(Irp);return STATUS_MORE_PROCESSING_REQUIRED;}BOOLEANSKillStripFileAttributes( IN HANDLE    FileHandle ){NTSTATUS          ntStatus = STATUS_SUCCESS;PFILE_OBJECT      fileObject;PDEVICE_OBJECT    DeviceObject;PIRP              Irp;KEVENT            event1;FILE_BASIC_INFORMATION    FileInformation;IO_STATUS_BLOCK ioStatus;PIO_STACK_LOCATION irpSp;ntStatus = ObReferenceObjectByHandle(FileHandle,DELETE,*IoFileObjectType,KernelMode,&fileObject,NULL);//我想知道的是这个文件句柄是在哪个进程的句柄表中if (!NT_SUCCESS(ntStatus)){return FALSE;}DeviceObject = IoGetRelatedDeviceObject(fileObject);Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);if (Irp == NULL){ObDereferenceObject(fileObject);return FALSE;}KeInitializeEvent(&event1, SynchronizationEvent, FALSE);memset(&FileInformation,0,0x28);FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;Irp->AssociatedIrp.SystemBuffer = &FileInformation;Irp->UserEvent = &event1;Irp->UserIosb = &ioStatus;Irp->Tail.Overlay.OriginalFileObject = fileObject;Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();Irp->RequestorMode = KernelMode;irpSp = IoGetNextIrpStackLocation(Irp);irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;irpSp->DeviceObject = DeviceObject;irpSp->FileObject = fileObject;irpSp->Parameters.SetFile.Length = sizeof(FILE_BASIC_INFORMATION);irpSp->Parameters.SetFile.FileInformationClass = FileBasicInformation;irpSp->Parameters.SetFile.FileObject = fileObject;IoSetCompletionRoutine(Irp,SkillSetFileCompletion,&event1,TRUE,TRUE,TRUE);IoCallDriver(DeviceObject, Irp);//调用这个设备对象的驱动对象,并且IO_StACK_LOCAtion会指向下一个,也就是刚刚设置的    //如果没有文件系统驱动建立的设备对象没有Attacked的话,就调用文件系统驱动的IRP_MJ_SET_INFORMATION分派例程//会调用NTFS.sys驱动的NtfsFsdSetInformation例程,再会进入NtfsSetBasicInfo()函数,最后它会设置代表此文件的FCB(文件//控制块结构的一些信息,用来设置代表此文件的属性。最后不知道在哪里会调用IoCompleteRequest,它会依次调用先前设置的回调函数//回调函数会释放刚分配的IRP和设置事件对象为受信状态。KeWaitForSingleObject(&event1, Executive, KernelMode, TRUE, NULL);//一等到事件对象变成受信状态就会继续向下执行。ObDereferenceObject(fileObject);return TRUE;}BOOLEANSKillDeleteFile(IN HANDLE    FileHandle){NTSTATUS          ntStatus = STATUS_SUCCESS;PFILE_OBJECT      fileObject;PDEVICE_OBJECT    DeviceObject;PIRP              Irp;KEVENT            event1;FILE_DISPOSITION_INFORMATION    FileInformation;IO_STATUS_BLOCK ioStatus;PIO_STACK_LOCATION irpSp;PSECTION_OBJECT_POINTERS pSectionObjectPointer;     ////////////////////SKillStripFileAttributes( FileHandle);          //去掉只读属性,才能删除只读文件ntStatus = ObReferenceObjectByHandle(FileHandle,DELETE,*IoFileObjectType,KernelMode,&fileObject,NULL);if (!NT_SUCCESS(ntStatus)){return FALSE;}DeviceObject = IoGetRelatedDeviceObject(fileObject);//如果NTFS.sys驱动建立的设备对象上没有附加的设备对象的话,就返回NTFS.sys建立的设备对象//否则返回的是这个设备对象的highest level设备对象。Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);//如果没有附加,StackSize为7if (Irp == NULL){ObDereferenceObject(fileObject);return FALSE;}KeInitializeEvent(&event1, SynchronizationEvent, FALSE);FileInformation.DeleteFile = TRUE;Irp->AssociatedIrp.SystemBuffer = &FileInformation;Irp->UserEvent = &event1;Irp->UserIosb = &ioStatus;Irp->Tail.Overlay.OriginalFileObject = fileObject;Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();Irp->RequestorMode = KernelMode;irpSp = IoGetNextIrpStackLocation(Irp);            //得到文件系统NTFS.sys驱动的设备IO_STACK_LOCATIONirpSp->MajorFunction = IRP_MJ_SET_INFORMATION;irpSp->DeviceObject = DeviceObject;irpSp->FileObject = fileObject;irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;irpSp->Parameters.SetFile.FileObject = fileObject;IoSetCompletionRoutine(Irp,SkillSetFileCompletion,&event1,TRUE,TRUE,TRUE);//再加上下面这三行代码 ,MmFlushImageSection    函数通过这个结构来检查是否可以删除文件。pSectionObjectPointer = fileObject->SectionObjectPointer;pSectionObjectPointer->ImageSectionObject = 0;pSectionObjectPointer->DataSectionObject = 0;IoCallDriver(DeviceObject, Irp);//这里会依次进入NTFS.sys驱动的NtfsFsdSetInformation例程->NtfsSetDispositionInfo()->MmFlushImageSection(),//MmFlushImageSection()这函数是用来检查FILE_OBJECT对象的SECTION_OBJECT_POINTER结构的变量,检查这个文件//在内存有没有被映射。也就是有没有执行。如果上面那样设置了,也就是说文件可以删除了。我们也可以HOOK NTFS.sys导入表中的//的MmFlushImageSection(),来检查这个文件对象是不是我们要删除 的,是的话,返回TRUE就行了。KeWaitForSingleObject(&event1, Executive, KernelMode, TRUE, NULL);ObDereferenceObject(fileObject);return TRUE;}NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ){UNICODE_STRING                  uniDeviceName;UNICODE_STRING                  uniSymLink;NTSTATUS                          ntStatus;PDEVICE_OBJECT                  deviceObject = NULL;HANDLE                hFileHandle;RtlInitUnicodeString(&uniDeviceName, NT_DEVICE_NAME);RtlInitUnicodeString(&uniSymLink, DOS_DEVICE_NAME);ntStatus = IoCreateDevice(DriverObject,0x100u,&uniDeviceName,FILE_DEVICE_UNKNOWN,FILE_DEVICE_SECURE_OPEN,TRUE,&deviceObject);if (!NT_SUCCESS(ntStatus)){return ntStatus;}ntStatus = IoCreateSymbolicLink(&uniSymLink, &uniDeviceName);if (!NT_SUCCESS(ntStatus)){IoDeleteDevice(deviceObject);return ntStatus;}DriverObject->DriverUnload = SKillUnloadDriver;//// 重点在这//hFileHandle = SkillIoOpenFile(L"\\Device\\HarddiskVolume1\\", FILE_READ_ATTRIBUTES,FILE_SHARE_DELETE);   //得到文件句柄if (hFileHandle!=NULL){SKillDeleteFile(hFileHandle);ZwClose(hFileHandle);}return STATUS_SUCCESS;}


对应的测试代码:动态加载驱动服务程序

加载NT驱动的代码
1、调用OpenSCManager,打开SCM管理器
2、调用CreateService,创建服务,成功则到步骤6
3、用GetLastError得到错误返回值
4、如果创建错误,返回值为ERROR_IO_PENDING,说明服务已经创建过,不需要重新创建,用OpenService打开此服务
5、错误返回失败
6、调用StartService开启服务

7、成功返回


#include <windows.h>  #include <winsvc.h>  #include <conio.h>  #include <stdio.h>#define DRIVER_NAME  L"SuperKill"#define DRIVER_PATH  L"..\\SuperKill.sys"//装载NT驱动程序BOOL LoadNTDriver(LPTSTR lpszDriverName,LPTSTR lpszDriverPath){LPTSTR  szDriverImagePath=NULL;//得到完整的驱动路径//GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);szDriverImagePath=L"D:\\drivertest\\sure\\SuperKill.sys";BOOL bRet = FALSE;SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄//打开服务控制管理器hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );if( hServiceMgr == NULL )  {//OpenSCManager失败printf( "OpenSCManager() Faild %d ! \n", GetLastError() );bRet = FALSE;goto BeforeLeave;}else{////OpenSCManager成功printf( "OpenSCManager() ok ! \n" );  }//创建驱动所对应的服务hServiceDDK = CreateService( hServiceMgr,lpszDriverName, //驱动程序的在注册表中的名字  lpszDriverName, // 注册表驱动程序的 DisplayName 值  SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限  SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序  SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值  SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值  szDriverImagePath, // 注册表驱动程序的 ImagePath 值  NULL,  NULL,  NULL,  NULL,  NULL);  DWORD dwRtn;//判断服务是否失败if( hServiceDDK == NULL )  {  dwRtn = GetLastError();if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )  {  //由于其他原因创建服务失败printf( "CrateService() Faild %d ! \n", dwRtn );  bRet = FALSE;goto BeforeLeave;}  else  {//服务创建失败,是由于服务已经创立过printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" );  }// 驱动程序已经加载,只需要打开  hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS );  if( hServiceDDK == NULL )  {//如果打开服务也失败,则意味错误dwRtn = GetLastError();  printf( "OpenService() Faild %d ! \n", dwRtn );  bRet = FALSE;goto BeforeLeave;}  else {printf( "OpenService() ok ! \n" );}}  else  {printf( "CrateService() ok ! \n" );}//开启此项服务bRet= StartService( hServiceDDK, NULL, NULL );  if( !bRet )  {  DWORD dwRtn = GetLastError();  if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )  {  printf( "StartService() Faild %d ! \n", dwRtn );  bRet = FALSE;goto BeforeLeave;}  else  {  if( dwRtn == ERROR_IO_PENDING )  {  //设备被挂住printf( "StartService() Faild ERROR_IO_PENDING ! \n");bRet = FALSE;goto BeforeLeave;}  else  {  //服务已经开启printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n");bRet = TRUE;goto BeforeLeave;}  }  }bRet = TRUE;//离开前关闭句柄BeforeLeave:if(hServiceDDK){CloseServiceHandle(hServiceDDK);}if(hServiceMgr){CloseServiceHandle(hServiceMgr);}return bRet;}//卸载驱动程序  BOOL UnloadNTDriver( LPTSTR szSvrName )  {BOOL bRet = FALSE;SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄SERVICE_STATUS SvrSta;//打开SCM管理器hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );  if( hServiceMgr == NULL )  {//带开SCM管理器失败printf( "OpenSCManager() Faild %d ! \n", GetLastError() );  bRet = FALSE;goto BeforeLeave;}  else  {//带开SCM管理器失败成功printf( "OpenSCManager() ok ! \n" );  }//打开驱动所对应的服务hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS );  if( hServiceDDK == NULL )  {//打开驱动所对应的服务失败printf( "OpenService() Faild %d ! \n", GetLastError() );  bRet = FALSE;goto BeforeLeave;}  else  {  printf( "OpenService() ok ! \n" );  }  //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。  if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) )  {  printf( "ControlService() Faild %d !\n", GetLastError() );  }  else  {//打开驱动所对应的失败printf( "ControlService() ok !\n" );  }  //动态卸载驱动程序。  if( !DeleteService( hServiceDDK ) )  {//卸载失败printf( "DeleteSrevice() Faild %d !\n", GetLastError() );  }  else  {  //卸载成功printf( "DelServer:eleteSrevice() ok !\n" );  }  bRet = TRUE;BeforeLeave://离开前关闭打开的句柄if(hServiceDDK){CloseServiceHandle(hServiceDDK);}if(hServiceMgr){CloseServiceHandle(hServiceMgr);}return bRet;} void TestDriver(){//测试驱动程序  HANDLE hDevice = CreateFile(L"\\\\.\\SuperKill",  GENERIC_WRITE | GENERIC_READ,  0,  NULL,  OPEN_EXISTING,  0,  NULL);  if( hDevice != INVALID_HANDLE_VALUE )  {printf( "Create Device ok ! \n" );  }else  {printf( "Create Device faild %d ! \n", GetLastError() );  }CloseHandle( hDevice );} int main(int argc, char* argv[])  {//加载驱动BOOL bRet = LoadNTDriver(DRIVER_NAME,DRIVER_PATH);if (!bRet){printf("LoadNTDriver error\n");return 0;}//加载成功printf( "press any to create device!\n" );  //getch();  TestDriver();//这时候你可以通过注册表,或其他查看符号连接的软件验证。  printf( "press any to unload the driver!\n" );  //getch();  //卸载驱动UnloadNTDriver(DRIVER_NAME);if (!bRet){printf("UnloadNTDriver error\n");return 0;}return 0;  }  



原创粉丝点击