众所周知,驱动运行在ring0层,故此,驱动可以调用更多的API,但是,同时的也无法调用部分应用层API。
驱动通常分为两种,一种是不支持即插即用功能的NT型驱动,另一种是支持即插即用的WDM型驱动,其中,WDM通常用于设备,因此需要使用INF文件进行注册。而NT型驱动则通常使用服务创建。
人工加载
按下Windows键加R,换成运行,在编辑框中输入cmd。
点击确定,唤出命令提示符。
然后输入一下命令
sc create [在这里填充服务名] binpath="[在这里填充文件的完整绝对路径]" type=kernel start=[在这里填充启动方式] ;注:启动方式主要分为BOOT(即引导阶段启动)、SYSTEM(即操作系统启动阶段)、AUTO(系统启动完毕后启动)、DEMAND(不自启)
例如:
接着,若提示成功,则调用以下命令
sc start [这里填充刚刚注册的服务名]
这个的作用是启动驱动
注意
若以上步骤出现了问题,提示驱动数字签名损坏等,不能完成操作,则说明系统启用了驱动强制签名。
解决办法:禁用系统驱动强制签名或申请正规驱动签名
在这之前
以下程序在VISTA系统以上仍然会受驱动程序强制签名的约束。
解决办法:禁用系统驱动强制签名或申请正规驱动签名。
相关头文件:
#include#include
函数原型:
SC_HANDLE WINAPI OpenService( _In_ SC_HANDLE hSCManager, _In_ LPCTSTR lpServiceName, _In_ DWORD dwDesiredAccess );
SC_HANDLE CreateService(
SC_HANDLE hSCManager, //服务控制管理程序维护的登记数据库的句柄,由系统函数OpenSCManager 返回
LPCTSTR lpServiceName, //以NULL 结尾的服务名,用于创建登记数据库中的关键字
LPCTSTR lpDisplayName, //以NULL 结尾的服务名,用于用户界面标识服务
DWORD dwDesiredAccess, //指定服务返回类型
DWORD dwServiceType, //指定服务类型
DWORD dwStartType, //指定何时启动服务
DWORD dwErrorControl, //指定服务启动失败的严重程度
LPCTSTR lpBinaryPathName, //指定服务程序二进制文件的路径
LPCTSTR lpLoadOrderGroup, //指定顺序装入的服务组名
LPDWORD lpdwTagId, //忽略,NULL
LPCTSTR lpDependencies, //指定启动该服务前必须先启动的服务或服务组
LPCTSTR lpServiceStartName, //以NULL 结尾的字符串,指定服务帐号。如是NULL,则表示使用LocalSystem 帐号
LPCTSTR lpPassword //以NULL 结尾的字符串,指定对应的口令。为NULL表示无口令。但使用LocalSystem时填NULL
);
SC_HANDLE WINAPI OpenSCManager( _In_opt_ LPCTSTR lpMachineName, _In_opt_ LPCTSTR lpDatabaseName, _In_ DWORD dwDesiredAccess );
程序实现
SC_HANDLE hScm; SC_HANDLE hS; hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);//以完全权限打开服务管理器
以上代码用于打开系统服务管理器。
hS = CreateService(hScm, a, a, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_BOOT_START, SERVICE_ERROR_IGNORE, b, NULL, NULL, NULL, NULL, NULL);//创建一个在引导阶段启动的服务,并返回句柄。 StartService(hS, NULL, NULL);//启动服务 CloseServiceHandle(hS);//关闭句柄,释放资源 CloseServiceHandle(hScm);
下面放完整代码
// 加载卸载驱动Dlg.cpp : 实现文件 // #include "stdafx.h" #include "加载卸载驱动.h" #include "加载卸载驱动Dlg.h" #include "afxdialogex.h" #include#include #include #ifdef _DEBUG #define new DEBUG_NEW #endif // C加载卸载驱动Dlg 对话框 C加载卸载驱动Dlg::C加载卸载驱动Dlg(CWnd* pParent ) : CDialogEx(IDD_MY_DIALOG, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINframe); } void C加载卸载驱动Dlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(C加载卸载驱动Dlg, CDialogEx) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON1, &C加载卸载驱动Dlg::OnBnClickedButton1) ON_BN_CLICKED(IDC_BUTTON2, &C加载卸载驱动Dlg::OnBnClickedButton2) END_MESSAGE_MAP() // C加载卸载驱动Dlg 消息处理程序 BOOL C加载卸载驱动Dlg::onInitDialog() { CDialogEx::onInitDialog(); // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 system("bcdedit /debug on"); // TODO: 在此添加额外的初始化代码 int a1=MessageBox("首次启动?因为首次启动需要初始化,需要重启,所以如果是,请点击“是”,就会重启,如果已经在点击“是”按钮的情况下重启,则点击否", "首次启动?", MB_YESNO); if (a1== IDYES) { HANDLE hToken; TOKEN_PRIVILEGES tkp; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { MessageBox(_T("关机失败..."), _T("警告"), MB_OK); } LookupPrivilegevalue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, NULL); if (GetLastError() != ERROR_SUCCESS) { MessageBox(_T("关机失败..."), _T("警告"), MB_OK); } ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0); //重启只需要把EWX_SHUTDOWN改为EWX_REBOOT } //AllocConsole(); CString a,b; //_cprintf("First start the program open to restart again, please"); //_cprintf("Please enter the driver file name(Drive will automatically start when computer boot):"); GetDlgItem(IDC_EDIT1)->GetWindowText(a); //_cprintf("Please enter the driver file path:"); GetDlgItem(IDC_EDIT2)->GetWindowText(b); //_cprintf("n"); //FreeConsole(); SC_HANDLE hScm; SC_HANDLE hS; hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); hS = CreateService(hScm, a, a, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_BOOT_START, SERVICE_ERROR_IGNORE, b, NULL, NULL, NULL, NULL, NULL); StartService(hS, NULL, NULL); CloseServiceHandle(hS); CloseServiceHandle(hScm); //ShowWindow(SW_HIDE); //ShowWindow(SW_HIDE); //ShowWindow(SW_HIDE); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void C加载卸载驱动Dlg::onPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast (dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::onPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR C加载卸载驱动Dlg::onQueryDragIcon() { return static_cast (m_hIcon); } void C加载卸载驱动Dlg::OnBnClickedButton1() { FreeConsole(); // TODO: 在此添加控件通知处理程序代码 } void C加载卸载驱动Dlg::OnBnClickedButton2() { //AllocConsole(); CString a; //_cprintf("Please enter the driver file name:"); GetDlgItem(IDC_EDIT1)->GetWindowText(a); //_cprintf("n"); //FreeConsole(); SC_HANDLE hScm; SC_HANDLE hS; SERVICE_STATUS status; hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); hS = OpenService(hScm, a, SERVICE_ALL_ACCESS); ControlService(hS, SERVICE_CONTROL_STOP, &status); DeleteService(hS); CloseServiceHandle(hS); CloseServiceHandle(hScm); // TODO: 在此添加控件通知处理程序代码 }



