首页
社区
课程
招聘
[求助]Stop Service驱动后发生蓝屏
发表于: 2008-5-20 17:27 7476

[求助]Stop Service驱动后发生蓝屏

2008-5-20 17:27
7476
第一次写驱动,水平很低
模仿的Intercessor
目的是用PsSetLoadImageNotifyRoutine监视DLL的加载
可是在Stop Service这个.sys文件后 再对系统进行其他操作 会蓝屏

#include <ntddk.h>

#define IOCTL_DLL_LOAD \
  (ULONG) CTL_CODE(FILE_DEVICE_DISK_FILE_SYSTEM,  0x901, METHOD_BUFFERED, FILE_ANY_ACCESS) 

typedef struct _DLL_INFO
{
  PUNICODE_STRING FullImageName;
  PVOID ImageBase;
  LARGE_INTEGER current_time;
} DLL_INFO, * PDLL_INFO;

typedef struct _DEVICE_EXTENSION
{
  KSPIN_LOCK protect_lock;
  SIZE_T data_num;
  DLL_INFO dll_info[200];
} DEVICE_EXTENSION,*PDEVICE_EXTENSION; 

static DEVICE_EXTENSION  devExtension;

static NTSTATUS MydrvDispatch(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp);
static NTSTATUS DrvIOCtrlDispatch( IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
static VOID DriverUnload(IN PDRIVER_OBJECT pDriverObj);
VOID LoadDllMon(IN PUNICODE_STRING  FullImageName,IN HANDLE  ProcessId,IN PIMAGE_INFO  ImageInfo);

#define DEVICE_NAME L"\\Device\\LoadDll"
#define LINK_NAME L"\\DosDevices\\LoadDll"

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING pRegistryString)
{

  NTSTATUS status = STATUS_SUCCESS;
  UNICODE_STRING ustrDevName,ustrLinkName;

  PDEVICE_OBJECT pDevObj;
  int i;

  for (i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
  {
    pDriverObj->MajorFunction[i]=MydrvDispatch;
  }
  pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DrvIOCtrlDispatch;
  pDriverObj->DriverUnload = DriverUnload;

  
  RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
  RtlInitUnicodeString(&ustrLinkName, LINK_NAME);

  
  status = IoCreateDevice(pDriverObj, 
        0,
        &ustrDevName, 
        FILE_DEVICE_UNKNOWN,
        0,
        FALSE,
        &pDevObj);
  if(!NT_SUCCESS(status))
  {
    return status;
  }

  status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);  
  if(!NT_SUCCESS(status))
  {
    IoDeleteDevice(pDevObj);  
    return status;
  }

  devExtension.data_num=0;
  status=PsSetLoadImageNotifyRoutine(LoadDllMon);
  if (!NT_SUCCESS(status))
  {
    DbgPrint("PsSetLoadImageNotifyRoutine()\n");
    return status;
  }
  
  return STATUS_SUCCESS;
}

VOID DriverUnload(IN PDRIVER_OBJECT pDriverObj)
{  

  UNICODE_STRING strLink;
  RtlInitUnicodeString(&strLink, LINK_NAME);
  IoDeleteSymbolicLink(&strLink);

  IoDeleteDevice(pDriverObj->DeviceObject);
  DbgPrint("LoadDll Stop\n");
  return;
}

NTSTATUS MydrvDispatch(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
  pIrp->IoStatus.Status = STATUS_SUCCESS;

  IoCompleteRequest(pIrp, IO_NO_INCREMENT);

  return STATUS_SUCCESS;
}

VOID LoadDllMon(IN PUNICODE_STRING  FullImageName,IN HANDLE  ProcessId,IN PIMAGE_INFO  ImageInfo)
{
  KIRQL old_spin_lock_val;

  KeAcquireSpinLock(&devExtension.protect_lock,&old_spin_lock_val);
  devExtension.dll_info[devExtension.data_num].FullImageName=FullImageName;
  devExtension.dll_info[devExtension.data_num].ImageBase=ImageInfo->ImageBase;
  KeQuerySystemTime(&devExtension.dll_info[devExtension.data_num].current_time);
  ++devExtension.data_num;

  if (devExtension.data_num>=200)
  {
    devExtension.data_num=199;
  }
  
  KeReleaseSpinLock(&devExtension.protect_lock,old_spin_lock_val);
}

static NTSTATUS DrvIOCtrlDispatch( IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
  NTSTATUS status = STATUS_SUCCESS; 
  PIO_STACK_LOCATION irpStack; 

  PVOID ioBuffer; 
  ULONG inputBufferLength; 
  ULONG outputBufferLength; 
  ULONG ioControlCode;
  KIRQL old_spin_lock_val;

  SIZE_T desiredBufferLength;
  
  irpStack = IoGetCurrentIrpStackLocation(Irp); 

  ioControlCode= irpStack->Parameters.DeviceIoControl.IoControlCode; 

  ioBuffer = Irp->AssociatedIrp.SystemBuffer; 
  inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; 
  outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; 
  status = STATUS_SUCCESS;

  switch(ioControlCode)
  {
  case IOCTL_DLL_LOAD:
    desiredBufferLength=sizeof(DLL_INFO)*200+sizeof(SIZE_T);
    if (outputBufferLength<desiredBufferLength||NULL==ioBuffer)
    {
      status=STATUS_BUFFER_TOO_SMALL;
      break;
    }
    KeAcquireSpinLock(&devExtension.protect_lock,&old_spin_lock_val);
    RtlCopyMemory(ioBuffer, &devExtension.data_num, desiredBufferLength);
    devExtension.data_num=0;
    KeReleaseSpinLock(&devExtension.protect_lock,old_spin_lock_val);
    break;
  default:
    break;
  }
  Irp->IoStatus.Status = status; 
  Irp->IoStatus.Information = outputBufferLength; 

  IoCompleteRequest(Irp, IO_NO_INCREMENT); 

  return status; 
}

另外的问题是
得到的 IN PUNICODE_STRING  FullImageName 和 IN PIMAGE_INFO  ImageInfo 里面的信息
如何在应用程序经转换后打印出来
我写的DrvIOCtrlDispatch对不对?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
2
DriverEntry里PsSetLoadImageNotifyRoutine,DriverUnload里面却没有PsRemoveLoadImageNotifyRoutine,所以驱动退出之后,系统再加载镜像文件时,再调用那个回调,这时驱动已经卸载,注册的回调函数地址无效,所以BSOD。

DriverUnload里面加上
PsRemoveLoadImageNotifyRoutine(LoadDllMon);
2008-5-20 17:51
0
雪    币: 6419
活跃值: (612)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
在DriverUnload里面
除了IoDeleteSymbolicLink  IoDeleteDevice
还应该做些什么呢?
2008-5-20 18:04
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
4
不能机械地把DriverUnload看成就是IoDeleteSymbolicLink和IoDeleteDevice

DriverUnload就是在驱动卸载(服务被停止)退出之前做处理的代码
因此,在驱动运行过程中,对系统内核做了什么修改的话,在DriverUnload里面就必须要还原,以保证驱动退出后的系统还能够正常运作。


如果驱动运行时对内核进行了HOOK,则DriverUnload就必须把HOOK还原

同样的,驱动运行时利用PsSetLoadImageNotifyRoutine,把自身的函数注册为系统加载镜像文件时的回调函数(这样做了之后,系统每一次加载镜像文件后,都会再调用这个回调函数),那么,在驱动退出的时候,不再需要这个回调了,就必须Remove掉,否则系统再调用的时候就会BSOD

同样的,也是因为驱动运行时IoCreateDevice和IoCreateSymbolicLink,创建了设备和符号连接,在DriverUnload时才需要IoDeleteSymbolicLink和IoDeleteDevice
如果驱动运行时根本不创建设备和符号连接,Unload时也就不需要IoDeleteSymbolicLink和IoDeleteDevice
2008-5-20 18:19
0
雪    币: 6419
活跃值: (612)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5
PsRemoveLoadImageNotifyRoutine 是什么函数呢 DDK里找不到...

好了 终于不蓝屏了

现在的问题是 我得到了
FullImageName 是个PUNICODE_STRING结构 还有
typedef struct  _IMAGE_INFO {
    union {
        ULONG  Properties;
        struct {
            ULONG ImageAddressingMode  : 8; //code addressing mode
            ULONG SystemModeImage      : 1; //system mode image
            ULONG ImageMappedToAllPids : 1; //mapped in all processes
            ULONG Reserved             : 22;
        };
    };
    PVOID  ImageBase;
    ULONG  ImageSelector;
    ULONG  ImageSize;
    ULONG  ImageSectionNumber;
} IMAGE_INFO, *PIMAGE_INFO;

现在传给应用程序,如何打印其中 PUNICODE_STRING PVOID  这些结构
能提供如何使用 PsSetLoadImageNotifyRoutine 和结构IMAGE_INFO的一些资料么?
2008-5-20 20:17
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
6
*(ULONG*) XXXX

就可以了。
2008-5-21 08:21
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
7
MSDN:

PsSetLoadImageNotifyRoutine:
http://msdn.microsoft.com/en-us/library/ms802949.aspx

PsRemoveLoadImageNotifyRoutine:
http://msdn.microsoft.com/en-us/library/ms802951.aspx

以上是MSDN中相关的文档。
2008-5-21 13:45
0
游客
登录 | 注册 方可回帖
返回
//