我正在编写一个调用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。
任何帮助都会非常有用
最佳答案
KeBugCheck
是内核函数。这意味着您不能从用户模式代码中调用它,就像您要编写的应用程序一样。
也没有为此功能提供用户模式包装器,因为用户模式代码不应降低整个系统的性能。
您必须编写自己的内核模式驱动程序才能执行此操作。要开始使用,请下载Windows Driver Development Kit (DDK)。在那种情况下,不需要整个LoadLibrary
和GetProcAddress
跳舞,因为函数声明位于公共Ntddk.h
头文件中,并且会自动从Ntoskrnl.lib
文件中链接进来。
至于您遇到的问题,LoadLibrary
返回ERROR_MOD_NOT_FOUND
,这是无关的。您所拥有的代码是错误的,从显式强制转换为LPCWSTR
到关闭编译器必须执行的代码非常明显。
您正在编译Unicode应用程序,因此对LoadLibrary
的调用将自动解析为LoadLibraryW
,它接受类型为LPCWSTR
的宽(Unicode)字符串。您试图将其传递给窄字符串文字,这会产生类型不匹配错误。除了插入了强制类型转换外,它有效地告诉编译器关闭,因为您比它更了解。除了你不知道。您应该听编译器的声音。它可以避免许多错误。
解决方法很简单:从代码中删除所有多余的强制类型转换,而改用宽字符串文字。 (但是,GetProcAddress
函数是唯一的:无论您是否要为Unicode编译,它总是需要一个狭窄的字符串。)
HMODULE bcLib = LoadLibrary(L"ntoskrnl.exe");
void* fnc = (void*)GetProcAddress(bcLib, "KeBugCheck");
当然,解决此问题后,您将希望看到我答案的第一部分。
关于c++ - LoadLibrary找不到ntoskrnl,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18042390/