最近想自己写个驱动加载程序。(平常用的加载程序不能拖动选择文件)
于是梳理一下驱动加载的两种方法
需要的函数:
通过OpenSCManager
函数打开SCM,获取其句柄
通过CreateService
函数利用SCM句柄创建一个服务
通过ControlService
传入的标志位安装启动服务等等。
两步安装驱动:
这两个函数做完后,核心的安装就完成了。
启动驱动
控制状态,停止驱动
卸载驱动
在返回结果异常的判断GetLastError()
中,加入了几个常见的判断
代码比较长,先贴一下安装代码,其余的可以在附件查看
效果(目标平台win10)
最后和普通的monitor加载的效果是一样的。
这个是RootKits的技术。
ZwSetSystemInformation函数是个未公开的函数,调用38号则会加载驱动。
原型如下
我们需要手动获取函数的地址
RtlInitUnicodeString
,ZwSetSystemInformation
这种方法的特性是比较简便隐秘,相比上一个方法不会在进程中主动查找服务管理器等敏感API。但是,这种方法没有提供卸载的特性,驱动加载后,只能通过重启系统来卸载。
最后,代码也贴在github一份。
SC_HANDLE sh = OpenSCManager(
NULL, // 机器名称,NULL表示本机.
NULL, // 设备管理器数据库,NULL表示默认值
SC_MANAGER_ALL_ACCESS // 打开的权限
);
SC_HANDLE m_hServiceDDK = CreateService(
sh,//SCManager句柄
DriverName.c_str(),//驱动服务名称
DriverName.c_str(),//驱动服务显示名称
SERVICE_ALL_ACCESS,//访问权限
SERVICE_KERNEL_DRIVER,//服务类型(驱动程序)
SERVICE_DEMAND_START,//启动方式(需要时启动,注册表驱动程序的Start值)
SERVICE_ERROR_IGNORE,//错误忽略
szFilePath,//驱动程序文件路径
NULL,//加载组命令
NULL,//TagId
NULL,//依存关系
NULL,//服务启动名
NULL);//密码
BOOL WINAPI StartService(
_In_ SC_HANDLE hService,
_In_ DWORD dwNumServiceArgs,
_In_opt_ LPCTSTR *lpServiceArgVectors
);
m_hServiceDDK = OpenService(sh, DriverName.c_str(), SERVICE_STOP);
SERVICE_STATUS svcsta = { 0 };
BOOL bRet = ControlService(m_hServiceDDK, SERVICE_CONTROL_STOP, &svcsta);
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!