LoadLibrary找不到ntoskrnl

noo*_*ker 0 c++ windows winapi loadlibrary visual-c++

我正在写一个小应用程序调用KeBugCheck并崩溃系统但LoadLibrary无法找到ntoskrnl.exe(我在调用GetLastError时得到126作为返回值)

这是我的代码:

void* fnc;
HMODULE bcLib;
bcLib = LoadLibrary((LPCWSTR)"ntoskrnl.exe");
fnc = (void*) GetProcAddress(bcLib, (LPCSTR)"KeBugCheck");
int(*KeBugCheck)(ULONG);
KeBugCheck = (int(*)(ULONG))fnc;
KeBugCheck(0x000000E2);
Run Code Online (Sandbox Code Playgroud)

此外,在调试窗口中,我看到此错误:

app.exe中0x00000000处的第一次机会异常:0xC0000005:访问冲突执行位置0x00000000.

任何帮助都会非常受欢迎

Cod*_*ray 8

KeBugCheck是一个核函数.这意味着您无法从用户模式代码中调用它,就像您尝试编写的应用程序一样.

此功能也没有提供用户模式包装器,因为用户模式代码不应该能够关闭整个系统.

您必须编写自己的内核模式驱动程序才能执行此操作.要开始使用,请下载Windows驱动程序开发工具包(DDK).在这种情况下,不需要整个LoadLibraryGetProcAddress舞蹈,因为函数声明在公共Ntddk.h标题中,并将自动从Ntoskrnl.lib文件链接.


至于你在这里遇到的问题,LoadLibrary回归ERROR_MOD_NOT_FOUND,这是无关的.您拥有的代码是错误的,从显式转换LPCWSTR到您必须执行以便关闭编译器是非常明显的.

您正在编译Unicode应用程序,因此调用将LoadLibrary自动解析为LoadLibraryW,它接受带有该类型的宽(Unicode)字符串LPCWSTR.您试图传递一个狭窄的字符串文字,这会产生类型不匹配错误.除了你已经插入了演员表,这有效地告诉编译器闭嘴,因为你知道比它更好.除非你不这样做.你应该听编译器; 它可以为您节省大量的错误.

修复很简单:从代码中删除所有多余的强制转换,然后使用字符串文字.(GetProcAddress但是,该函数是唯一的:它总是需要一个窄字符串,无论您是否正在编译Unicode.)

HMODULE bcLib = LoadLibrary(L"ntoskrnl.exe");
void* fnc = (void*)GetProcAddress(bcLib, "KeBugCheck");
Run Code Online (Sandbox Code Playgroud)

当然,一旦解决了这个问题,你就会想看到我答案的第一部分.