You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将外部内核代码集成到基于EFI的用户态应用并编译

项目核心与集成需求

项目核心

我需要实现将内核API/代码添加到用户态应用中,且我的应用具备执行权限。

EFI环境准备说明

要让该应用能执行内核代码,需制作一个U盘,在其中创建EFI文件夹,再在EFI下创建boot文件夹并放入bootx64.efi文件;该文件可通过编译指定GitHub项目获得。注意:未在Intel处理器上测试,仅支持关闭SECURE BOOT的Windows 22H2系统,不建议运行此EFI文件,仅需确保用户态应用可编译启动即可。

现有用户态应用代码示例

main.cpp(用户态应用核心代码)

#include "km.h"

//
// hello world
//

std::vector<QWORD> km::global_export_list;
NTOSKRNL_EXPORT(PsGetCurrentProcess);
NTOSKRNL_EXPORT(PsGetCurrentProcessId);

int main(void)
{
    if (!km::initialize())
    {
        return 0;
    }

    LOG("current process: %llx\n", km::call(PsGetCurrentProcess));
    LOG("current process id: %lld\n", km::call(PsGetCurrentProcessId));
}

km.h(负责EFI与用户态应用间的通信,实现内核代码执行)

extern "C" NTSTATUS NTAPI RtlAdjustPrivilege(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN);
extern "C" NTSTATUS NTAPI NtQuerySystemEnvironmentValueEx(PUNICODE_STRING, LPGUID, PVOID, PULONG, PULONG);

namespace km
{
    extern std::vector<QWORD> global_export_list;

    class DLL_EXPORT
    {
        QWORD address;
    public:
        DLL_EXPORT(QWORD address) : address(address)
        {
            global_export_list.push_back((QWORD)&this->address);
        }
        operator QWORD () const { return address; }
    };

    QWORD call(QWORD kernel_address, QWORD r1 = 0, QWORD r2 = 0, QWORD r3 = 0, QWORD r4 = 0, QWORD r5 = 0, QWORD r6 = 0, QWORD r7 = 0)
    {
        #pragma pack(push,1)
        typedef struct {
            QWORD param_1;
            QWORD param_2;
            QWORD param_3;
            QWORD param_4;
            QWORD param_5;
            QWORD param_6;
            QWORD param_7;
        } PAYLOAD ;
        #pragma pack(pop)

        PAYLOAD parameters;
        parameters.param_1 = r1;
        parameters.param_2 = r2;
        parameters.param_3 = r3;
        parameters.param_4 = r4;
        parameters.param_5 = r5;
        parameters.param_6 = r6;
        parameters.param_7 = r7;

        QWORD peb = __readgsqword(0x60);
        peb = *(QWORD*)(peb + 0x18);
        peb = *(QWORD*)(peb + 0x20);

        *(QWORD*)(peb + 0x18) = kernel_address;
        *(QWORD*)(peb + 0x10) = (QWORD)&parameters;

        UNICODE_STRING string;
        RtlInitUnicodeString(&string, L"SecureBoot");

        ULONG ret = 0;
        ULONG ret_len = 1;
        ULONG attributes = 0;

        GUID gEfiGlobalVariableGuid         = { 0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }};
        NTSTATUS status = NtQuerySystemEnvironmentValueEx(&string,
                            &gEfiGlobalVariableGuid,
                            &ret,
                            &ret_len,
                            &attributes);

        QWORD rax = *(QWORD*)(peb + 0x18);
        *(QWORD*)(peb + 0x18) = 0;
        *(QWORD*)(peb + 0x10) = 0;

        if (NT_SUCCESS(status))
            return 0;

        return rax;
    }

    template <typename T>
    T call(QWORD kernel_address, QWORD r1 = 0, QWORD r2 = 0, QWORD r3 = 0, QWORD r4 = 0, QWORD r5 = 0, QWORD r6 = 0, QWORD r7 = 0)
    {
        QWORD ret = call(kernel_address, r1, r2, r3, r4, r5, r6, r7);
        return *(T*)&ret;
    }

    BOOL initialize(void)
    {
        QWORD ntoskrnl_base = 0;

        for (auto &drv : get_kernel_modules())
        {
            if (!_strcmpi(drv.name.c_str(), "ntoskrnl.exe"))
            {
                ntoskrnl_base = drv.base;
                break;
            }
        }

        if (ntoskrnl_base == 0)
        {
            LOG("ntoskrnl.exe base address not found\n");
            return 0;
        }

        for (auto &i : global_export_list)
        {
            QWORD temp = *(QWORD*)i;

            *(QWORD*)i = get_kernel_export(ntoskrnl_base, "ntoskrnl.exe", (PCSTR)temp);
            if (*(QWORD*)i == 0)
            {
                LOG("export %s not found\n", (PCSTR)temp);
                return 0;
            }
        }

        BOOLEAN privs=1;
        if (RtlAdjustPrivilege(22, 1, 0, &privs) != 0l)
        {
            LOG("run as admin\n");
            return 0;
        }
        return 1;
    }
}

集成需求

我还有另一应用的内核代码(C++编写),希望将其功能集成到我的现有用户态应用中。请问如何编译集成了该内核代码功能的用户态应用?


内容的提问来源于stack exchange,提问作者saw3l1y

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 09:05:59