首页
社区
课程
招聘
[求助]《Windows驱动开发技术详解》第三章动态加载驱动问题
发表于: 2013-10-18 11:41 8647

[求助]《Windows驱动开发技术详解》第三章动态加载驱动问题

2013-10-18 11:41
8647
首先驱动是正确的 用DriverMonitor加载成功

//下面 是加载驱动的源代码 基本跟书上一样
#include <stdio.h>  
#include <windows.h>  
#include <winsvc.h>
#include <conio.h>  

#define DRIVER_NAME "HelloDDK"
#define DRIVER_PATH "MyDriver.sys"
//#define DRIVER_PATH "MyDriver.sys"
//装载NT驱动程序
BOOL LoadNTDriver(char* lpszDriverName,char* lpszDriverPath)
{
        char szDriverImagePath[256] = {0};
        //得到完整的驱动路径
        GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);
        //strcpy(szDriverImagePath, lpszDriverPath);
        //char szTemp[256] = "\\??\\" ;
        //strcat(szTemp,szDriverImagePath);
        //strcpy(szDriverImagePath, szTemp);

        BOOL bRet = FALSE;

        SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
        SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄

        //打开服务控制管理器
        hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

        if( hServiceMgr == NULL )  
        {
                //OpenSCManager失败
                printf( "OpenSCManager() Faild %d ! \n", GetLastError() );
                bRet = FALSE;
                goto BeforeLeave;
        }
        else
        {
                ////OpenSCManager成功
                printf( "OpenSCManager() ok ! \n" );  
        }

        //创建驱动所对应的服务
        hServiceDDK = CreateService( hServiceMgr,
                lpszDriverName, //驱动程序的在注册表中的名字  
                lpszDriverName, // 注册表驱动程序的 DisplayName 值  
                SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限  
                SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序  
                SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值  
                SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值  
                szDriverImagePath, // 注册表驱动程序的 ImagePath 值  
                NULL,  
                NULL,  
                NULL,  
                NULL,  
                NULL);  

        DWORD dwRtn;

        //判断服务是否失败
        if( hServiceDDK == NULL )  
        {  
                dwRtn = GetLastError();
                if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )  
                {  
                        //由于其他原因创建服务失败
                        printf( "CrateService() Faild %d ! \n", dwRtn );  
                        bRet = FALSE;
                        goto BeforeLeave;
                }  
                else  
                {
                        //服务创建失败,是由于服务已经创立过
                        printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" );  
                }

                // 驱动程序已经加载,只需要打开  
                hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS );  
                if( hServiceDDK == NULL )  
                {
                        //如果打开服务也失败,则意味错误
                        dwRtn = GetLastError();  
                        printf( "OpenService() Faild %d ! \n", dwRtn );  
                        bRet = FALSE;
                        goto BeforeLeave;
                }  
                else
                {
                        printf( "OpenService() ok ! \n" );
                }
        }  
        else  
        {
                printf( "CrateService() ok ! \n" );
        }

        //开启此项服务
        bRet= StartService( hServiceDDK, NULL, NULL );  
        if( !bRet )  
        {  
                DWORD dwRtn = GetLastError();  
                if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )  
                {  
                        printf( "StartService() Faild %d ! \n", dwRtn );  
                        bRet = FALSE;
                        goto BeforeLeave;
                }  
                else  
                {  
                        if( dwRtn == ERROR_IO_PENDING )  
                        {  
                                //设备被挂住
                                printf( "StartService() Faild ERROR_IO_PENDING ! \n");
                                bRet = FALSE;
                                goto BeforeLeave;
                        }  
                        else  
                        {  
                                //服务已经开启
                                printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n");
                                bRet = TRUE;
                                goto BeforeLeave;
                        }  
                }  
        }
        bRet = TRUE;
        //离开前关闭句柄
BeforeLeave:
        if(hServiceDDK)
        {
                CloseServiceHandle(hServiceDDK);
        }
        if(hServiceMgr)
        {
                CloseServiceHandle(hServiceMgr);
        }
        return bRet;
}

//卸载驱动程序  
BOOL UnloadNTDriver( char * szSvrName )  
{
        BOOL bRet = FALSE;
        SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
        SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄
        SERVICE_STATUS SvrSta;
        //打开SCM管理器
        hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );  
        if( hServiceMgr == NULL )  
        {
                //带开SCM管理器失败
                printf( "OpenSCManager() Faild %d ! \n", GetLastError() );  
                bRet = FALSE;
                goto BeforeLeave;
        }  
        else  
        {
                //带开SCM管理器失败成功
                printf( "OpenSCManager() ok ! \n" );  
        }
        //打开驱动所对应的服务
        hServiceDDK = OpenService( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS );  

        if( hServiceDDK == NULL )  
        {
                //打开驱动所对应的服务失败
                printf( "OpenService() Faild %d ! \n", GetLastError() );  
                bRet = FALSE;
                goto BeforeLeave;
        }  
        else  
        {  
                printf( "OpenService() ok ! \n" );  
        }  
        //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。  
        if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) )  
        {  
                printf( "ControlService() Faild %d !\n", GetLastError() );  
        }  
        else  
        {
                //打开驱动所对应的失败
                printf( "ControlService() ok !\n" );  
        }  

        //动态卸载驱动程序。  
        if( !DeleteService( hServiceDDK ) )  
        {
                //卸载失败
                printf( "DeleteSrevice() Faild %d !\n", GetLastError() );  
        }  
        else  
        {  
                //卸载成功
                printf( "DelServer:eleteSrevice() ok !\n" );  
        }  
        bRet = TRUE;
BeforeLeave:
        //离开前关闭打开的句柄
        if(hServiceDDK)
        {
                CloseServiceHandle(hServiceDDK);
        }
        if(hServiceMgr)
        {
                CloseServiceHandle(hServiceMgr);
        }
        return bRet;       
}

void TestDriver()
{
        //测试驱动程序  
        HANDLE hDevice = CreateFile("\\\\.\\HelloDDK",  
                GENERIC_WRITE | GENERIC_READ,  
                0,  
                NULL,  
                OPEN_EXISTING,  
                0,  
                NULL);  
        if( hDevice != INVALID_HANDLE_VALUE )  
        {
                printf( "Create Device ok ! \n" );  
        }
        else  
        {
                printf( "Create Device faild %d ! \n", GetLastError() );  
        }
        CloseHandle( hDevice );
}

int main(int argc, char* argv[])  
{
        //加载驱动
        BOOL bRet = LoadNTDriver(DRIVER_NAME,DRIVER_PATH);
        if (!bRet)
        {
                printf("LoadNTDriver error\n");
                return 0;
        }
        //加载成功

        printf( "press any to create device!\n" );  
        getch();  

        TestDriver();

        //这时候你可以通过注册表,或其他查看符号连接的软件验证。  
        printf( "press any to unload the driver!\n" );  
        getch();  

        //卸载驱动
        UnloadNTDriver(DRIVER_NAME);
        if (!bRet)
        {
                printf("UnloadNTDriver error\n");
                return 0;
        }
        return 0;  
}  

第一次运行:

第二次运行
OpenSCManager()ok!
CreateService()ok!
StartService()Faild 3!//此处的3是路径名错误
LoadNTDriver error!

如果程序第二次运行:
OpenSCManager()ok!
CreateService()Faild Service is ERROR_IO_PENDING or ERROR_SERUICE_EXISTS!
OpenService()ok!
StartService()Faild 2!
LoadNTDriver error!

所以我试调了下:

szDriverImagePath 最终是:
f:\MyProc\MyDriver\Test\MyDriver.sys
于是我把驱动放到该目录下。

可是还是提示:
OpenSCManager()ok!
CreateService()Faild Service is ERROR_IO_PENDING or ERROR_SERUICE_EXISTS!
OpenService()ok!
StartService()Faild 2!
LoadNTDriver error!

求解!

MyDriver.rar

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 293
活跃值: (287)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
用这个试试
上传的附件:
2013-10-18 12:23
0
雪    币: 49
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
单步调试 错误码 查看MSDN 应该是能查出来问题所在
这种问题 自己调试可能效率更高
2013-10-20 10:23
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢 这个是可以用的 但是加载驱动的方法跟我的不一样。

我的源码 在别的电脑上可以使用, 我想估计是被电脑上的什么QQ管家之类的 保护软件给拦截了吧!
2013-10-21 09:45
0
雪    币: 293
活跃值: (287)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
我原来也用服务管理器去加载的,后来有客户反映程序有时候失败,一火,直接用ZwLoadDriver。而且这个方式加载,驱动还可以删除掉
2013-10-21 10:30
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不是程序代码问题,应该是被杀毒软件拦截了,我放在虚拟机中就可以正确运行。虚拟机中没有杀毒什么的软件。
2013-10-21 11:43
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我自己来结贴:
此问题形成原因:
使用DriverMonitor或者其他其他工具载入时,创建了HelloDDK服务。可能由于某种不明原因导致程序被强行退出,导致服务没有正常被卸载。

解决方法就是卸载该服务:
调处命令行窗口。敲入命令:sc delete XXX   
XXX为你所要删除的服务名。
2013-11-4 14:26
0
游客
登录 | 注册 方可回帖
返回
//