zoukankan      html  css  js  c++  java
  • 编写内核驱动加载工具

               编写内核驱动加载工具

    一丶加载内核驱动的常用API介绍.

    加载内核驱动,使用我们的ring3下的API即可完成.

    API分别是:

    OpenSCManager  打开设备(服务)管理器

    CreateService  创建服务(或者设备,根据参数不同而不同)

    OpenService     打开设备或者服务.

    StartService           启动服务,启动设备.

    ControlService       控制设备或者服务的状态.

    CloseServiceHandle 关闭服务或者设备的句柄

    DeleteService       卸载服务

    参数介绍:

    1.打开设备管理器

    SC_HANDLE OpenSCManager(
      LPCTSTR lpMachineName,   // 机器名称.可以制定计算机,如不指定,给NULL则是打开自己.
      LPCTSTR lpDatabaseName,  // 打开设备管理器数据库的名称,如果为NULL则使用默认的.
      DWORD dwDesiredAccess    // 打开的权限.
    );

    返回值:

      成功: 返回设备管理器的句柄

      失败: 返回NULL

    2.创建设备或者服务.

    SC_HANDLE CreateService( 
    SC_HANDLE hSCManager, //设备管理器句柄,通过OpenScManger返回 LPCTSTR lpServiceName, // 服务或者设备启动的名称 LPCTSTR lpDisplayName, // 服务或者的显示名称 DWORD dwDesiredAccess, // 访问服务或者设备的权限 DWORD dwServiceType, // 创建的服务或者设备的类型,如果是内核驱动,则通过这里给 DWORD dwStartType, // 服务或者设备何时启动 DWORD dwErrorControl, // 服务或者设备如果启动出错,则指定一下应用程序应该怎么做,(重启,或者重新长还是.) LPCTSTR lpBinaryPathName, // 服务或者设备的文件路径,必须给. LPCTSTR lpLoadOrderGroup, // 服务或者设备排租. LPDWORD lpdwTagId, // 可以通过注册表来启动服务. LPCTSTR lpDependencies, // array of dependency names LPCTSTR lpServiceStartName, // 服务的启动名称. LPCTSTR lpPassword // 密码;

    返回值:

      成功: 返回创建服务或者设备的句柄.

      失败: 返回NULL

    3.打开服务或者设备.

    SC_HANDLE OpenService(
      SC_HANDLE hSCManager,  // 设备管理器的句柄,通过OpenScManger返回.
      LPCTSTR lpServiceName, // 服务或者设备的名称.
      DWORD dwDesiredAccess  // 打开服务或者设备的权限.
    );

    返回值:

      成功: 返回服务或者设备的句柄.

      失败: 返回NULL

    4.启动服务或者设备.

    BOOL StartService(
      SC_HANDLE hService,            // 服务或者设备句柄
      DWORD dwNumServiceArgs,        // 二维数组的个数.
      LPCTSTR* lpServiceArgVectors   // 二维数组.其中每组存储一个服务名称.如果是内核驱动则都给NULL即可.
    );

    返回值:

      成功: 返回非零值

      失败: 返回零值.

    5.控制服务或者设备.

    BOOL ControlService(
      SC_HANDLE hService,               // 服务或者设备句柄,通过OpenService或者CreateService返回.
      DWORD dwControl,                  //控制代码. 如果给SERVICE_CONTROL_PAUSE那么服务就会暂停
      LPSERVICE_STATUS lpServiceStatus  // 服务的状态.是一个结构体,操作系统帮你填好.

    结构体:

    typedef struct _SERVICE_STATUS { 
      DWORD dwServiceType;     //服务的类型
      DWORD dwCurrentState;    //服务的当前状态,暂停状态还是停止状态....
      DWORD dwControlsAccepted;    //服务的控制码.
      DWORD dwWin32ExitCode;    //服务错误或者停止返回的错误驮
      DWORD dwServiceSpecificExitCode; //服务启动的是否返回的错误代码.
      DWORD dwCheckPoint;      //服务开启的是否的用于统计的次数.到达100则启动完成.一般进度条使用
      DWORD dwWaitHint; 
    } SERVICE_STATUS, *LPSERVICE_STATUS//给定一个期望值.时间.然后按照时间一点一点的启动.

    6.关闭服务句柄.

    BOOL CloseServiceHandle(
      SC_HANDLE hSCObject   // 服务或者设备的句柄
    );

     7.卸载服务

    BOOL DeleteService(  SC_HANDLE hService   // handle to service);

    二丶详细代码

    上面是简单的API介绍.下面则贴出完整的代码.

    请注意我这里使用的是MFC编写的. 但是其每个函数不会互相依赖.如果你是拷贝代码.则之间诶拷贝过去就可以使用.

    1.安装内核驱动代码

     m_CreateService = CreateService(
            m_ScHand, 
            服务或者设备名称,   //例如: MySystem.sys
            服务或者设备的名称,
            SC_MANAGER_ALL_ACCESS,
            SERVICE_KERNEL_DRIVER,//安装的属性,我这里给的是内核的.所以安装的是内核.
            SERVICE_DEMAND_START,
            SERVICE_ERROR_SEVERE,
            m_EdtPathName,
            NULL,
            NULL,
            NULL,
            NULL,
            NULL);
        if (m_CreateService == NULL)
        {
            ::CloseServiceHandle(m_CreateService);
            ::CloseServiceHandle(m_ScHand);
            ::MessageBox(NULL, TEXT("Sorry Install Drive Fail"), TEXT("Error"), NULL);
            return;
        }
        ::CloseServiceHandle(m_CreateService);
        ::CloseServiceHandle(m_ScHand);
        ::MessageBox(NULL, TEXT("InStall Drive Sucess"), TEXT("Sucess"), NULL);

    2.卸载代码

         m_ScHand = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        if (m_ScHand == NULL)
        {
            ::MessageBox(NULL, TEXT("Sorry OpenScManger Fail
    "), TEXT("Error"), MB_ICONEXCLAMATION);
            return;
        }
        //open Service
        m_CreateService = OpenService(m_ScHand, m_ServiceName, SERVICE_STOP | DELETE);
        if (m_CreateService == NULL)
        {
            ::MessageBox(NULL, TEXT("Sorry Install Drive Fail"), TEXT("Error"), NULL);
            return;
        }
        BOOL bRet = FALSE;
              bRet = DeleteService(m_CreateService);
             if (!bRet)
             {
                 ::CloseServiceHandle(m_CreateService);
                 ::CloseServiceHandle(m_ScHand);
                 ::MessageBox(NULL, TEXT("Sorry UnInstall Drive Fail"), TEXT("Error"), NULL);
                 return;
             }
            
    
      
         DeleteService(m_CreateService);
        ::CloseServiceHandle(m_CreateService);
        ::CloseServiceHandle(m_ScHand);
        ::MessageBox(NULL, TEXT("UnInstall Drive Sucess"), TEXT("Sucess"), NULL);

    3.启动内核驱动的代码

      m_ScHand = NULL;
        m_CreateService = NULL;
        m_ScHand = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        if (m_ScHand == NULL)
        {
            ::MessageBox(NULL, TEXT("Sorry OpenScManger Fail
    "), TEXT("Error"), MB_ICONEXCLAMATION);
            return;
        }
        //open Service
        m_CreateService = OpenService(m_ScHand, m_ServiceName, SERVICE_START);
        if (m_CreateService == NULL)
        {
            ::MessageBox(NULL, TEXT("Sorry Start Drive Fail"), TEXT("Error"), NULL);
            return;
        }
    
        UpdateData(TRUE);
        BOOL bRet = StartService(m_CreateService,0,NULL); //重要的地方.
    
        if (bRet == NULL)
        {
            ::CloseServiceHandle(m_CreateService);
            ::CloseServiceHandle(m_ScHand);
            ::MessageBox(NULL, TEXT("Sorry Start Service Fail
    "), TEXT("Error"), IDOK);
            return;
        }
    
        ::CloseServiceHandle(m_CreateService);
        ::CloseServiceHandle(m_ScHand);
        ::MessageBox(NULL, TEXT(" Start Service Sucess
    "), TEXT("Sucess"), IDOK);

    4..暂停内核驱动.

    m_ScHand = NULL;
        m_CreateService = NULL;
        UpdateData(TRUE);
        m_ScHand = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);  
        SERVICE_STATUS svcsta = { 0 };  
        if (m_ScHand != NULL){  
            SC_HANDLE hService = OpenService(m_ScHand, m_ServiceName, SERVICE_STOP);  
            if (hService != NULL)
            {  
                if (ControlService(m_CreateService, SERVICE_CONTROL_STOP, &svcsta))  
                {  
                    CloseServiceHandle(m_CreateService);  
                    CloseServiceHandle(m_ScHand);  
                    ::MessageBox(NULL, TEXT(" Stop Service Sucess
    "), TEXT("Sucess"), IDOK);
                    return ;  
                }  
                CloseServiceHandle(m_CreateService);  
                CloseServiceHandle(m_ScHand);  
                ::MessageBox(NULL, TEXT(" Stop Service Fail
    "), TEXT("Error"), IDOK);
                return ;  
            }  
            CloseServiceHandle(m_ScHand);  
            return ;  
        }  
        else 
        {
            ::MessageBox(NULL, TEXT(" Stop Service Fail
    "), TEXT("Fail"), IDOK);
            return ;  
        }
        return;
        

    完整测试代码:

    // InstallDriver.cpp : 定义应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "InstallDriver.h"
    #include "../../publicstruct.h"
    
    SC_HANDLE m_ScHand;
    SC_HANDLE m_CreateService;
    CBinString m_ServiceName;
    CBinString m_EdtPathName;
    
    //安装驱动
    
    
    BOOL InstallDriver(CBinString ServiecName,CBinString ServicePathName)
    {
        
     
        m_EdtPathName = ServicePathName;
        m_ServiceName = ServiecName; 
        m_ScHand = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        if (m_ScHand == NULL)
        {
            //::MessageBox(NULL, TEXT("Open ScManger Fail"), TEXT("Error"), NULL);
            //OutputDebugString(TEXT("打开服务管理器失败"));
            return FALSE;
        }
        m_CreateService = CreateService(
            m_ScHand,
            m_ServiceName.c_str(),
            m_ServiceName.c_str(),
            SC_MANAGER_ALL_ACCESS,
            SERVICE_KERNEL_DRIVER,
            SERVICE_DEMAND_START,
            SERVICE_ERROR_SEVERE,
            m_EdtPathName.c_str(),
            NULL,
            NULL,
            NULL,
            NULL,
            NULL);
        if (m_CreateService == NULL)
        {
            ::CloseServiceHandle(m_CreateService);
           
            //OutputDebugString(TEXT("调用CreateService失败"));
    
            return FALSE;
        }
        ::CloseServiceHandle(m_CreateService);
    
        return TRUE;
    }
    
    
    BOOL StartDriver(CBinString ServiceName)
    {
        // TODO: Add your control notification handler code here
       
        SC_HANDLE m_CreateService = NULL;
        if (m_ScHand == NULL)
        {
            //OutputDebugString(TEXT("启动驱动: SCM为NULL打开失败"));
            return FALSE;
        }
        //open Service
        m_CreateService = OpenService(m_ScHand, m_ServiceName.c_str(), SERVICE_START);
        if (m_CreateService == NULL)
        {
           
            //OutputDebugString(TEXT("启动驱动: OpenService服务失败"));
    
            return FALSE;
    
        }
    
       
        BOOL bRet = StartService(m_CreateService, 0, NULL);
    
        if (bRet == NULL)
        {
            ::CloseServiceHandle(m_CreateService);
           
            //OutputDebugString(TEXT("启动驱动: StartService失败"));
    
            return FALSE;
        }
    
        ::CloseServiceHandle(m_CreateService);
       
       
        return TRUE;
    }
    
    BOOL StopDriver(CBinString ServiceName)
    {
        // TODO: Add your control notification handler code here
      
       
       
     
        SERVICE_STATUS svcsta = { 0 };
        if (m_ScHand != NULL) {
            SC_HANDLE hService = OpenService(m_ScHand, m_ServiceName.c_str(), SERVICE_STOP);
            if (hService != NULL)
            {
                if (ControlService(hService, SERVICE_CONTROL_STOP, &svcsta))
                {
                    CloseServiceHandle(hService);
                   
                    
                    return TRUE;
                }
                CloseServiceHandle(hService);
                return FALSE; 
            }
          
            return FALSE;
        }
        else
        {
           
            return FALSE;
        }
        return FALSE;
    
    
    }
    
    BOOL UninstallDriver(CBinString ServiceName)
    {
        // TODO: Add your control notification handler code here
      
        if (m_ScHand == NULL)
        {
           
            return FALSE;
        }
        //open Service
        m_CreateService = OpenService(m_ScHand, m_ServiceName.c_str(), SERVICE_STOP | DELETE);
        if (m_CreateService == NULL)
        {
          
            return FALSE;
        }
        BOOL bRet = FALSE;
        bRet = DeleteService(m_CreateService);
        if (!bRet)
        {
            ::CloseServiceHandle(m_CreateService);
            ::CloseServiceHandle(m_ScHand);
           
            return FALSE;
        }
    
    
    
        DeleteService(m_CreateService);
        ::CloseServiceHandle(m_CreateService);
        ::CloseServiceHandle(m_ScHand);
        return TRUE;
    
    }
    
    
    void LoadDriver(CBinString ServiceName,CBinString ServicePathName)
    {
        /*
        1.安装
        2.启动
        3.停止
        4.卸载.
        */
        BOOL bRet = FALSE;
        bRet =  InstallDriver(ServiceName, ServicePathName);
        if (!bRet)
        {
           // OutputDebugString(TEXT("安装驱动失败"));
           
        }
        bRet =  StartDriver(ServiceName);
    
        if (!bRet)
        {
            //OutputDebugString(TEXT("启动驱动失败"));
            return;
        }
    
        Sleep(3000);
    
        bRet = StopDriver(ServiceName);
    
        if (!bRet)
        {
            //OutputDebugString(TEXT("停止驱动失败"));
            return;
        }
    
        Sleep(1000);
        bRet = UninstallDriver(ServiceName);
        if (!bRet)
        {
            //OutputDebugString(TEXT("删除驱动失败"));
            return;
        }
    }
    
    int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                         _In_opt_ HINSTANCE hPrevInstance,
                         _In_ LPWSTR    lpCmdLine,
                         _In_ int       nCmdShow)
    {
       
    
        CBinString ServiceName;
        CBinString ServicePathName;
        TCHAR szBuffer[MAX_PATH] = { 0 };
        GetCurrentDirectory(sizeof(TCHAR) * MAX_PATH, szBuffer);
        OutputDebugString(szBuffer);
        ServiceName = TEXT("PassRegister"); //注: 不能有后缀名
    
        ServicePathName = szBuffer;
        ServicePathName += TEXT("\");
        ServicePathName.append(ServiceName);//注意必须是路径加文件名 D;\xx.exe/sys/dll
        ServicePathName.append(TEXT(".sys"));
    
        OutputDebugString(ServicePathName.c_str());
        
       
    
        LoadDriver(ServiceName, ServicePathName);
        return 0;
    }
    测试代码.可拷贝

    完整的工程代码资料下载:

      链接:https://pan.baidu.com/s/1kWoHJZD 密码:osy7

    原创不易,转载请注明出处.

  • 相关阅读:
    浅谈Oracle12c 数据库、用户、CDB与PDB之间的关系
    ECLIPSE快捷键
    Oracle12cWindows安装、介绍及简单使用(图文)
    金士顿DT100 G3 PS2251-07海力士U盘量产修复成功教程
    tomcat绑定域名
    TCP慢启动、拥塞避免、快速重传、快速恢复
    理解HTTP幂等性
    TCP协议缺陷不完全记录
    Nginx模块开发入门
    一步步构建大型网站架构
  • 原文地址:https://www.cnblogs.com/iBinary/p/8280912.html
Copyright © 2011-2022 走看看