Usage of GetProcAddress confused non executing - c++

I might be missing something very easy but still i confronted this problem that i couldnt solve. I create a dll with these functions,
extern "C"{
__declspec(dllexport) void some();
__declspec(dllexport) void printer();
}
void printer()
{
printf("printing...\n");
}
i compile it using cmake
cmake .. -G "Visual Studio 15 2017" -A x64 -DBUILD_SHARED_LIBS=TRUE
cmake --build . --config Release
the i load it from my dllloader.cpp
int main() {
HINSTANCE hGetProcIDDLL = LoadLibrary("mydll.dll");
if (hGetProcIDDLL == NULL) {
std::cout << "cannot locate the .dll file" << std::endl;
} else {
std::cout << "it has been called" << std::endl;
}
if(GetProcAddress(hGetProcIDDLL, "printer") == NULL){
}else{
std::cout <<"not null" << std::endl;
}
std::cout << GetLastError() << " err" << std::endl;
getchar();
return 0;
}
So GetLastError returns 0 but nothing is printed, in the original file it is pretty much the same, the function is more that just a printf() call but the function gets loaded, how do we run it ? I know i might be missing something, just function does not execute. Any help is appreciated

typedef void(*my_dll_print)(); // function pointer to print method of dll
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibrary("mydll.dll");
if (hGetProcIDDLL == nullptr)
std::cout << "cannot locate the .dll file" << std::endl;
else
std::cout << "it has been called" << std::endl;
my_dll_print print_method = reinterpret_cast<my_dll_print>(GetProcAddress(hGetProcIDDLL, "printer")); // Extract method address and create pointer
if (print_method == nullptr)
std::cout << "is null" << std::endl;
else
print_method(); // Call dll method
std::cout << GetLastError() << " err" << std::endl;
getchar();
return 0;
}
Try to use nullptr instead NULL to check pointer.
GetProcAdrress retrieves the address of an exported function or variable from the specified dynamic-link library! and makes no function call. You must first assign to function pointer then make call to pointed function!

Related

Loading a DLL with LoadLibraryA(path_to_dll) is changing the inherit handle flag (HANDLE_FLAG_INHERIT) from 1 to 0 for file descriptors 0, 1, and 2

We have written some functions in golang and a c wrapper on top of that to invoke those functions. We first build golang code to create an archive file and then we build the wrapper code in c to be consumed as a DLL.
After loading this DLL using LoadLibraryA(path_to_dll) in my program I am seeing that the inherit flags for fd 0, 1, and 2 are getting changed from 1 to 0. This does not happen immediately after loading the DLL though. I had added sleep in my code after the load library call and seems like it takes a few milliseconds after loading the library to change the flag values.
I am using GetHandleInformation((HANDLE) sock, &flags) to get the inherit flag value.
Any idea/pointers on what could be causing this? Thanks!
Updates:
I was able to find out the exact line in the go code that is flipping the inherit flag values. The global variable reqHandler in below k8sService.go code is causing this. Any idea why the use of this global variable is flipping the inherit flag values?
my-lib/k8sService.go (go code)
package main
import "C"
import (
"my-lib/pkg/cmd"
)
func main() {
}
var reqHandler []*cmd.K8sRequest
my-lib/pkg/cmd/execute.go
import (
"my-lib/pkg/dto"
)
type K8sRequest struct {
K8sDetails dto.K8sDetails
}
my-lib/pkg/dto/structs.go
package dto
// K8sDetails contains all the necessary information about talking to the cluster. Below struct has few more variables.
type K8sDetails struct {
// HostName of the cluster's API server
HostName string `json:"hostname"`
// Port on which the API server listens on to
Port int `json:"port"`
}
We have a C wrapper on top of the above k8sService.go. We first build golang code to create an archive file and then with this archive file and wrapper code in C we build the target DLL. Below is the sample program which loads this DLL and also prints the inherit flag values before and after loading the DLL.
#include <windows.h>
#include <iostream>
#include <io.h>
#include "wrapper/cWrapper.h"
void printInheritVals() {
typedef SOCKET my_socket_t;
my_socket_t fd0 = _get_osfhandle(0);
my_socket_t fd1 = _get_osfhandle(1);
my_socket_t fd2 = _get_osfhandle(2);
std::cout << "fd0: " << fd0 << std::endl;
std::cout << "fd1: " << fd1 << std::endl;
std::cout << "fd2: " << fd2 << std::endl;
DWORD flags;
int inherit_flag_0 = -1;
int inherit_flag_1 = -1;
int inherit_flag_2 = -1;
if (!GetHandleInformation((HANDLE) fd0, &flags)) {
std::cout << "GetHandleInformation failed" << std::endl;
} else {
inherit_flag_0 = (flags & HANDLE_FLAG_INHERIT);
}
if (!GetHandleInformation((HANDLE) fd1, &flags)) {
std::cout << "GetHandleInformation failed" << std::endl;
} else {
inherit_flag_1 = (flags & HANDLE_FLAG_INHERIT);
}
if (!GetHandleInformation((HANDLE) fd2, &flags)) {
std::cout << "GetHandleInformation failed" << std::endl;
} else {
inherit_flag_2 = (flags & HANDLE_FLAG_INHERIT);
}
std::cout << "inherit_flag_0: " << inherit_flag_0 << std::endl;
std::cout << "inherit_flag_1: " << inherit_flag_1 << std::endl;
std::cout << "inherit_flag_2: " << inherit_flag_2 << std::endl;
}
int main()
{
printInheritVals(); // In output all flag values are 1
HINSTANCE hGetProcIDDLL = LoadLibraryA(PATH_TO_DLL);
if (!hGetProcIDDLL) {
std::cout << "could not load the dynamic library" << std::endl;
return EXIT_FAILURE;
}
std::cout << "Library loaded" << std::endl;
printInheritVals(); // In output all flag values are 1
Sleep(1000);
printInheritVals(); // In output all flag values are 0
return EXIT_SUCCESS;
}
This is a bug in the golang.org/x/sys/windows package. The same issue used to be in the built-in syscall package as well, but it was fixed in Go 1.17.
Something in your project must be importing the golang.org/x version of the package instead of the built-in one, and so the following code executes to initialize the Stdin, Stdout, and Stderr variables:
var (
Stdin = getStdHandle(STD_INPUT_HANDLE)
Stdout = getStdHandle(STD_OUTPUT_HANDLE)
Stderr = getStdHandle(STD_ERROR_HANDLE)
)
func getStdHandle(stdhandle uint32) (fd Handle) {
r, _ := GetStdHandle(stdhandle)
CloseOnExec(r)
return r
}
The fix for that code would be to remove the CloseOnExec call, which is what clears HANDLE_FLAG_INHERIT on the given file handle.
How to solve that in your project is less clear. I think you can vendor golang.org/x/sys module in your project, perhaps with a replace directive in your go.mod. Apply the fix in your local copy.
Meanwhile, I encourage you to also report the bug. The documentation instructs you to report the issue on the main Go project at GitHub, prefixing the title with x/sys.

'dll_file' could be '0': This does not adhere to the specification for the function 'GetProcAddress'

So I would like to use the DLL that I created, and I have this really weird warning I didn't see anyone has this one. I checked if LoadLibray returns "NULL", and this is not the case.
typedef DATA_BLOB(*encryption_decryption)(DATA_BLOB, bool*);
HINSTANCE dll_file = LoadLibrary(L"dllForEncryptionNDecryptionn.dll");
if (dll_file != NULL) {
cout << "Library loaded!" << endl;
}
else {
failed();
}
encryption_decryption encryption = (encryption_decryption)GetProcAddress(dll_file,"encryption");
if(encryption != NULL)
{
cout << "Workded!" << endl;
}
else
{
failed();
}
void failed() {
cout << GetLastError() << endl;
cout << "Faild!" << endl;
}
Warning at the 8th line: "'dll_file' could be '0': this does not adhere to the specification for the function 'GetProcAddress'."
Everything works, it doesn't write any errors when I run it.
If anything goes wrong in LoadLibrary you call failed() that prints the error code and returns.
HINSTANCE dll_file = LoadLibrary(L"dllForEncryptionNDecryptionn.dll");
if (dll_file != NULL) {
cout << "Library loaded!" << endl;
}
else {
failed(); // returns even when dll_file is NULL
}
// so, here you don't know if it's NULL or a valid handle which is why you get the warning
encryption_decryption encryption = (encryption_decryption)GetProcAddress(dll_file,"encryption");
If LoadLibrary fails, you shold not use that dll_file to call GetProcAddress.
encryption_decryption encryption = nullptr;
HINSTANCE dll_file = LoadLibrary(L"dllForEncryptionNDecryptionn.dll");
if(dll_file) {
encryption_decryption encryption =
(encryption_decryption)GetProcAddress(dll_file,"encryption");
} else {
// do NOT call GetProcAddress
}
if(encryption) {
// function successfully loaded
}

Why can't I open DLL file? Every time it returns NULL

So, I'm trying to use a function from DLL file and for some reason I can't open the DLL file: when I'm using the LoadLibrary function it returns as NULL
I'm freaking out that I can't find this bug
typedef unsigned int (WINAPI* AvVersion)(void);
void secret()
{
HMODULE dll = LoadLibrary("Secret.dll");
if (dll == NULL)
{
std::cout << "coudlnt open ""secret.dll""\nError Code:" << GetLastError() << std::endl;
return;
}
AvVersion function = (AvVersion)GetProcAddress(dll, "TheAnswerToLifeTheUniverseAndEverything");
std::cout << "result:" << function() << std::endl;
}
The code number is 126
and the name of the function is TheAnswerToLifeTheUniverseAndEverything

Function pointer obtained from GetProcAddress crashes the program if it uses the stdlib

I'm trying to dynamically load a dll and call a function from it at runtime. I have succeeded in getting a working pointer with GetProcAddress, but the program crashes if the function from the dll uses the stdlib. Here's the code from the executable that loads the dll:
#include <iostream>
#include <windows.h>
typedef int (*myFunc_t)(int);
int main(void) {
using namespace std;
HINSTANCE dll = LoadLibrary("demo.dll");
if (!dll) {
cerr << "Could not load dll 'demo.dll'" << endl;
return 1;
}
myFunc_t myFunc = (myFunc_t) GetProcAddress(dll, "myFunc");
if (!myFunc) {
FreeLibrary(dll);
cerr << "Could not find function 'myFunc'" << endl;
return 1;
}
cout << "Successfully loaded myFunc!" << endl;
cout << myFunc(3) << endl;
cout << myFunc(7) << endl;
cout << myFunc(42) << endl;
cout << "Successfully called myFunc!" << endl;
FreeLibrary(dll);
return 0;
}
Here's code for the dll that actually works:
#include <iostream>
extern "C" {
__declspec(dllexport) int myFunc(int demo) {
//std::cout << "myFunc(" << demo << ")" << std::endl;
return demo * demo;
}
}
int main(void) {
return 0;
}
(Note that the main method in the dll code is just to appease the compiler)
If I uncomment the line with std::cout however, then the program crashes after the cout << "Sucessfully loaded myFunc!" << endl; line but before anything else gets printed. I know there must be some way to do what I want; what do I need to change for it to work?
As discussed in the comments, it turns out that the compiler's demands for a main function were hints that I was inadvertently making a an exe that decptively used the file extension dll, not an actual dll (because I didn't quite understand the compiler options I was using), which in some way messed up the dynamic loading of that assembly.

Usage of dlsym()/dlopen()

I wrote next program:
#include <iostream>
#include <dlfcn.h>
int main(int argc, char** argv)
{
typedef void* (*fptr)();
fptr func;
void *handle = dlopen(0, RTLD_NOW);
std::cout << dlerror() << std::endl;
*(void **)(&func) = dlsym(handle, "__libc_start_main");
std::cout << dlerror() << std::endl;
std::cout << handle << " " << func << "\n";
dlclose(handle);
return 0;
}
and try to compile in next way:
g++ -rdynamic main.cpp -ldl -o test
When I run this program I don’t see any message. Why?
Thank U for attention.
Your process is faulting because dlerror() is only valid to call in an error condition, which you never validated actually happened prior to invocation.
From the Linux docs:
The function dlerror() returns a human readable string describing the
most recent error that occurred from dlopen(), dlsym() or dlclose()
since the last call to dlerror(). It returns NULL if no errors have
occurred since initialization or since it was last called.
In other words, your dlopen succeeded, so NULL is returned from dlerror(). That NULL is then sent as a char * to std::cout, and kerboom.
Bottom line: check your error conditions before invoking dlerror(). Try this instead:
#include <iostream>
#include <dlfcn.h>
int main(int argc, char** argv)
{
typedef void* (*fptr)();
fptr func;
void *handle = dlopen(0, RTLD_NOW);
if (handle == nullptr)
{
std::cout << dlerror() << std::endl;
exit(EXIT_FAILURE);
}
func = (fptr)dlsym(handle, "__libc_start_main");
if (!func)
{
std::cout << dlerror() << std::endl;
exit(EXIT_FAILURE);
}
std::cout << handle << " " << func << "\n";
dlclose(handle);
return 0;
}
This is (likely) undefined behavior:
std::cout << dlerror() << std::endl;
...unless dlerror is actually non-null (which it probably isn't). It should be:
char* error = dlerror();
if (error != 0)
std::cout << error << std::endl;
...or:
void *handle = dlopen(0, RTLD_NOW);
if (handle == 0)
std::cout << dlerror() << std::endl;
Also, you probably should abort if dlerror is non-null (or handle is null), because calling dlsym on an null handle is also undefined behavior.
See Why does std::cout output disappear completely after NULL is sent to it.