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
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.
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.
Related
I am thoroughly stumped on this one, can you please help.
I am trying to call the sqrt from a function with a Dll. When doing so I get the following error,
First-chance exception at 0x000082bc in DllTest.exe: 0xC0000005: Access violation.
The exception happens when the sqrt is called.
The code in my Dll is (contained in the header)
/////////////////////////////////////////////////////////////
#include <math.h>
//////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport) float MyFunction (void)
{
float f(10.0f);
float r(sqrt(f));
return r;
}
///////////////////////////////////////////////////////////
Which is run from a command line application. (Contained in the cpp file)
#include "stdafx.h"
///////////////////////////////////////////////////////
typedef float (*MyDllFn)(void);
//////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE module = LoadLibraryEx(_T("MyDll.dll"),
NULL,
DONT_RESOLVE_DLL_REFERENCES);
MyDllFn pMyDllFunction ((MyDllFn) GetProcAddress(module, "MyFunction"));
float sqrt10 = pMyDllFunction();
return 0;
}
I have tried moving the sqrt into the cpp file which made no difference. I am really not sure why this could be happening so any help is greatly appreciated.
You are not performing any error checking at all.
Quite possibly LoadLibraryEx fails and returns NULL. Then GetProcAddress fails and returns NULL. You then try to call a function at address NULL. Or perhaps LoadLibraryEx succeeds, but the call to GetProcAddress fails because you got the function name wrong. The function name looks right, but there is always the possibility of name mangling or decoration. Granted the way you have exported it means neither of those should happen. So I rather suspect that module is NULL.
The use of DONT_RESOLVE_DLL_REFERENCES puzzles me. I cannot imagine why you included that. The documentation says:
If this value is used, and the executable module is a DLL, the system
does not call DllMain for process and thread initialization and
termination. Also, the system does not load additional executable
modules that are referenced by the specified module.
Note Do not use this value; it is provided only for backward compatibility. If you are planning to access only data or resources in
the DLL, use LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE or
LOAD_LIBRARY_AS_IMAGE_RESOURCE or both. Otherwise, load the library as
a DLL or executable module using the LoadLibrary function.
That is as clear as can be. Do not use this value. In fact, you should just call LoadLibrary. You do not need the added functionality that LoadLibraryEx offers.
The fact that the error is raised in the DllTest.exe module indicates that you never make it into the DLL. And so I'm reasonably confident that one of my hypotheses above is accurate.
Add some error checking. The documentation for the functions that you call tell you how to do that. Specifically you will need to check the return values of the functions that you call. For both of these functions a return value of NULL indicates failure. And, for both of these functions, when they fail you can obtain an error code by calling GetLastError. But not all Win32 functions work that way so always read the documentation carefully and always check for errors.
You want code that looks like this:
HMODULE module = LoadLibrary(L"MyDll.dll");
if (module == NULL)
return GetLastError(); // or do some real error handling
MyDllFn pMyDllFunction = (MyDllFn)GetProcAddress(module, "MyFunction");
if (pMyDllFunction == NULL)
return GetLastError(); // or do some real error handling
float sqrt10 = pMyDllFunction();
I have a DLL given named Lib.ddl. In the dll i have a function named add that takes an integer as a parameter.
Using the windows API and by using the following class.
class WindoswAPI
{
public:
WindowsAPI();//constructor
//helper functions
~WindowsAPI();
private:
}
How do I load this library in the constructor of the class. Extract the function via helper functions, and unload the function in the destructor?
I have looked on the internet for solutions and help but i cant find any.
You should first look at LoadLibraryEx() in order to load the dll in your process, then you can use GetProcAddress() to obtain a pointer to a function by name. Note the HMODULE parameter requested from the second function is returned by the first. You have to carefully know the function signature to invoke it without causing GPFs, so don't be surprised if you have to do some debug before having it working.
First easy thing to check anyway are the return values of both functions: the first one should return something different from zero ( it actually returns the virtual address where the dll is loaded ), if it returns NULL, use GetLastError to have some hints.
The same for GetProcAddress, if it return zero something didn't work, and usually is the incorrect spelling of the function name. As I said before having back an address from GetProcAddress does not guarantee you have finished: you must know perfectly how to call the function. If you need help in discovering which name are exposed from the dll, you will find useful DUMPBIN.EXE, you should have it already available from the Visual Studio Tools command prompt.
When your code finish with the dll, you can try to unload it by using FreeLibrary().
Look at POCO C++ Libraries, it contains very nice crossplatfrom DLL-Loader to avoid hand-written workarounds and boilerplate.
I have a dll (C code) that is built using VS2010 and defines a set of functions. I also have an exe (C++ code), built using VS2010 that dynamically loads the dll and calls the functions. The first couple of function calls work fine then about 20% of the time a call to a third function causes an access violation at address zero. The other 80% of the time the call is fine. It's always the same function call that is causing the issue.
typedef void (__cdecl *mtSim_ResetODScan)(void);
mtSim_ResetODScan mpSim_ResetODScan;
if ((mpSim_ResetODScan = (mtSim_ResetODScan)GetProcAddress(mhSimDLL,
"_Sim_ResetODScan")) == NULL) return 0;
At this point mpSim_ResetODScan = 0x5E9741D0. Later on the function is called and when I debug the executable it breaks execution at the function call:
mpSim_ResetODScan();
Attempting to step into the function regenerates the access violation. The VS debugger reports that mpSim_ResetODScan still has the value 0x5E9741D0.
Commenting out all code inside the function in the dll makes no difference.
In the DLL:
extern "C" __declspec(dllexport) void __cdecl _Sim_ResetODScan(void);
Dependency Walker shows that the dll and exe are using MSVCR100.DLL version 10.0.30319.460.
Any suggestions on how I can debug this further or any hints on things I might have missed?
Try running the program normally under debugger itself, and put a data breakpoint around variable mpSim_ResetODScan - to see when it is possibly changing. Seems to be problem of buffer overrun.
I'm programing on C++, I'm using Visual Studio 2008, Windows XP, and I have the following problem:
My application, that is a DLL that can be used from Python, loads an external dll, uses the required methods, and then unloads this external Dll.
It's working properly, but after more than 1000 cycles the method "LoadLibraryA" returns a NULL reference.
The main steps are:
HINSTANCE h = NULL;
h = LoadLibraryA(dllfile.c_str());
DWORD dw = GetLastError();
The error got is:
ERROR_DLL_INIT_FAILED
1114 (0x45A) A dynamic link library (DLL) initialization routine failed.
The Dll is unloaded by using the following:
FreeLibrary(mDLL);
mDLL = NULL;
Where mDLL is defined like this:
HINSTANCE mDLL;
First alternative tried:
Just load the Dll only once, and unloaded it when the application ends. This fix the problem but introduces a new one.
When the application ends, instead of first executing the DllMain method of my applicaion, wich unloads the external DLL, is executing first the DllMain method of the other Dll. This cause the following error because my application is trying to unload a Dll that was unload by itself previously.
"Unhandled exception at 0x04a00d07 (DllName.DLL) in Python.exe: 0xC0000005: Access violation reading location 0x0000006b".
Any suggestion will be welcomed.
Thanks in advance.
Regards.
Make sure that initialization code of the loaded/unloaded library doesn't leak memory. Many libraries expect to be loaded only once and not always clean up their resources properly.
E.g. in C++ file at the top level one can declare and initialize a variable like this:
AClass *a = new AClass(1,2,3);
The code would be executed when library is loaded automatically. Yet, now, it is impossible to free the hanging instance as library doesn't know precisely when/how it is going to be unloaded. In the case one can either replace "AClass *a" with "AClass a" or write your own DllMain for the library and free resources on DLL_PROCESS_DETACH.
If you have no control over the library's code, then it might make sense to create a cache of loaded libraries and simply never unload them. It is very hard to imagine that there would be unlimited number of libraries to overload such cache.
I have a native DLL that is a plug-in to a different application (one that I have essentially zero control of). Everything works just great until I link with an additional .lib file (links my DLL to another DLL named ABQSMABasCoreUtils.dll). This file contains some additional API from the parent application that I would like to utilize. I haven't even written any code to use any of the functions exported but just linking in this new DLL is causing problems. Specifically, I get the following error when I attempt to run the program:
The application failed to initialize properly (0xc0000025). Click on OK to terminate the application.
I believe I have read somewhere that this is typically due to a DllMain function returning FALSE. Also, the following message is written to the standard output:
ERROR: Memory allocation attempted before component initialization
I am almost 100% sure this error message is coming from the application and is not some type of Windows error.
Looking into this a little more (aka flailing around and flipping every switch I know of) I linked with /MAP turned on and found this in the resulting .map file:
0001:000af220 ??3#YAXPEAX#Z 00000001800b0220 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
0001:000af226 ??2#YAPEAX_K#Z 00000001800b0226 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
0001:000af22c ??_U#YAPEAX_K#Z 00000001800b022c f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
0001:000af232 ??_V#YAXPEAX#Z 00000001800b0232 f ABQSMABasCoreUtils_import:ABQSMABasCoreUtils.dll
If I undecorate those names using "undname" they give the following (same order):
void __cdecl operator delete(void * __ptr64)
void * __ptr64 __cdecl operator new(unsigned __int64)
void * __ptr64 __cdecl operator new[](unsigned __int64)
void __cdecl operator delete[](void * __ptr64)
I am not sure I understand how anything from ABQSMABasCoreUtils.dll can exist within this .map file or why my DLL is even attempting to load ABQSMABasCoreUtils.dll if I don't have any code that references this DLL. Can anyone help me put this information together and find out why this isn't working? For what it's worth I have confirmed via "dumpbin" that the parent application imports ABQSMABasCoreUtils.dll, so it is being loaded no matter what. I have also tried delay loading this DLL in my DLL but that did not change the results.
EDIT
I have double checked and all files involved are 64 bit.
I just had exactly the same problem. This is an issue with the Abaqus API rather than with the loading of DLLS.
I think it is because the Abaqus API overrides the new and delete functions (as you seem to have noticed). If you call new or delete in your program before initializing the Abaqus API, such as by calling odb_initializeAPI(); then you get the
ERROR: Memory allocation attempted before component initialization
error message and the program crashes.
In my program, calling odb_initializeAPI(); before the first new resolved the problem.
Well, sure you'll reference the imports of that library. Hard to write a C++ program without using the new or delete operator. Dealing with 3rd party software that thinks it needs to override the CRT version of those operators is hard enough, impossible when it won't allow you to call them until it thinks the time is right. Abandon all hope or seek help from the vendor.
One of the possible reason of an error during loading of ABQSMABasCoreUtils.dll is that some dependency module (inclusive delayed load DLLs) could not be found. Use Dependency Walker (see http://www.dependencywalker.com/) to examine all dependencies of ABQSMABasCoreUtils.dll.
I have two suggestions:
Verify that you can load ABQSMABasCoreUtils.dll with respect of LoadLibrary. You don't need call any function from ABQSMABasCoreUtils.dll. Usage of LoadLibrary I don't see as the end solution. It' s only a diagnostic test. With the test you can verify either you have some general problem of loading ABQSMABasCoreUtils.dll in your program or you have some kind of process initialization problem.
If loading of ABQSMABasCoreUtils.dll with respect of LoadLibrary will failed, then use profiling feature of Dependency Walker to protocol of all calls done during loading of ABQSMABasCoreUtils.dll. One other way would be usage of Process Monitor (see http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) to trace what file and registry operations will be done during loading of ABQSMABasCoreUtils.dll.
If LoadLibrary is not failed, then you have really an initialization problem of DLLs. Typically the problem exist if a DLL inside of DllMain try use a function from another DLL which is not yet initialized (not yet returns from DllMain). Before one start diagnostic of this problem, we should try to exclude a more simple problems with LoadLibrary.
The ABQSMABasCoreUtils.dll looks like it's importing 64-bit functions. Is your dll also 64-bit? If not, then that's the problem - you cannot mix DLLs compiled for different architectures in the same process.