【问题标题】:C++ Win32 API Load a driver to the kernel spaceC++ Win32 API 将驱动程序加载到内核空间
【发布时间】:2015-09-06 13:43:10
【问题描述】:

是否有用于在内核空间中加载和执行内核模式程序的 Win32/native API 函数? (.sys, .exe)

【问题讨论】:

  • 您可以使用 CreateService() 加载和启动设备驱动程序,服务类型为 SERVICE_KERNEL_DRIVER,启动类型为 SERVICE_DEMAND_START。

标签: c++ windows kernel


【解决方案1】:

首先,您使用OpenSCManager() 获得服务管理器的句柄。

然后您使用 SERVICE_KERNEL_DRIVER 和 SERVICE_DEMAND_START 调用 CreateService(),这将加载驱动程序。

这是一个很好的例子,它通过错误检查为您完成所有工作:

BOOL LoadNTDriver(WCHAR* lpszDriverName, WCHAR* lpszDriverPath)
{
    WCHAR szDriverImagePath[256];

    GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);
    BOOL bRet = FALSE;

    SC_HANDLE hServiceMgr = NULL;
    SC_HANDLE hServiceDDK = NULL;

    hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

    if (hServiceMgr == NULL)
    {

        printf("OpenSCManager() Faild %d ! \n", GetLastError());
        bRet = FALSE;
        goto BeforeExit;
    }
    else
    {
        printf("OpenSCManager() ok ! \n");
    }

    hServiceDDK = CreateService(hServiceMgr,
        lpszDriverName, 
        lpszDriverName,
        SERVICE_ALL_ACCESS,
        SERVICE_KERNEL_DRIVER,
        SERVICE_DEMAND_START,
        SERVICE_ERROR_IGNORE,
        szDriverImagePath,
        NULL,
        NULL,
        NULL,
        NULL,
        NULL);

    DWORD dwRtn;

    if (hServiceDDK == NULL)
    {
        dwRtn = GetLastError();
        if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS)
        {
            printf("CrateService() Faild %d ! \n", dwRtn);
            bRet = FALSE;
            goto BeforeExit;
        }
        else
        {
            printf("CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n");
        }

        hServiceDDK = OpenService(hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS);
        if (hServiceDDK == NULL)
        {
            dwRtn = GetLastError();
            printf("OpenService() Faild %d ! \n", dwRtn);
            bRet = FALSE;
            goto BeforeExit;
        }
        else
        {
            printf("OpenService() ok ! \n");
        }
    }
    else
    {
        printf("CrateService() ok ! \n");
    }

    bRet = StartService(hServiceDDK, NULL, NULL);
    if (!bRet)
    {
        DWORD dwRtn = GetLastError();
        if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING)
        {
            printf("StartService() Faild %d ! \n", dwRtn);
            bRet = FALSE;
            goto BeforeExit;
        }
        else
        {
            if (dwRtn == ERROR_IO_PENDING)
            {
                printf("StartService() Faild ERROR_IO_PENDING ! \n");
                bRet = FALSE;
                goto BeforeExit;
            }
            else
            {
                printf("StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n");
                bRet = TRUE;
                goto BeforeExit;
            }
        }
    }
    bRet = TRUE;

BeforeExit:
    if (hServiceDDK)
    {
        CloseServiceHandle(hServiceDDK);
    }
    if (hServiceMgr)
    {
        CloseServiceHandle(hServiceMgr);
    }
    return bRet;
}

来源:https://github.com/roycncn/PUBG-wall-hacking-user-mode/blob/master/MapESP/LoadDriver.hpp

【讨论】:

    【解决方案2】:

    据我所知,没有。你不能那样做(这将是一个相当大的安全问题)。您必须正确注册驱动程序并让 Windows 加载它。

    后者可以使用DIFxAPI 来完成,你应该在 MSDN 上阅读它,因为它太复杂了,无法在这里简单地回答。

    您应该寻找的核心函数是DriverPackageInstall

    【讨论】:

    • 我发现了这个:codeproject.com/Articles/31905/…
    • 您可以使用 CreateService() API,比设备管理 API 简单得多。没有安全问题;当然,您需要管理员权限,并且驱动程序签名要求(如果启用)仍然适用,就像您以通常的方式安装普通驱动程序一样。
    猜你喜欢
    • 2014-04-28
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    相关资源
    最近更新 更多