Calling sqrt from dll in C++. Access violation - c++

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();

Related

TypeDef with Function Pointer: Function does not Exist

The problem is running code on an older machine where a requested function does not exist. To check for it one uses LoadLibrary and GetProcAddress as demonstrated here, but GetProcAddress requires the address of the functions in a TypeDef prior to its use.
For example, take these two on e.g, XP SP2 32 bit:
typedef BOOL (__stdcall *LPFN_Wow64RevertWow64FsRedirection) (PVOID OldValue);
typedef BOOL (__stdcall *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
...
...
LPFN_Wow64RevertWow64FsRedirection wowRevert = NULL;
LPFN_Wow64DisableWow64FsRedirection wowDisable = NULL;
HINSTANCE hLib;
if(GetProcAddresses( &hLib, "kernel32.dll", 2, &wowRevert,_
"Wow64RevertWow64FsRedirection", &wowDisable, Wow64DisableWow64FsRedirection" ))
{...
Code crashes here with:
The procedure entry point Wow64RevertWow64FsRedirection could not be located in the dynamic link library Kernel32.dll
It's easy enough to implement our own custom Wow64RevertWow64FsRedirection with non-WINAPI typedefs, but how can they be replaced with the base type when the function exists in kernel32.dll?
I'm having a bit of trouble understanding your question. The Wow64RevertWow64FsRedirection function is obviously not going to exist on a 32-bit operating system, so it won't exist on 32-bit Windows XP. Therefore, attempting to retrieve a pointer to this function with GetProcAddress will fail. You get the sensible error that this entry point could not be found. If the entry point cannot be found, the function does not exist and you should not attempt to call it.
You claim that you can implement your own custom Wow64RevertWow64FsRedirection function, but I haven't the foggiest idea why you would want to do this. If the operating system supports WOW64 file-system redirection, then it will provide the Wow64RevertWow64FsRedirection function. If it does not, then it does not provide the function, but you do not need such a function, because there is no such thing as WOW64 file-system redirection. You don't need to enable, disable, or revert it.
It seems that you are making this far more complicated than it needs to be. You don't even need to first verify that the process is a 64-bit process. You can just attempt to locate the entry point to Wow64RevertWow64FsRedirection (or Wow64DisableWow64FsRedirection, as needed), call it if it exists, or ignore the failure if it does not exist.
It is as simple as:
BOOL RevertWOW64RedirectionIfNecessary(PVOID pOldValue)
{
typedef BOOL (WINAPI * fnWow64RevertWow64FsRedirection)(PVOID);
fnWow64RevertWow64FsRedirection pfn =
reinterpret_cast<fnWow64RevertWow64FsRedirection>(
reinterpret_cast<void*>(
GetProcAddress(GetModuleHandle(L"kernel32"),
"Wow64RevertWow64FsRedirection")));
if (pfn)
{
// The function exists, so call it through the pointer we obtained.
return pfn(pOldValue);
}
else
{
// The function does not exist, so we can't call it.
// But we don't ever need to call it in such cases,
// so do nothing and feign success.
return TRUE;
}
}
Note that I am calling the GetModuleHandle function to retrieve a handle to the module kernel32.dll (the .dll extension is implied). I can use GetModuleHandle here instead of LoadModule because I know that kernel32.dll is guaranteed to always be loaded in any application's process. And since I've used GetModuleHandle, I don't need to free the module handle, either.
I pass the resulting handle to the GetProcAddress function, along with a string that contains the name of the function/procedure whose address is to be retrieved. This function attempts to retrieve the address of that function, and returns it if it exists; otherwise, it fails and returns NULL.
I check to see if it returned a valid pointer, and if so, I call the function dynamically through that pointer. Otherwise, it returned NULL, meaning that the function is not available, but in that case, we don't even need to worry about it, so the code just becomes a no-op.
As for the funny casting, see my answer here, which explains this trick.

C++ Access Violation while calling dll function

I am actually using an unmanaged C++ DLL, and I don't have access to the .h, .cpp or .lib, but only to the .DLL.
After using PE Explorer and finding the function I wanted to use, here is what I get :
#Tdtm_Dossier#Logon$qv; Index 1310; Unmangled Borland C++ Function: qualified function Tdtm_Dossier::Logon()
And here is what I get from using dumpbin :
1310 11F9 00105234 #Tdtm_Dossier#Logon$qv
Here is the exception :
Unhandled Exception at 0x034B258C (modDll.dll) in functionsCpp.exe : 0xC0000005 :
Access violation writting to 0x000000AC.
The code I am using to call and use this function is as follow :
#include <stdio.h>
#include <Windows.h>
#include <iostream>
typedef int (*Logon)();
int main()
{
HMODULE modDll;
int resultLogon;
modDll= LoadLibrary("C:\\dll\\modDll.dll");
Logon logon;
logon = (Logon)GetProcAddress(modDll,"#Tdtm_Dossier#Logon$qv");
if(logon)
{
resultLogon = logon(); //<-- This is where I get the exception
printf("Function has been loaded\n");
}
else
// TODO: Error message
FreeLibrary(modDll);
}
Since the DLL documentation doesn't give me any interesting information on how to use the function, I can't count on it.
The DLL is correctly loaded and the GetProcAddress does return something. I guess (but I'm not sure) that it has something to do with my typedef, but I can't figure out what could be the return type of this function.
If you read e.g. this document on Borland C++ name mangling you might figure out that the symbol name "#Tdtm_Dossier#Logon$qv" represents a non-static member function of the class Tdtm_Dossier. You can't call non-static member function like normal functions, they have a hidden first argument that becomes the this pointer in the member function.
What's happening here is probably that the Logon member function tries to access member variables of the object instance, of which there is none, which leads to undefined behavior and a crash.
To be able to use this library you need the header file and the link library. You can't just call functions (member or not) and hope for the best.

LoadLibrary cannot find ntoskrnl

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.

Lua module pushing C functions from DllMain

I've got damn big problem. As you know Lua allows making modules and you can load these modules with require() function from 5.1(previously loadlib).
#define LUA extern "C" __declspec(dllexport) int __cdecl
static int l_TestFunc(lua_State * L)
{
lua_pushboolean (L, 1); // return true
return 1;
}
LUA luaopen_MyModule(lua_State *L)
{
printf("test2");
lua_pushcfunction(L, l_TestFunc);
lua_setglobal(L, "TestFunc");
return 1;
}
so in Lua you are just using require("MyModule") and everything works.(luaopen_* is entry point then)
But I need to use standard way(DllMain as entry point). I tried but it didn't work.
Got any ideas?
But I need to use standard way(DllMain as entry point). I tried but it didn't work. Got any ideas?
DllMain is always going to be your entry point (if defined), but you can't use it to load your functions because you have no Lua state to load them into there.
When you run "require" in Lua code, the app executing that code (e.g. lua.exe) will load your DLL (invoking DllMain), then call luaopen_MyModule passing in the Lua state that executed the require statement. There's no way for your DllMain to have access to that state pointer...
...well, no ordinary way. You could work something out so that the host apps writes the memory location of the Lua state to some external location accessible to your DLL (registry, file, etc.) before loading your DLL. Your DLLMain could fetch the pointer register and it's functions into that state. Not sure why you'd want to do that, but in a language like C it's technically possible.
This would require that you wrote the host, so you could arrange to write the state somewhere. Or you could have a separate module, loaded the ordinary way, which writes the Lua_state value, then all other modules could access it from their DllMains.
This smells a lot like an XY Problem. Care to share why you want to register your functions in DllMain?
Try this...
Instead of using the name MyModule in require("MyModule") and luaopen_MyModule use the name of the executable that your DLL is injected into. If that doesn't work change the require call to have .exe at the end.
Lua's require is going to call Win32 LoadLibrary and then GetProcAddress to find the luaopen function. Both calls will use the argument to require(). It appears that PE-inject makes all the functions in the injected DLL appear as if they are in the EXE module. So, you need LoadLibrary to return the handle to the EXE module and then GetProcAddress will find the injected luaopen function.
The are a few reasons this might not work. One is that Lua's require does have the requirement that the DLL file name and the DLL module name match. That's not a Win32 requirement and so might not be the case for your portable executable.

Access Violation calling imported function

I've got a function imported from a DLL. I control the source of both the host executable and the dynamic library. Now, in DLLMain then I used MessageBox to pop up the address of the function I'm exporting, and compared it using a breakpoint to the function pointer returned by GetProcAddress, and they're identical.
However, when I try to call the function, I get an access violation. The function in question just returns NULL and has no logic, so it can't be thrown by the function specifically.
How can calling a known valid function pointer, with the correct signature, and verified safe logic, yield an access violation?
Edit: Information gained through another separate question about why the debugger is dying in this situation suggests that my stack is being smashed too? That would make more sense than an AV, but the function pointer and the function are completely compatible and the address is correct.
extern "C" Render* __cdecl CreateRender(WindowsOS* ptr) {
return nullptr;
}
typedef Render*(__cdecl *RendererCreateFunction)(WindowsOS*);
I used a simple, small piece of code in DLLMain to qualify that they are in fact compatible as far as the compiler is concerned.
BOOL WINAPI DllMain(
__in HINSTANCE hinstDLL,
__in DWORD fdwReason,
__in LPVOID lpvReserved
) {
RendererCreateFunction func = &CreateRender;
}
If they aren't compatible (they include the same header) then the compiler should throw an error and refuse to build the DLL, but it accepts this just fine.
If this is DLLMain you use in your code then it has no return statement and most likely returns a not initialized value, quite probably 0 as a good main function, which effectively unloads the DLL from the memory. Make sure DLLMain returns TRUE.
I completely failed this one. Wrote a class that manages a resource without respecting my move and copy semantics properly. Turns out that I was calling FreeLibrary() on the library in question mistakenly before I needed to use it.