首页
社区
课程
招聘
[求助]学习驱动中遇到的问题
发表于: 2009-6-3 22:48 4920

[求助]学习驱动中遇到的问题

2009-6-3 22:48
4920
由于本人学习内核编程不久,自己在编写隐藏文件夹的驱动中遇到如下问题,可以通过编译,但是已安装就蓝屏,提示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;
}

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

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 379
活跃值: (152)
能力值: ( LV12,RANK:330 )
在线值:
发帖
回帖
粉丝
2
比较急,希望高手能帮忙解答,用windbg与vmware调试驱动有没有好的技巧,能否给点资料,真得谢谢那,
2009-6-3 23:06
0
雪    币: 379
活跃值: (152)
能力值: ( LV12,RANK:330 )
在线值:
发帖
回帖
粉丝
3
由于本人学习内核编程不久,自己在编写隐藏文件夹的驱动中遇到如下问题,可以通过编译,但是已安装就蓝屏,提示IRQL_NOT_LESS_OR_EQVAL错误,好像是中断层次的问题,通过WINDBG跟踪调试,最后限于中断死循环中,望高手帮忙看一下,指出问题所在,不胜感激,邱各位大侠帮忙看看
2009-6-4 17:48
0
雪    币: 75
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
!analyze -v 的output发出来。
或者dump发上来。
2009-6-5 02:27
0
雪    币: 379
活跃值: (152)
能力值: ( LV12,RANK:330 )
在线值:
发帖
回帖
粉丝
5
dump的分析如下:

Microsoft (R) Windows Debugger Version 6.10.0003.233 X86
Copyright (c) Microsoft Corporation. All rights reserved.

Loading Dump File [D:\BuildSys\Mini060609-01.dmp]
Mini Kernel Dump File: Only registers and stack trace are available

Symbol search path is: SRV*d:\symcache*http://msdl.microsoft.com/download/symbols;D:\RFile\objchk\i386
Executable search path is: D:\RFile\objchk\i386\
Windows XP Kernel Version 2600 (Service Pack 3) UP Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp.080413-2111
Machine Name:
Kernel base = 0x804d8000 PsLoadedModuleList = 0x8055c1c0
Debug session time: Sat Jun  6 20:21:01.156 2009 (GMT+8)
System Uptime: 0 days 0:05:16.828
Loading Kernel Symbols
...............................................................
................................................
Loading User Symbols
Loading unloaded module list
.........
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck 1000000A, {575628e8, 2, 0, 804dce7b}

Probably caused by : rdbss.sys ( rdbss!RxTimerDispatch+be )

Followup: MachineOwner
---------

kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 575628e8, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, bitfield :
        bit 0 : value 0 = read operation, 1 = write operation
        bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
Arg4: 804dce7b, address which referenced memory

Debugging Details:
------------------

READ_ADDRESS:  575628e8

CURRENT_IRQL:  2

FAULTING_IP:
nt!KiInsertTimerTable+2f
804dce7b 3b51fc          cmp     edx,dword ptr [ecx-4]

CUSTOMER_CRASH_COUNT:  1

DEFAULT_BUCKET_ID:  INTEL_CPU_MICROCODE_ZERO

BUGCHECK_STR:  0xA

PROCESS_NAME:  Idle

LAST_CONTROL_TRANSFER:  from 804dceff to 804dce7b

STACK_TEXT:  
80551d60 804dceff fff79b90 ffffffff bcd822a2 nt!KiInsertTimerTable+0x2f
80551d7c 804dd3cb fff79b90 ffffffff f82aa2d0 nt!KiInsertTreeTimer+0x7d
80551d9c 804dd402 002aa2a0 fff79b90 ffffffff nt!KeSetTimerEx+0x4b
80551db8 f82a0405 f82aa2a0 fff79b90 ffffffff nt!KeSetTimer+0x18
80551de4 804dd4fd f82aa2e0 00000000 41024240 rdbss!RxTimerDispatch+0xbe
80551f00 804dd378 8055ac20 8055a9c0 ffdff000 nt!KiTimerListExpire+0x122
80551f2c 804dcbd4 8055b020 00000000 00004f34 nt!KiTimerExpiration+0xaf
80551f40 8055a9c0 ffdffc50 00000000 00000000 nt!KiRetireDpcList+0x46
80551f50 804dcb4d 00000000 0000000e 00000000 nt!KiIdleThread0
80551f54 00000000 0000000e 00000000 00000000 nt!KiIdleLoop+0x26

STACK_COMMAND:  kb

FOLLOWUP_IP:
rdbss!RxTimerDispatch+be
f82a0405 8b45f4          mov     eax,dword ptr [ebp-0Ch]

SYMBOL_STACK_INDEX:  4

SYMBOL_NAME:  rdbss!RxTimerDispatch+be

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: rdbss

IMAGE_NAME:  rdbss.sys

DEBUG_FLR_IMAGE_TIMESTAMP:  48025ee6

FAILURE_BUCKET_ID:  0xA_rdbss!RxTimerDispatch+be

BUCKET_ID:  0xA_rdbss!RxTimerDispatch+be

Followup: MachineOwner
---------
2009-6-6 21:21
0
雪    币: 75
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
DPC level 访问了paged memory了。
rdbss是你的driver?
80551de4 804dd4fd f82aa2e0 00000000 41024240 rdbss!RxTimerDispatch+0xbe
是哪行代码?
给我把dump发到Email吧?peking2toronto@hotmail.com
2009-6-7 01:04
0
雪    币: 379
活跃值: (152)
能力值: ( LV12,RANK:330 )
在线值:
发帖
回帖
粉丝
7
我将extern ServiceDescriptorTableEntry_t  KeServiceDescriptorTable;改为__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;就可以,这是为什么,还有rdbss.sys是一个系统文件恢复的驱动
2009-6-7 16:11
0
雪    币: 75
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
calling convention不对,把stack搞乱了。
2009-6-7 21:58
0
雪    币: 379
活跃值: (152)
能力值: ( LV12,RANK:330 )
在线值:
发帖
回帖
粉丝
9
清详细指出call convention,但是我现在的驱动编译没问题那!只要改成
extern  ServiceDescriptorTableEntry_t   KeServiceDescriptorTable;就会提示IRQL_NOT_LESS_OR_EQVAL错误,还望不吝赐教
2009-6-8 07:14
0
游客
登录 | 注册 方可回帖
返回
//