首页
社区
课程
招聘
[原创][成果3.3]驱动整个入门流程之流程四--驱动动态加载
发表于: 2007-12-28 18:18 16064

[原创][成果3.3]驱动整个入门流程之流程四--驱动动态加载

2007-12-28 18:18
16064

这个课题主要是讲如何动态加载驱动,虽然现在已经存在很多的动态驱动加载器,但是使用自己编写的东西,还是有不同的感觉的。当是科普吧。

在这里,主要使用SCM来进行驱动的动态加载和卸载。

先介绍下SCM,服务控制管理器(Service Control Manager , SCM )。服务(Service)是在后台运行配套的程序,并且不需要用户交互(也就是说没有常见的用户界面或者控制台)。换句话说,一个服务就是一个始终运行于系统中的 Win32 进程,即使没有用户登陆进来也如此。SC 管理器(即服务控制管理器)可以控制服务和驱动程序。

主要涉及的函数如下:
名 称          描 述
CloseServiceHandle        关闭来自 OpenSCManager() 、 CreateService() 或 OpenService() 的句柄
ControlService        停止、暂停、继续、查询或通知已加载的服务 / 驱动程序
CreateService        加载一个服务 / 驱动程序
DeleteService        卸载一个服务 / 驱动程序
OpenSCManager        获取 SC 管理器的句柄
OpenService         获取一个已加载的服务 / 驱动程序的句柄
QueryServiceStatus         查询一个服务 / 驱动程序的属性和当前状态
StartService         启动一个已加载的服务 / 驱动程序

加载和运行一个服务需要执行的典型操作步骤:

1. 调用 OpenSCManager() 以获取一个管理器句柄
2. 调用 CreateService() 来向系统中添加一个服务
3. 调用 StartService() 来运行一个服务
4. 调用 CloseServiceHandle() 来释放管理器或服务句柄

不过我这里决定把加载驱动和启动驱动的过程分开,这样容易看明白,如果想整合也很容易,直接调用两个函数就可以了。

一 打开SCM
第一步需要做的是和SCM交互,则要使用OpenSCManager函数。原型如下:
SC_HANDLE OpenSCManager(LPCTSTR lpMachineName,
              LPCTSTR lpDatabaseName,
              DWORD dwDesiredAccess);
lpMachineName:电脑名。如果为NULL,则为本机。
lpDatabaseName:SCM数据库标识,应该为SERVICES_ACTIVE_DATABASE或者如果为NULL,则SEVICES_ACTIVE_DATABASE数据库作为默认数据库被打开。
dwDesiredAccess:以何种权限打开。
本函数返回一个SC_HANDLE的句柄以便作为其他函数的参数来操作SCM数据库。

当完成对SCM数据库的访问后,在退出前必须使用CloseServiceHandle关闭它。原型为:
BOOL CloseServiceHandle(SC_HANDLE hSCManger);

二 创建服务
增加一个Service,需要用到CreateService函数,原型如下:
SC_HANDLE CreateService(SC_HANDLE hSCManager,
             LPCTSTR lpServiceName,
             LPCTSTR lpDisplayName,
             DWORD dwDesireAccess,
             DWORD dwServiceType,
             DWORD dwStartType,
             DWORD dwErrorControl,
             LPCTSTR lpBinaryPathName,
             LPCTSTR lpLoadOrderGroup,
             LPDWORD lpdwTagId,
             LPCTSTR lpDependencies,
             LPCTSTR lpServiceStartName,
             LPCTSTR lpPassword);
这个函数有十三个参数:
hSCManager:是OpenSCManager得到的返回值,即服务管理器的句柄。
lpServiceName:Service的名字,,同时注册表也使用这个名字,这个Service的相应信息存放在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Service\lpServiceName子键下;
lpDisplayName:Service在服务控制面板中显示的名字;
dwDesireAccess:访问Service的权限类型;
dwServiceType:Service的类型,可以是SERVICE_FILE_SYSTEM_DRIVER、SERVICE_KERNEL_DRIVER、SERVICE_WIN32_OWN_PROCESSS、SERVICE_WIN32_SHARE_PROCESS之一;
dwStartType:Service启动类型,可以是自动(SERVICE_ATUO_START)、手动(SERVICE_DEMAND_START)、禁止(SERVICE_DISABLED);
dwErrorControl:出错控制,SERVICE_ERROR_IGNORE和SERVICE_ERROR_NORMAL表示出错时在日志中纪录并继续。两个参数的区别是SERVICE_ERROR_NORMAL将会在出错时向用户显示一条出错信息,SERVICE_ERROR_SERVER和SERVICE_ERROR_CRITICAL告诉系统在失败时重启;
lpBinaryPathName:驱动的路径,也是服务的路径;
lpLoadOrderGroup:如果这个服务是加载服务组中的一个,这个指针指向这者字符串数组,一般为NULL;
lpdwTagId:指针,指向的变量,接收的值用於区别lpLoadOrderGroup服务组中的不同服务,一般为NULL;
lpDependencies:这个Service所依赖的其他服务,在启动本Service之前需要先启动这些服务;
lpServiceStartName:帐号;
lpPassword:密码。
需要注意的是,如果要增加一个Service,那么OpenSCManager函数中的dwDesiredAccess参数至少需要为SC_MANAGER_CREATE_SERVICE。

三 启动服务
启动Service,相应函数如下:
BOOL StartService(SC_HANDLE hService,
         DWORD dwNumServiceArgs,
         LPCTSTR *lpServiceArgVectors);
hService:Service的句柄;
dwNumServiceArgs:指定在lpServiceArgVectors指向的数组中参数的个数,如果lpServiceArgVectors为NULL,这个值为0;
lpServiceArgVectors:指向传递给Service的参数字符串数组的指针,可以为NULL;

Service运行之后,ControlService函数用于的控制,函数原型如下:
BOOL ControlService(SC_HANDLE hService,
          DWORD dwControl,
          LPSERVICE_STATUS lpServiceStatus);
hService:Service句柄;
dwControl:SERVICE_CONTROL_STOP,SERVICE_CONTROL_PAUSE,SERVICE_CONTROL_CONTINUE,SERVICE_CONTROL_INTERROGATE之一,也可以自定义(128~255);
lpServiceStatus:一个LPSERVICE_STATUS的结构指针。

如果想停止服务,也需要使用该函数来进行控制。

BOOL QueryServiceStatus(SC_HANDLE hService,
            LPSERVICE_STATUS lpServiceStatus);
调用QueryServiceStatus函数和调用带SERVICE_CONTROL_INTERROGATE参数的ControlService相差无几。
使用该函数进行服务状态的查询,比如判断服务是否已经启动,服务是否停止了。

好,下面就是代码了,我使用的是delphi7,把这些功能写在一个类中,代码很容易明白。也就不多说了。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (13)
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
2
偶经常用ZwLoadDriver。

呵呵。
2007-12-28 18:44
0
雪    币: 1919
活跃值: (901)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
3
谢谢楼主的文章~~~
2007-12-28 18:53
0
雪    币: 271
活跃值: (18)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
4
恩...赖大哥  写的不错...
2007-12-28 20:19
0
雪    币: 486
活跃值: (13)
能力值: ( LV9,RANK:430 )
在线值:
发帖
回帖
粉丝
5
恭喜楼主完成一个成果。
2007-12-29 00:29
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
搜索内存要用到驱动方面的东西吗?
2007-12-30 22:07
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
是不是写驱动(就是制造SYS文件),就只能用C 或者ASM了????
2008-1-2 08:19
0
雪    币: 266
活跃值: (60)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
8
要有相应的ddk就可以了,delphi就有一个驱动的ddk,可以用delphi写,不过一般都没这么做,微软的ddk编译器没办法用c++,所以只有c和asm了。
2008-1-2 08:39
0
雪    币: 12
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
学习...
放假准备进军驱动方向了
2008-1-2 09:41
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
学习驱动的好教程啊
2008-1-2 10:30
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我编辑不了  ..晕
2017-10-5 17:47
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
不知道为何呀····
2017-10-5 17:47
0
雪    币: 15
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
13
学习了
2017-10-16 12:20
0
雪    币: 0
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
配置vs环境的时候部署驱动不成功,总显示目标计算机进程执行出错。
上传的附件:
2017-10-23 15:04
0
游客
登录 | 注册 方可回帖
返回
//