我正在编写一个调用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);
另外,在调试窗口中,我看到了这个错误:
app.exe中0x00000000处的第一次机会异常:0xC0000005: 访问冲突执行位置0x00000000。
任何帮助都会非常适合
答案 0 :(得分:8)
KeBugCheck
是一个内核函数。这意味着您无法从用户模式代码中调用它,例如您尝试编写的应用程序。
此功能也没有提供用户模式包装器,因为用户模式代码不应该能够关闭整个系统。
您必须编写自己的内核模式驱动程序才能执行此操作。要开始使用,请下载Windows Driver Development Kit (DDK)。在这种情况下,不需要整个LoadLibrary
和GetProcAddress
舞蹈,因为函数声明位于公共Ntddk.h
标题中,并且将自动链接到Ntoskrnl.lib
1}}文件。
至于你在这里遇到的问题,LoadLibrary
返回ERROR_MOD_NOT_FOUND
,这是无关的。您拥有的代码是错误的,从显式转换为LPCWSTR
非常明显,您必须执行此操作才能关闭编译器。
您正在编译Unicode应用程序,因此对LoadLibrary
的调用会自动解析为LoadLibraryW
,它接受类型为LPCWSTR
的宽(Unicode)字符串。您试图将 narrow 字符串文字传递给它,这会产生类型不匹配错误。除了你已经插入了演员表,这有效地告诉编译器闭嘴,因为你知道比它更好。除非你不这样做。你应该听编译器;它可以帮助你避免许多错误。
修复很简单:从代码中删除所有多余的强制转换,然后使用 wide 字符串文字。 (但GetProcAddress
函数是唯一的:它总是需要一个窄字符串,无论您是否正在编译Unicode。)
HMODULE bcLib = LoadLibrary(L"ntoskrnl.exe");
void* fnc = (void*)GetProcAddress(bcLib, "KeBugCheck");
当然,一旦解决了这个问题,你就会想看到我答案的第一部分。
答案 1 :(得分:0)
尝试使用ntdll.dll NtRaiseHardError函数。 ntdll函数是您在用户模式下与内核模式函数最接近的函数,NtRaiseHardError最终在内核中调用KeBugCheck。