由于本人学习内核编程不久,自己在编写隐藏文件夹的驱动中遇到如下问题,可以通过编译,但是已安装就蓝屏,提示IRQL_NOT_LESS_OR_EQVAL错误,好像是中断层次的问题,通过WINDBG跟踪调试,最后限于中断死循环中,望高手帮忙看一下,指出问题所在,不胜感激,主要代码如下:
#include <ntddk.h>
#include <stdio.h>
typedef unsigned long DWORD;
typedef unsigned long ULONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef struct ServiceDescriptorEntry{
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int *NumberOfServices;
unsigned char *ParamTableBase;
}ServiceDescriptorTableEntry_t,*PServiceDescriptorTableEntry_t;
extern ServiceDescriptorTableEntry_t KeServiceDescriptorTable;//用关键字extern说明的变量成为外部变量(不需要分配内存,在外部定义)
#define SYSCALL(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]
typedef struct _FILE_BOTH_DIR_INFORMATION{
ULONG NextEntryOffset;
ULONG FileIndex;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
ULONG EaSize;
CCHAR ShortNameLength;
WCHAR ShortName[12];
WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
//定义Hook的API函数的原型:
NTSTATUS
NTAPI
MyZwQueryDirectoryFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan);
//先声明申明ZwQueryDirectoryFile
NTSYSAPI
NTSTATUS
NTAPI ZwQueryDirectoryFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan);
//定义ZwQueryDirectoryFile的原型
typedef NTSTATUS (*ZWQUERYDIRECTORYFILE)(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan);
ZWQUERYDIRECTORYFILE RealZwQueryDirectoryFile = NULL;
NTSTATUS HookApi();
NTSTATUS UnHook();
NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject);
//HOOK的函数过程
NTSTATUS MyZwQueryDirectoryFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan)
{
NTSTATUS status;
DbgPrint("Hide:NewZwQueryDirectoryFile called.");
// 执行真正的ZwQueryDirectoryFile函数
status=((ZWQUERYDIRECTORYFILE)(RealZwQueryDirectoryFile))(
FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
FileInformation,
Length,
FileInformationClass,
ReturnSingleEntry,
FileName,
RestartScan);
/*如果执行成功(而且FILE_INFORMATION_CLASS的值为FileBothDirectoryInformation,
检查的是文件和文件夹的话我们就进行处理,过滤*/
if(NT_SUCCESS(status)&&(FileInformationClass==FileBothDirectoryInformation))
{
PFILE_BOTH_DIR_INFORMATION pFileInfo;
PFILE_BOTH_DIR_INFORMATION pLastFileInfo;
BOOLEAN bLastOne;
//把执行结果赋给pFileInfo
pFileInfo=(PFILE_BOTH_DIR_INFORMATION)FileInformation;
pLastFileInfo=NULL;
do
{
bLastOne =!(pFileInfo->NextEntryOffset);//
// 开始进行比较,如果找到了就隐藏这个文件或者目录
if(RtlCompareMemory(pFileInfo->FileName,L"RFile",10 ) == 10)
{
DbgPrint("This is HideDirFile!\n");
if(bLastOne)
{
if(pFileInfo==(PFILE_BOTH_DIR_INFORMATION)FileInformation)//如果找到这个是文件和文件夹就隐藏
{
status=STATUS_NO_MORE_FILES; //隐藏文件或者目录;
}
else
{
pLastFileInfo->NextEntryOffset = 0;
}
break;
}
else
{
//指针往后移动,考虑到是文件链表的形式
int iPos=((ULONG)pFileInfo) - (ULONG)FileInformation;
int iLeft=(ULONG)Length - iPos - pFileInfo->NextEntryOffset;
RtlCopyMemory((PVOID)pFileInfo,(PVOID)( (char*)pFileInfo+pFileInfo->NextEntryOffset ),(ULONG)iLeft);
continue;
}
}
pLastFileInfo=pFileInfo;
pFileInfo=(PFILE_BOTH_DIR_INFORMATION)((char*)pFileInfo+pFileInfo->NextEntryOffset);
}while(!bLastOne);
}
return status;
}
NTSTATUS HookApi()
{
//首先保存原来的地址
RealZwQueryDirectoryFile = (ZWQUERYDIRECTORYFILE)SYSCALL(ZwQueryDirectoryFile);
_asm{
mov eax,cr0
and eax,not 10000h //10000h=~10000h
mov cr0,eax
}
//把自定义的替换函数指针指向真正的ZwQueryDirectoryFile函数
(ZWQUERYDIRECTORYFILE)SYSCALL(ZwQueryDirectoryFile)=MyZwQueryDirectoryFile;
_asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
}
return( STATUS_SUCCESS );
}
NTSTATUS UnHook()
{
_asm{
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
//将真正的ZwQueryDirectoryFile地址,恢复原来的函数指针
(ZWQUERYDIRECTORYFILE)SYSCALL(ZwQueryDirectoryFile) = RealZwQueryDirectoryFile;
_asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
}
return( STATUS_SUCCESS );
}
NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
NTSTATUS status;
DbgPrint("OnUnload called!\n");
status=UnHook();
return status;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
IN PUNICODE_STRING theRegistryPath)
{
NTSTATUS status;
DbgPrint("I Load!\n");
theDriverObject->DriverUnload=DriverUnload;
status=HookApi();
return status;
}
[课程]FART 脱壳王!加量不加价!FART作者讲授!