NT驱动加载方式

摘要:

最近在分析一个驱动级别的脱壳器OllyBonE(OllyDbg的一个插件), 遂即对驱动做了简单的了解,驱动程序主要分为两类:一类是不支持即插即用的NT是驱动程序如NTDDK.h;另外一类是支持即插即用的WDM驱动程序,如WDM.h。 由于OllyBonE是一个NT式驱动,所以仅仅熟悉了NT式驱动的相关知识。本文主要对NT式驱动的三类加载方式:工具加载、手动加载、程序加载,并通过具体实验做以介绍。

 

方式一(工具):利用Driver Monitor加载NT式驱动

File->OpenDriver,选择需要加载的驱动.sys文件。

File->Start Driver加载驱动。

成功加载如下图:

 


方式二(手动):与方式一原理一样,都是在注册表中填写相应的字段,

注册表是windows中最重要的文件之一,Windows注册表是帮助Windows控制硬件、软件、用户环境的重要东东,其实如何打开注册表,只需打开“开始菜单”—点“运行”—输入“regedit”,点确定,即可打开,如下图所示.注册表编辑器实际上也可以在系统根目录下找到windows\system中找到。

在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services中添加新项目,这个项目名称为这个驱动名称,例如,HelloDDK.

‚添加一下子键:

ƒ在命令行方式运行netstart驱动名称,例如,net start HelloDDK.这是驱动会被I/O管理器加载,并且调用入口函数DriverEntry。停止驱动的方式很类似,运行netstop HelloDDK。如果不采用命令行的方式,可以在设备管理器中运行或停止,如下图。

 


方式三(代码):Windows服务程序遵循服务控制管理器。基于服务控制管理程序(Service Control Manager, SCM)系统组建完成。在“WINSAC.H”中有定义了SCM组建。

加载和卸载NT驱动分为四个步骤:

为NT驱动创建新的服务。

‚开启此项服务。

ƒ关闭此项服务。

„删除NT驱动所创建的服务。



以下为常用的SCM组建API相关函数(直接从WINSAC.H中拷贝的)

1.打开SCM管理器的函数

WINADVAPI

SC_HANDLE

WINAPI

OpenSCManagerA(

    LPCSTR lpMachineName,   //计算机名称,NULL代表本机

    LPCSTR lpDatabaseName,   //SCM数据库,NULL代表使用缺省数据库

    DWORD  dwDesiredAccess  //使用权限

);

2.关闭服务的句柄

WINADVAPI

BOOL

WINAPI

CloseServiceHandle(

    SC_HANDLE  hSCObject  //关闭SCM管理器的句柄

);

3.创建服务

WINADVAPI

SC_HANDLE

WINAPI

CreateService(

    SC_HANDLE   hSCManager,

    LPCSTR    lpServiceName,

    LPCSTR    lpDisplayName,

    DWORD       dwDesiredAccess,

    DWORD       dwServiceType,

    DWORD       dwStartType,

    DWORD       dwErrorControl,

    LPCSTR    lpBinaryPathName,

    LPCSTR    lpLoadOrderGroup,

    LPDWORD     lpdwTagId,

    LPCSTR    lpDependencies,

    LPCSTR    lpServiceStartName,

    LPCSTR    lpPassword

    );

4.打开服务

WINADVAPI

SC_HANDLE

WINAPI

OpenService(

    SC_HANDLE  hSCManager,

    LPCSTR   lpServiceName,

    DWORD      dwDesiredAccess

);

5.控制服务

WINADVAPI

BOOL

WINAPI

ControlService(

    SC_HANDLE           hService,    //服务器的句柄

    DWORD               dwControl,   //控制码

    LPSERVICE_STATUS    lpServiceStatus  //返回码的状态

);

 

加载NT驱动的流程图:

 

卸载NT驱动流程图:

 

附代码如下:

#include<windows.h>
#include<winuser.h>
#include<stdlib.h>
#include<string.h>
#include<winsvc.h>
#include<iostream>
usingnamespace std;
 
SC_HANDLEhServiceMgr = NULL;
SC_HANDLEhServiceDDK = NULL;
voidBeforeLeave()
{
        if(hServiceMgr)
        {
                 CloseServiceHandle(hServiceMgr);
        }
        if(hServiceDDK)
        {
                 CloseServiceHandle(hServiceDDK);
        }
}
 
boolLoadNTDriver(char * name, char* path)
{
int temp = 0;
//      char * Imagepath = path + "\\"+name;
        char * Imagepath ="D:\\Code\\ollybone.sys";
 
        hServiceMgr = OpenSCManager(    NULL,          // machine (NULL == local)
                                NULL,         // database (NULL == default)
                                                               SC_MANAGER_ALL_ACCESS  // access required
                                                         );
        if(hServiceMgr==NULL)
        {
                 printf("OpenSCManager()Failed %d!\n", GetLastError());
                 temp = 0;
                 BeforeLeave();
 
        }
        else
        {
           printf("OpenSCManager() OK !\n");
        }
    //创建驱动所对应的服务
        hServiceDDK = CreateService(hServiceMgr,          // SCManagerdatabase
                                name,           // name of service
                                name,           // name to display
                                SERVICE_ALL_ACCESS,    // desired access
                               SERVICE_KERNEL_DRIVER, // service type
                               SERVICE_DEMAND_START,  // starttype
                               SERVICE_ERROR_NORMAL,  // errorcontrol type
                                Imagepath,            // service's binary
                                NULL,                  // no load ordering group
                                NULL,                  // no tag identifier
                                NULL,                  // no dependencies
                                NULL,                  // LocalSystem account
                                NULL                   // no password
                                );
        DWORD dwRtn;
        if(hServiceDDK==NULL)
        {
                 dwRtn = GetLastError();
           if(dwRtn!= ERROR_IO_PENDING && dwRtn!=ERROR_SERVICE_EXISTS)
                 {
        printf("CreateService()Failed %d!\n", dwRtn);
            temp = 0;
            BeforeLeave();
                 }
                 else
                 {
         printf( "CreateService() Failedis ERROR_IO_PENDING
orERROR_SERVICE_EXISTS! \n");
                 }
        hServiceDDK =  OpenService( hServiceMgr, name,SERVICE_ALL_ACCESS );
                 if(hServiceDDK==NULL)
                 {
             dwRtn = GetLastError();
                printf("OpenService() Failed %d!\n", dwRtn);
            temp = 0;
            BeforeLeave();
                 }
                 else
                 {
             printf("OpenService() OK!\n");
                 }
        }
        else
        {
           printf("CreateService() OK !\n");
        }
        temp =StartService(hServiceDDK,NULL,NULL);
        if(!temp)
        {
        DWORD dwRtn =  GetLastError();
                 if( dwRtn != ERROR_IO_PENDING
&&  dwRtn != ERROR_SERVICE_ALREADY_RUNNING )
                 {
            printf("startService() Failed%d!\n", dwRtn);
            temp = 0;
            BeforeLeave();
                 }
                 else
                 {
                         if(dwRtn== ERROR_IO_PENDING)
                         {
            printf("startService() FailedERROR_IO_PENDING\n");
            temp = 0;
            BeforeLeave();
                         }
                         else
                         {
            printf("startService() FailedERROR_SERVICE_ALREADY_RUNNING\n");
            temp = 1;
            BeforeLeave();
                         }
                 }
        }
        temp = 1;
        BeforeLeave();
    return temp;
}
 
boolUnloadNTDriver(char *name)
{
    int temp = 0;
        SERVICE_STATUS SvrSta;
        hServiceMgr = OpenSCManager(    NULL,            // machine (NULL == local)
                                NULL,            // database (NULL == default)
                                                           SC_MANAGER_ALL_ACCESS //access required
                                                         );
        if(hServiceMgr==NULL)
        {
                 printf("OpenSCManager()Failed %d!\n", GetLastError());
                 temp = 0;
                 BeforeLeave();
        }
        else
        {
           printf("OpenSCManager() OK !\n");
        }
     hServiceDDK = OpenService( hServiceMgr, name, SERVICE_ALL_ACCESS );
                 if(hServiceDDK==NULL)
                 {
               printf("OpenService() Failed %d!\n", GetLastError());
            temp = 0;
            BeforeLeave();
                 }
                 else
                 {
             printf("OpenService() OK!\n");
                 }
                 if( !ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrSta ))
                 {
           printf("ControlService() Failed%d!\n", GetLastError());
                 }
                 else
                 {
             printf("ControlService() OK!\n");
                 }
                 if(!DeleteService(hServiceDDK))
                 {
           printf("DeleteService() Failed%d!\n", GetLastError());
                 }
                 else
                 {
            printf("DeleteService() OK!\n");
                 }
        temp = 1;
        BeforeLeave();
    return temp;
}
 
void main()
{
        char * name = "ollybone.sys";
    char * path = "D:\\Code";
        int temp = LoadNTDriver(name, path);
        if(temp == 0)
        {
                 printf("LoadNTDrivererror\n");
        //      cout<<"LoadNTDrivererror\n";
        }
        Sleep(500);
        UnloadNTDriver(name);
        if(temp == 0)
        {
                 printf("UnloadNTDrivererror\n");
        //      cout<<"UnloadNTDrivererror!\n";
        }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值