我本来是驱动初学不久,因为参加信息安全比赛做点东西,只能超越现阶段能力,其中就有SSDT HOOK文件操作,当然,HOOK 实现来自网上标准方法。但是问题来了:我在HOOK 了ZwWriteFile后,自己的实现老是蓝屏,开始比较简单,问题不大,后来加了一些代码,越蓝越离谱,最后竟然连我注释掉了一个没有用到的变量都会蓝屏。。。。
下面是实现:
/****************************************************///HookNtWriteFile,HOOK写文件
HookZwWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
)
{
if (TurnOnFileMon==1)//如果功能开启的话
{
char aProcessName[PROCNAMELEN];
UNICODE_STRING volumeDosName={0};
PCWSTR WriteFileName;
PFILE_OBJECT fileobj;
UNICODE_STRING uProcessPath={0};//进程路径
ANSI_STRING aProcessPath={0};//进程路径
if ( FileHandle != NULL)
{
/**************************************************************************///进程信息获取
PCWSTR ProcessName = GetCurrentProcessFileName();
RtlInitUnicodeString(&uProcessPath,ProcessName);
RtlUnicodeStringToAnsiString(&aProcessPath,&uProcessPath,TRUE);
/**************************************************************************/
{
ANSI_STRING apath;//文件路径,不含驱动器
UNICODE_STRING upath;
ANSI_STRING apathpre;//驱动器
UNICODE_STRING upathpre;
/****************************************///得到文件名
ObReferenceObjectByHandle(FileHandle,GENERIC_READ,*IoFileObjectType,KernelMode,(PVOID *)&fileobj,NULL);
WriteFileName=fileobj->FileName.Buffer;
RtlInitUnicodeString(&upath,WriteFileName);
RtlUnicodeStringToAnsiString(&apath,&upath,TRUE);
/****************************************/
{
IoVolumeDeviceToDosName(((PFILE_OBJECT)fileobj)->DeviceObject, &volumeDosName);
if(&volumeDosName!=NULL && (volumeDosName.Length<=6))
{
// 此处转换 盘符
RtlInitUnicodeString(&upathpre,volumeDosName.Buffer);
RtlUnicodeStringToAnsiString(&apathpre,&upathpre,TRUE);
KdPrint(("%s修改文件:%s%s \r\n",aProcessPath.Buffer,apathpre.Buffer,apath.Buffer));
strcpy(cmpfile,apathpre.Buffer);
strcat(cmpfile,apath.Buffer);
///////
memset(Dir_Path,0,256);
strcpy(Dir_Path,cmpfile);
GetDir();
if(CmpDir(Dir_Path)==1)//目录比对
{
strcpy(aPathName,apathpre.Buffer);
strcat(aPathName,apath.Buffer);
strcpy(aProcessName,aProcessPath.Buffer);
strcat(aProcessName,"##");
if (GoOrNot(aProcessName,aPathName))
{
return RealZwWriteFile(FileHandle, Event OPTIONAL, ApcRoutine OPTIONAL, ApcContext OPTIONAL, IoStatusBlock, Buffer, Length, ByteOffset OPTIONAL, Key OPTIONAL );
}
else
{
FileHandle = NULL;
return STATUS_ACCESS_DENIED;
}
}
if(CmpFile(cmpfile)==1)//文件比对
{
strcpy(aPathName,apathpre.Buffer);
strcat(aPathName,apath.Buffer);
strcpy(aProcessName,aProcessPath.Buffer);
strcat(aProcessName,"##");
if (GoOrNot(aProcessName,aPathName))
{
return RealZwWriteFile(FileHandle, Event OPTIONAL, ApcRoutine OPTIONAL, ApcContext OPTIONAL, IoStatusBlock, Buffer, Length, ByteOffset OPTIONAL, Key OPTIONAL );
}
else
{
FileHandle = NULL;
return STATUS_ACCESS_DENIED;
}
}
/*else
return RealZwWriteFile(FileHandle, Event OPTIONAL, ApcRoutine OPTIONAL, ApcContext OPTIONAL, IoStatusBlock, Buffer, Length, ByteOffset OPTIONAL, Key OPTIONAL );*/
}
/*else
return RealZwWriteFile(FileHandle, Event OPTIONAL, ApcRoutine OPTIONAL, ApcContext OPTIONAL, IoStatusBlock, Buffer, Length, ByteOffset OPTIONAL, Key OPTIONAL );*/
}
}
}
else
return RealZwWriteFile(FileHandle, Event OPTIONAL, ApcRoutine OPTIONAL, ApcContext OPTIONAL, IoStatusBlock, Buffer, Length, ByteOffset OPTIONAL, Key OPTIONAL );
}
else
return RealZwWriteFile(FileHandle, Event OPTIONAL, ApcRoutine OPTIONAL, ApcContext OPTIONAL, IoStatusBlock, Buffer, Length, ByteOffset OPTIONAL, Key OPTIONAL );
}
说明
1、GetDir();用来从文件全路径分离出不含文件名的路径
2、if(CmpDir(Dir_Path)==1)//目录比对
if(CmpFile(cmpfile)==1)//文件比对
用来进行链表比对,我在HookZwSetInformationFile也用到了,没有问 题
3、///进程信息获取那一段函数在别处也用到,应该没问题早期问题是用程序进行写操作没问题,但是打开我的电脑就蓝屏,后来一打开监控就蓝屏。。。。环境:虚拟机 WIN XP SP3 +真机,谢谢了
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课