这里作为几个总结,一是自己不小心导致的问题;二是的确有点匪夷所思的。具体产生的原因,未做深入研究,仅做记录。
环境:
Win7 X64 SP1
VS2012
WDK8
记录:
使用ObRegisterCallbacks注册的进程对象回调,_ObPreProcessCallback。
1、在回调_ObPreProcessCallback中,不能调用ZwOpenProcess这类打开进程的API。会导致重入,理由就是_ObPreProcessCallback回调是在进程被打开的时候调用的。
2、在回调_ObPreProcessCallback中,不要使用PsLookupProcessByProcessId这个API,在某些特定情况下,会导致桌面卡死。
这里有个是简单的实例代码:
1 OB_PREOP_CALLBACK_STATUS _ObPreProcessCallback(_In_ PVOID RegistrationContext, _In_ POB_PRE_OPERATION_INFORMATION OperateInfo)
2 {
3 PEPROCESS Process = NULL;
4 PsLookupProcessByProcessId(PsGetCurrentProcessId(), &Process);
5
6 UNREFERENCED_PARAMETER(RegistrationContext);
7 UNREFERENCED_PARAMETER(OperateInfo);
8
9 return OB_PREOP_SUCCESS;
10 }
启动驱动后,使用PowerPool这个程序,选择“进程管理”标签。桌面不响应了,PowerPool的进程列表也刷新不出来。
3、FltGetFileNameInformation函数返回成功后,还是需要检测返回的名称参数。跑了很长很长时间的驱动,挂在了该函数返回成功,但是返回的名称的参数却是NULL。这个发声的概率很低很低
----------------------------ZwReadFile在swapgs指令时卡死的问题----------------------------
所在环境:
Win7_X64_SP1、VS2012、WDK8
问题描述:
在LoadImage回调中, 当ProcessId != 0同时加载的是.sys文件, 如果调用ZwReadFile、ZwQueryInfromationFile等ZwXxxFile的API时,会导致卡死,卡死的位置的在swapgs这个指令不返回。
解决办法:
ProcessId != 0时Load的是sys文件,需要判断SystemModeImage是否等于1,如果SystemModeImage == 0则调用ZwXxxFile的函数时会卡死在swapgs指令中,如果SystemModeImage == 1时调用ZwXxxFile则不会卡死。
问题原因:
尚未可知
----------------------------KrnlProc_GetNtPath在LoadImage中导致蓝屏的问题----------------------------
所在环境:
Win_X64_SP1、VS2012、WDK8
问题描述:
在LoadImage回调中,通过ZwOpenProcess、ZwQueryInfromationProcess(ProcessImageFileName)来获取进程路径时导致蓝屏。蓝屏的位置不是本模块、是Windows的系统内核模块。
同时,如果调用了ObQueryNameString传递加载的模块的FileObject也会出现像上面的情况。
解决办法:
解决办法,只有在其他地方获取进程信息并保存,LoadImage中来查询自己保存的进程信息。LoadImage在FullImageName为NULL的时候,先查询FileObject->DeviceObject,然后组合FileObject->FileName即可。这只是绕过了这个问题,暂时没有找到直接解决的办法。
问题原因:
尚未可知
----------------------------SetupInstallServicesFromInfSection安装Inf文件的问题----------------------------
所在环境:
Win_X64_SP1、VS2012
问题描述:
在调用SetupInstallServicesFromInfSection进行安装Inf文件时,错误码为: 0xe0000217。
测试的代码如下:
#define IS_HANDLE_DISABLE(_h) ( ((_h) == NULL) || ((_h) == INVALID_HANDLE_VALUE) ) ULONG MF_Setup(const char* InfPath, bool bRemove) { UINT dwErrLine = 0; ULONG dwError = 0; HSPFILEQ hFileQ = ::SetupOpenFileQueue(); if ( IS_HANDLE_DISABLE(hFileQ) ) { dwError = ::GetLastError(); return dwError; } HINF hInf = ::SetupOpenInfFileA(InfPath, NULL, INF_STYLE_WIN4, &dwErrLine); if ( IS_HANDLE_DISABLE(hInf) ) { dwError = ::GetLastError(); goto EXIT_INST; } if ( bRemove ) { if ( !::SetupInstallServicesFromInfSectionA(hInf, "DefaultUninstall.Services", 0) ) { dwError = ::GetLastError(); } } else { if ( !::SetupInstallServicesFromInfSectionA(hInf, "DefaultInstall.Services", 0) ) { dwError = ::GetLastError(); } } EXIT_INST: if ( !IS_HANDLE_DISABLE(hInf) ) { ::SetupCloseInfFile(hInf); hInf = NULL; } if ( !IS_HANDLE_DISABLE(hFileQ) ) { ::SetupCloseFileQueue(hFileQ); hFileQ = NULL; } return dwError; }
解决办法:
将INF文件中的ServiceBinary修改为系统目录。比如: %12%\%DriverName%.sys
问题原因:
产生的日志文件位于:C:\Windows\inf\setupapi.app.log中。提示:dvi: Driver Path not in system root。指明INF文件中的ServiceBinary不是处于系统目录中。