0

I am writing a small app which calls KeBugCheck and crashes the system but LoadLibrary is unable to find ntoskrnl.exe (I get 126 as return value when calling GetLastError)

Here is my code:

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

Also, in the debug window, I see this error:

First-chance exception at 0x00000000 in app.exe: 0xC0000005: Access violation executing location 0x00000000.

Any help will be very much appriciated

noobprohacker
  • 125
  • 3
  • 15

2 Answers2

8

KeBugCheck is a kernel function. That means you can't call it from user-mode code, like the application you're trying to write.

There is also no user-mode wrapper provided for this function because user-mode code is not supposed to be able to bring down the entire system.

You will have to write your own kernel-mode driver to do this. To get started, download the Windows Driver Development Kit (DDK). And in that case, there will be no need for the whole LoadLibrary and GetProcAddress dance, since the function declaration is in the public Ntddk.h header and will be linked in automatically from the Ntoskrnl.lib file.


As for the problem you're having here, with LoadLibrary returning ERROR_MOD_NOT_FOUND, that is unrelated. The code you have is wrong, quite obvious from the explicit cast to LPCWSTR that you're having to perform in order to shut the compiler up.

You're compiling a Unicode application, so the call to LoadLibrary is automatically resolved to LoadLibraryW, which accepts a wide (Unicode) string with the type LPCWSTR. You're trying to pass it a narrow string literal, which generates a type mismatch error. Except that you've inserted the cast, which effectively tells the compiler to shut up because you know better than it. Except that you don't. You should listen to the compiler; it can save you from a lot of bugs.

The fix is simple: remove all the superfluous casts from your code and use a wide string literal instead. (The GetProcAddress function, however, is unique: it always requires a narrow string, regardless of whether or not you're compiling for Unicode.)

HMODULE bcLib = LoadLibrary(L"ntoskrnl.exe");
void* fnc = (void*)GetProcAddress(bcLib, "KeBugCheck");

Of course, once you fix this, you'll want to see the first part of my answer.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • Hmm, but why is the program returning 126 as return code (ERROR_MOD_NOT_FOUND: The specified module could not be found) ? – noobprohacker Aug 04 '13 at 11:40
  • I did that, but I still get the same error (126): `HMODULE bcLib = LoadLibrary(L"ntoskrnl.exe"); void* fnc = (void*) GetProcAddress(bcLib, "KeBugCheck"); int(*KeBugCheck)(ULONG); KeBugCheck = (int(*)(ULONG))fnc; KeBugCheck(0x000000E2);` – noobprohacker Aug 04 '13 at 12:31
  • Something is not getting through here... I'm not sure how I can make it much more clear. The code is not going to work. You cannot call kernel-mode functions from user-mode code. I have no idea exactly what error message you're going to get. There may not be an ERROR_CANT_CALL_KERNEL_FUNCTIONS_FROM_USER_CODE error. What were you hoping to see? – Cody Gray - on strike Aug 04 '13 at 12:33
  • I know its not going to or may not work, but why is it returning ERROR_MOD_NOT_FOUND? Ntoskrnl.exe exists in system32 – noobprohacker Aug 04 '13 at 13:40
  • I'm very late, but NtRaiseHardError CAN be called from user-mode and can BSOD the system. – man Sep 26 '17 at 20:40
  • I wasn't really considering undocumented functions, @Kappa... But I guess that's a fair point. – Cody Gray - on strike Sep 27 '17 at 05:51
0

Try using the ntdll.dll NtRaiseHardError function. ntdll functions are the closest that you can get in user-mode to kernel-mode functions and NtRaiseHardError eventually calls KeBugCheck in the kernel.