0%

SYSManger

驱动管理器

相对于之前使用net于sc命令进行操作的命令行工具,完全可以自己进行编写一个小软件进行自动化的测试。

加载函数

首先我们需要编写加载驱动以及卸载驱动的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/************************************************************************/
/* 用来加载驱动程序 */
/************************************************************************/
BOOL LoadNTDriver(char* lpszDreverName,char * lpszDriverPath)
{
char szDriverImagePath[256];
GetFullPathName(lpszDriverPath,256,szDriverImagePath,NULL);
BOOL bRet = FALSE;
SC_HANDLE hServiceMgr = NULL;//scm管理器的句柄
SC_HANDLE hServiceDDK = NULL;//NT驱动的服务句柄
hServiceMgr = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (hServiceMgr == NULL)
{
printf("OpenSCManger() Faild %d\n",GetLastError());
goto BeforeLeave;
}
else
{
printf("OpenSCManger() OK\n");
}
hServiceDDK = CreateService(hServiceMgr,lpszDreverName,lpszDreverName,SC_MANAGER_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START
,SERVICE_ERROR_IGNORE,szDriverImagePath,NULL,NULL,NULL,NULL,NULL);

DWORD dwRtn;
if (hServiceDDK == NULL)
{
dwRtn = GetLastError();
if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS)
{
printf("CreateService失败,错误号:%d\n",dwRtn);
goto BeforeLeave;
}
else
{
printf("服务之前已经创建过了,正在打开之前的服务!\n");
hServiceDDK = OpenService(hServiceMgr,lpszDreverName,SERVICE_ALL_ACCESS);
if (hServiceDDK == NULL)
{
printf("打开服务出错 错误码:%d",GetLastError());
goto BeforeLeave;
}
else
{
printf("打开服务成功");
}
}
}else
{
printf("CreateService 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",dwRtn);
bRet = FALSE;
goto BeforeLeave;
}
else
{
if (dwRtn == ERROR_IO_PENDING)
{
//设备被挂起
printf("设备已经被挂起");
bRet = FALSE;
goto BeforeLeave;
}
else
{
//服务已经启动了
printf("服务之前已经启动了! ERROR_SERVICE_ALREADY_RUNNING");
bRet = TRUE;
goto BeforeLeave;
}
}
}
bRet = TRUE;
BeforeLeave:
if (hServiceMgr)
CloseServiceHandle(hServiceMgr);
if(hServiceDDK)
CloseServiceHandle(hServiceDDK);
return bRet;
}

其实代码阅读起来很简单,首先就是我们获取文件的完整路径,然后我们打开SC的句柄(判断性质的就不记录了),接着我们创建服务,创建服务的时候我们需要用到我们之前得到的SC句柄,创建失败的话呢我们判断是否是之前的服务,如果是就打开。我们接下来启动服务,然后就是简单的判断,需要注意的是,这里用到了很老的goto语句。

卸载函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

/************************************************************************/
/* 用来卸载驱动 */
/************************************************************************/
BOOL UnLoadNTDriver(char * szSvrName)
{
BOOL bRet = FALSE;
SC_HANDLE hServiceMgr = NULL;//scm管理器的句柄
SC_HANDLE hServiceDDK = NULL;//NT驱动的服务句柄
SERVICE_STATUS SvrSta;
hServiceMgr = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if(hServiceMgr == NULL)
{
//打开SCM管理器
printf("OpenSCManager失败:%d\n",GetLastError());
bRet = FALSE;
goto BeforeLeave;
}else
{
printf("OpenSCManager成功\n");
}
//打开驱动所对应的服务
hServiceDDK = OpenService(hServiceMgr,szSvrName,SERVICE_ALL_ACCESS);
if (hServiceDDK == NULL)
{
//打开驱动所对应的服务失败
printf("OpenService打开服务失败Faild:%d\n",GetLastError());
bRet = FALSE;
goto BeforeLeave;
}
else
{
printf("OpenService打开成功\n");
}
if (!ControlService(hServiceDDK,SERVICE_CONTROL_STOP,&SvrSta))
{
printf("ControlService faild :%d\n",GetLastError());
bRet = FALSE;
goto BeforeLeave;
}
else
{
printf("ControlService成功\n");
}
//动态卸载驱动
if (!DeleteService(hServiceDDK))
{
printf("DeleteService faild:%d\n",GetLastError());
}
else
{
printf("DeleteService 删除成功\n");
}
bRet = TRUE;
BeforeLeave:
if (hServiceMgr)
CloseServiceHandle(hServiceMgr);
if(hServiceDDK)
CloseServiceHandle(hServiceDDK);
return bRet;
}

卸载函数在打开服务之前是一样的,区别就是不打开服务了,直接进行控制服务,使用SERVICE_CONTROL_STOP停止服务,然后通过delete删除服务就完成了。

主控制函数的话呢就是获取控制台参数就可以了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int _tmain(int argc, _TCHAR* argv[])
{
if (argc <3)
{
printf("需要两个参数,第一个是临时服务的名称,第二个是你的驱动路径!");
system("pause");
return -1;
}
BOOL bRet = LoadNTDriver(argv[1],argv[2]);
if(!bRet)
{
printf("驱动加载失败");
return -2;
}
printf("按任何键卸载驱动");
getchar();
bRet = UnLoadNTDriver(argv[1]);
if (!bRet)
{
printf("驱动卸载失败");
return -3;
}
return 0;
}

运行的效果:
sysmanger

其他程序

其实类似的程序有个叫做KmdManager.exe这个的程序其实就是比较好用的。