首页
社区
课程
招聘
[求助]在驱动中调用wcsstr()为什么会蓝屏?
发表于: 2007-6-19 22:33 9114

[求助]在驱动中调用wcsstr()为什么会蓝屏?

2007-6-19 22:33
9114
郁闷了两天,始终不知道下面的代码为什么会蓝屏。
这是一个驱动程序,目的是通过挂钩ZwCreateFile监视针对特定文件的访问。
代码如下,请路过的朋友们帮我看看,这驱动运行大概30分钟就会蓝屏。。,通过调试dump文件,说是wcsstr()函数调用后出错,但我始终看不出有什么问题。郁闷啊,哪位朋友帮帮忙~感谢

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include <ntddk.h>

#define DEBUG
typedef unsigned long DWORD, *PDWORD;
typedef unsigned char BYTE, *PBYTE;

#pragma pack(1)
typedef struct ServiceDescriptorEntry {
    PDWORD ServiceTable;
    PDWORD CounterTableBase;
    DWORD  ServiceLimit;
    PBYTE  ArgumentTable;
} SDT;
#pragma pack()

__declspec(dllimport) SDT KeServiceDescriptorTable;

typedef NTSYSAPI NTSTATUS (*ZWCREATEFILE)(
                                          OUT PHANDLE FileHandle,
                                          IN ACCESS_MASK DesiredAccess,
                                          IN POBJECT_ATTRIBUTES ObjectAttributes,
                                          OUT PIO_STATUS_BLOCK IoStatusBlock,
                                          IN PLARGE_INTEGER AllocationSize OPTIONAL,
                                          IN ULONG FileAttributes,
                                          IN ULONG ShareAccess,
                                          IN ULONG CreateDisposition,
                                          IN ULONG CreateOptions,
                                          IN PVOID EaBuffer OPTIONAL,
                                          IN ULONG EaLength
                                          );

ULONG gProcessNameOffset;
unsigned long OldCr0;
ZWCREATEFILE OldZwCreateFile;
extern ZWCREATEFILE OldZwCreateFile;

#define SYSTEMSERVICE(_name)  KeServiceDescriptorTable.ServiceTable[*(DWORD *) ((unsigned char *)_name + 1)]

PCWSTR REALFILE=L"abc.txt";

NTSTATUS DriverEntry(PDRIVER_OBJECT, PUNICODE_STRING);
void unload_driver(IN PDRIVER_OBJECT);
void hook(void);
void unhook();

void GetProcessNameOffset()
{
  PEPROCESS curproc = PsGetCurrentProcess();
  int i;
  for( i = 0; i < 3*PAGE_SIZE; i++ )
  {
      if( !strncmp( "System", (PCHAR) curproc + i, strlen("System") ))
        {
          gProcessNameOffset = i;
        }
  }
}

ULONG GetProcessName( PCHAR theName )
{
  PEPROCESS       curproc;
  char            *nameptr;
  ULONG           i;
  KIRQL           oldirql;

  if( gProcessNameOffset )
    {
      curproc = PsGetCurrentProcess();
      nameptr   = (PCHAR) curproc + gProcessNameOffset;
      strncpy( theName, nameptr, 16 );
      theName[16] = 0; /* NULL at end */
      return TRUE;
    }
  return FALSE;
}

NTSTATUS NewZwCreateFile(OUT PHANDLE FileHandle,
                         IN ACCESS_MASK DesiredAccess,
                         IN POBJECT_ATTRIBUTES ObjectAttributes,
                         OUT PIO_STATUS_BLOCK IoStatusBlock,
                         IN PLARGE_INTEGER AllocationSize OPTIONAL,
                         IN ULONG FileAttributes,
                         IN ULONG ShareAccess,
                         IN ULONG CreateDisposition,
                         IN ULONG CreateOptions,
                         IN PVOID EaBuffer OPTIONAL,
                         IN ULONG EaLength) {
    NTSTATUS ntS = (NTSTATUS) NULL;

        PWSTR IsOurFile = NULL;
                PCWSTR FileNameaddr=NULL;
        CHAR aProcessName[20];
       
        ULONG i=0,j=0;
       
        //DbgPrint("ZwCreateFile called\n");
         _asm    //获取要打开的文件名地址
        {
            pushad
            mov edi, ObjectAttributes
            mov eax, [edi+8]
            mov edi, [eax+4]
            mov FileNameaddr, edi
            popad
        }               

        IsOurFile = wcsstr( FileNameaddr, REALFILE ); //判断是否是打开abc.txt

        if ( IsOurFile != NULL )
        {
        GetProcessName( aProcessName );
        DbgPrint("检测到有进程%s要打开abc.txt",aProcessName);
         }                          
   
    // on appelle la vraie fonction
    ntS = ((ZWCREATEFILE)(OldZwCreateFile)) (
        FileHandle,
        DesiredAccess,
        ObjectAttributes,
        IoStatusBlock,
        AllocationSize,
        FileAttributes,
        ShareAccess,
        CreateDisposition,
        CreateOptions,
        EaBuffer,
        EaLength);
    return(ntS);
}

void hook(void) {
   
        _asm{   //关闭内存保护
        cli;
                mov eax,cr0
        mov OldCr0,eax
        and eax,0fffeffffh
        mov cr0,eax
    }
       
    OldZwCreateFile = (ZWCREATEFILE) (SYSTEMSERVICE(ZwCreateFile));
    (ZWCREATEFILE) (SYSTEMSERVICE(ZwCreateFile)) =    NewZwCreateFile;
        _asm   //开启内存保护
    {
        mov eax,OldCr0
                mov cr0,eax
                sti;
    }

}

void unhook() {

        _asm{   //关闭内存保护
        cli;
                mov eax,cr0
        mov OldCr0,eax
        and eax,0fffeffffh
        mov cr0,eax
    }
       
    // on restaure la bonne adresse de ZeCreateFile dans la SDT
    (ZWCREATEFILE) (SYSTEMSERVICE(ZwCreateFile)) = OldZwCreateFile;
        _asm   //开启内存保护
    {
        mov eax,OldCr0
                mov cr0,eax
                sti;
    }
}

void unload_driver(IN PDRIVER_OBJECT DriverObject) {
   
    DbgPrint("unhooking API ...\n");
    unhook();
}

NTSTATUS DriverEntry(PDRIVER_OBJECT driverObject, PUNICODE_STRING RegistryPath) {
   
    driverObject->DriverUnload  = unload_driver;
   
    DbgPrint("hooking API ...\n");
        GetProcessNameOffset();
    hook();
   
    return(STATUS_SUCCESS);
}

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

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
2
返回的FileNameaddr会不会有问题
2007-6-19 23:00
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
FileNameaddr是一个地址,里面存放着要ZwCreateFile要打开的文件名字,是宽字符的。
应该不会有问题吧
2007-6-20 08:14
0
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
4
感觉返回的字符串一般还是先检查一下再用,要不你自己写个wcsstr试下
2007-6-20 12:13
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
  谢谢提示,我这就试试看
2007-6-20 16:04
0
游客
登录 | 注册 方可回帖
返回
//