如何将外部内核代码集成到基于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)¶meters; 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
相关产品推荐
相关产品推荐

