吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1308|回复: 6
收起左侧

[已解决] 内核驱动是怎么安装及卸载得很好的?

[复制链接]
你不会了解 发表于 2021-11-29 13:35
本帖最后由 你不会了解 于 2021-11-29 16:17 编辑

我是通过,OpenSCManager\CreateService\OpenService进行安装驱动,通过OpenSCManager\CreateService\ControlService\DeleteService进行卸载。

问题1:怎么让用户看不见sys驱动文件?

每次安装的时候,我的sys驱动文件和exe文件都在同一目录下,但是我看别的软件,也许就一个exe就能默默的安装了驱动

问题2:安装驱动是不是只能通过OpenSCManager这个服务的方式来进行安装?

PChunter有一个选项是禁止加载驱动,他是不是拦截了我上述的一系列函数搞定的?

问题3:怎么样可以将自己安装的驱动在程序退出时卸载得干干净净?

我通过上面的方式进行卸载,可是实际上注册表里还有,即便我手动删除了注册表,再次进行安装的时候也会失败,除非重启。

三个问题,求大佬帮忙解答。

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

lyl610abc 发表于 2021-11-29 15:02
1.所谓的看不见是指不放在同目录下?或者放在C:\Windows\System32\drivers等系统默认路径下?使用相对路径即可。你所说的一个exe默默安装驱动应该是把驱动释放到其他路径下进行加载
2.安装驱动的常规方法是通过SCMManager来加载,也可以通过自己写入注册表项 "计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services”并直接调用 NtLoadDriver  或者 使用NtSetSystemInformation等其他方式进行加载
3.正常驱动停止卸载后注册表里是没有内容的,本身就是干干净净的

免费评分

参与人数 1吾爱币 +1 收起 理由
你不会了解 + 1 谢谢@Thanks!

查看全部评分

 楼主| 你不会了解 发表于 2021-11-29 15:53
lyl610abc 发表于 2021-11-29 15:02
1.所谓的看不见是指不放在同目录下?或者放在C:\Windows\System32\drivers等系统默认路径下?使用相对路径 ...

问题一,我能理解成,别的软件是先把sys驱动文件的二进制存入自身代码里,然后自身exe运行到某一步的时候,找个文件夹下创建文件CreateFile,再把sys驱动文件的二进制WriteFile写进去,最后得到其地址再进行加载吗?
lyl610abc 发表于 2021-11-29 15:59
你不会了解 发表于 2021-11-29 15:53
问题一,我能理解成,别的软件是先把sys驱动文件的二进制存入自身代码里,然后自身exe运行到某一步的时候 ...

对的,可以这么做
yunruifuzhu 发表于 2021-11-29 16:03
[C++] 纯文本查看 复制代码
// 安装驱动
BOOL installDvr(CONST WCHAR drvPath[50], CONST WCHAR serviceName[20]) {

	// 打开服务控制管理器数据库
	SC_HANDLE schSCManager = OpenSCManager(
		NULL,                   // 目标计算机的名称,NULL:连接本地计算机上的服务控制管理器
		NULL,                   // 服务控制管理器数据库的名称,NULL:打开 SERVICES_ACTIVE_DATABASE 数据库
		SC_MANAGER_ALL_ACCESS   // 所有权限
	);
	if (schSCManager == NULL) {
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 创建服务对象,添加至服务控制管理器数据库
	SC_HANDLE schService = CreateService(
		schSCManager,               // 服务控件管理器数据库的句柄
		serviceName,                // 要安装的服务的名称
		serviceName,                // 用户界面程序用来标识服务的显示名称
		SERVICE_ALL_ACCESS,         // 对服务的访问权限:所有全权限
		SERVICE_KERNEL_DRIVER,      // 服务类型:驱动服务
		SERVICE_DEMAND_START,       // 服务启动选项:进程调用 StartService 时启动
		SERVICE_ERROR_IGNORE,       // 如果无法启动:忽略错误继续运行
		drvPath,                    // 驱动文件绝对路径,如果包含空格需要多加双引号
		NULL,                       // 服务所属的负载订购组:服务不属于某个组
		NULL,                       // 接收订购组唯一标记值:不接收
		NULL,                       // 服务加载顺序数组:服务没有依赖项
		NULL,                       // 运行服务的账户名:使用 LocalSystem 账户
		NULL                        // LocalSystem 账户密码
	);
	if (schService == NULL) {
		CloseServiceHandle(schService);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	CloseServiceHandle(schService);
	CloseServiceHandle(schSCManager);
	return TRUE;
}

// 启动服务
BOOL startDvr(CONST WCHAR serviceName[20]) {

	// 打开服务控制管理器数据库
	SC_HANDLE schSCManager = OpenSCManager(
		NULL,                   // 目标计算机的名称,NULL:连接本地计算机上的服务控制管理器
		NULL,                   // 服务控制管理器数据库的名称,NULL:打开 SERVICES_ACTIVE_DATABASE 数据库
		SC_MANAGER_ALL_ACCESS   // 所有权限
	);
	if (schSCManager == NULL) {
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 打开服务
	SC_HANDLE hs = OpenService(
		schSCManager,           // 服务控件管理器数据库的句柄
		serviceName,            // 要打开的服务名
		SERVICE_ALL_ACCESS      // 服务访问权限:所有权限
	);
	if (hs == NULL) {
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}
	if (StartService(hs, 0, 0) == 0) {
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}


	CloseServiceHandle(hs);
	CloseServiceHandle(schSCManager);
	return TRUE;
}

// 停止服务
BOOL stopDvr(CONST WCHAR serviceName[20]) {

	// 打开服务控制管理器数据库
	SC_HANDLE schSCManager = OpenSCManager(
		NULL,                   // 目标计算机的名称,NULL:连接本地计算机上的服务控制管理器
		NULL,                   // 服务控制管理器数据库的名称,NULL:打开 SERVICES_ACTIVE_DATABASE 数据库
		SC_MANAGER_ALL_ACCESS   // 所有权限
	);
	if (schSCManager == NULL) {
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 打开服务
	SC_HANDLE hs = OpenService(
		schSCManager,           // 服务控件管理器数据库的句柄
		serviceName,            // 要打开的服务名
		SERVICE_ALL_ACCESS      // 服务访问权限:所有权限
	);
	if (hs == NULL) {
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 如果服务正在运行
	SERVICE_STATUS status;
	if (QueryServiceStatus(hs, &status) == 0) {
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}
	if (status.dwCurrentState != SERVICE_STOPPED &&
		status.dwCurrentState != SERVICE_STOP_PENDING
		) {
		// 发送关闭服务请求
		if (ControlService(
			hs,                         // 服务句柄
			SERVICE_CONTROL_STOP,       // 控制码:通知服务应该停止
			&status                     // 接收最新的服务状态信息
		) == 0) {
			CloseServiceHandle(hs);
			CloseServiceHandle(schSCManager);
			return FALSE;
		}

		// 判断超时
		INT timeOut = 0;
		while (status.dwCurrentState != SERVICE_STOPPED) {
			timeOut++;
			QueryServiceStatus(hs, &status);
			Sleep(50);
		}
		if (timeOut > 80) {
			CloseServiceHandle(hs);
			CloseServiceHandle(schSCManager);
			return FALSE;
		}
	}

	CloseServiceHandle(hs);
	CloseServiceHandle(schSCManager);
	return TRUE;
}

// 卸载驱动
BOOL unloadDvr(CONST WCHAR serviceName[20]) {

	// 打开服务控制管理器数据库
	SC_HANDLE schSCManager = OpenSCManager(
		NULL,                   // 目标计算机的名称,NULL:连接本地计算机上的服务控制管理器
		NULL,                   // 服务控制管理器数据库的名称,NULL:打开 SERVICES_ACTIVE_DATABASE 数据库
		SC_MANAGER_ALL_ACCESS   // 所有权限
	);
	if (schSCManager == NULL) {
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 打开服务
	SC_HANDLE hs = OpenService(
		schSCManager,           // 服务控件管理器数据库的句柄
		serviceName,            // 要打开的服务名
		SERVICE_ALL_ACCESS      // 服务访问权限:所有权限
	);
	if (hs == NULL) {
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	// 删除服务
	if (DeleteService(hs) == 0) {
		CloseServiceHandle(hs);
		CloseServiceHandle(schSCManager);
		return FALSE;
	}

	CloseServiceHandle(hs);
	CloseServiceHandle(schSCManager);
	return TRUE;
}
int main()
{
	if (installDvr(L"procexp64.sys", L"我的驱动名称") == TRUE) {
		printf("安装驱动成功!\n");

	}
	if (startDvr(L"我的驱动名称") == TRUE) {
		printf("启动驱动成功!\n");
	}	
	if (stopDvr(L"我的驱动名称") == TRUE) {
		printf("停止驱动成功!\n");
	}
	if (unloadDvr(L"我的驱动名称") == TRUE) {
		printf("卸载驱动成功!\n");
	}

	getchar();
	return 0;

}

免费评分

参与人数 1热心值 +1 收起 理由
你不会了解 + 1 谢谢@Thanks!

查看全部评分

 楼主| 你不会了解 发表于 2021-11-29 16:15
yunruifuzhu 发表于 2021-11-29 16:03
[mw_shl_code=cpp,true]// 安装驱动
BOOL installDvr(CONST WCHAR drvPath[50], CONST WCHAR serviceName[ ...

感谢回复,最终发现是我在安装和卸载之间,创建设备和驱动层沟通了,但是CreateFile的设备没有释放,然后就会卸载失败
chuang2015 发表于 2021-11-29 16:23
把驱动存储到资源 然后运行时释放,然后驱动力写代码删除自身 ,别人就看不见了

禁止加载驱动 写个 minifiter 就能拦截,或者写个回调 禁止注册表操作 \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 18:30

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表