How to call a function within DLL?

This is what I have, what am I doing wrong?

1
2
3
4
5
6
7
8
9
10
11
#include <windows.h>

void test(){
    MessageBox(0, "Function called", "Function", MB_OK);
}

BOOL APIENTRY DllMain(HMODULE Module, DWORD reason, LPVOID Reserved){
    if(reason == DLL_PROCESS_ATTACH){
        CreateThread(0, 0, &test(), 0, 0, 0);
    }
}
Well, the first thing I notice is on line 9, you have &test(), which doesn't do what you want. It should be without parenthesis.

Edit:
According to https://msdn.microsoft.com/en-us/library/windows/desktop/ms686736(v=vs.85).aspx , You should declare your test function as DWORD WINAPI, not void. (so return 0 at the end of the function)
Last edited on
How would I go about calling this DLL's test() function from a console application then? The simplest way please :-)
Okay did some research and found a way, problem is, the console crashes for some reason.

This is my DLLmain:

1
2
3
4
5
6
7
8
9
10
11
#include <windows.h>

void ThreadProc(){
    MessageBox(0, "DLL function", "DLL function", MB_OK);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){
    if(fdwReason == DLL_PROCESS_ATTACH){
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadProc, 0, 0, 0);
    }
}


And this is the console application attempting to call the DLL's function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <windows.h>

typedef void (*ThreadProcFunc)();

int main(){
    ThreadProcFunc _ThreadProcFunc;
    HINSTANCE GetDllFunc = LoadLibrary("C:\\DLL.dll");
    if(GetDllFunc){
        _ThreadProcFunc = (ThreadProcFunc)GetProcAddress(GetDllFunc, "ThreadProc");

        _ThreadProcFunc();
    }
}


Changing the function type from void to DWORD WINAPI still results in a crash.
Last edited on
You do not check the return value of GetProcAddress(), which could be nullptr if the function is not found or if something else fails.
ThreadProc() is not being exported with __declspec(dllexport), so a pointer to it will never be returned by GetProcAddress().
Finally, ThreadProc() should use the stdcall calling convention, it should take a void * as a parameter, and it should return a DWORD. Never cast a function pointer to a different type of function pointer like you're doing on line 9.
Last edited on
What compiler are you using? (If you aren't using MSVC then __declspec(dllexport) won't work.)

Andy

PS When I tried the above code with MSVC I didn't get a crash. Instead the DLL failed to load with error 1114 (ERROR_DLL_INIT_FAILED) for both release and debug builds. As DllMain is not returning TRUE as expected, instead there is no explicit return, it seems it ends up returning FALSE hence aborting the DLL load.

When I build with MinGW GCC I do get a crash.
Last edited on
Working with DLL threading is frustrating but I HAVE to learn it for what I want to do. I managed to fix the crashing issue at least. I was told to never create a thread from DllMain function and to instead export a function that would launch the thread. This is the result, but nothing happens.

DLLmain.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <windows.h>
#include <iostream>


DWORD WINAPI threadProc(LPVOID parameter){
    std::cout << "Writing this to the ostream of command prompt through threading" << std::endl;
}

void startThread(){
    HANDLE DllThread = CreateThread(0, 0, &threadProc, 0, 0, 0);
    CloseHandle(DllThread);
}


BOOL WINAPI DllMain(HINSTANCE DLL, DWORD Reason, LPVOID Reserved){
    switch(Reason){
    case DLL_PROCESS_ATTACH:
        startThread();
        break;
    }
} 


and simply main.cpp doing the calling:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <windows.h>

typedef void (*startThreadFunc)();

int main(){
    HINSTANCE getDLLFunc = LoadLibrary("C:\\Users\\Kalist\\Desktop\\Projects\\DLL\\bin\\Debug\\DLL.dll");
    startThreadFunc startThreadFuncVar = (startThreadFunc)GetProcAddress(getDLLFunc, "startThread");
    startThreadFuncVar();
    FreeLibrary(getDLLFunc);
}



I don't understand the whole deal with __declspec(dllexport)/(dllimport), it doesn't seem to make a difference whether I put it there or not...
Last edited on
I forgot to mention, besides everything I said earlier, the function to be exported also has to be extern "C" to prevent the compiler from mangling the name, else you'll never be able to get the name right for passing to GetProcAddress().
Your program isn't giving the thread time to run.

Loading the library, getting the function's address and calling it (to start the thread), and then immediately exiting the program isn't terribly useful.

Also note that calling CreateThread from DllMain "is not recommended"!

Does creating a thread from DllMain deadlock or doesn't it?
http://blogs.msdn.com/b/oldnewthing/archive/2007/09/04/4731478.aspx

Andy

you'll never be able to get the name right for passing to GetProcAddress().

Well, not never. But it is messy.

If forced to (i.e. you have inherited pre-exisiting DLL which you don't have the code for) you can dump the exports with "link /dump /exports" and copy and paste the horrible string or you can call GetProcAddress using the ordinal.
Last edited on
Well, yes. Without inspecting the DLL, I meant to say.
Can you call threads(functions) from the DLL process without declaring DllMain()?
You said it yourself.
You wrote:
I was told to never create a thread from DllMain function and to instead export a function that would launch the thread.
Thank you all for spending time answering this. I found a solution, and it was much simpler than I'd ever imagined.

DLLmain:
1
2
3
4
5
6
7
#include <iostream>
#include <windows.h>

extern "C" void message(){
    std::cout << "Hello from DLL thread";
}


main:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <windows.h>

typedef void (*FNPTR)();

int main(){
    HINSTANCE hInst = LoadLibrary("C:\\Users\\Kalist\\Desktop\\Projects\\DLL\\bin\\Debug\\DLL.dll");

    if(!hInst){
        std::cout << "Could not load the library";
        return EXIT_FAILURE;
    }

    FNPTR fn = (FNPTR)GetProcAddress(hInst, "message");
    if(!fn){
        std::cout << "Could not locate the function";
        return EXIT_FAILURE;
    }
    fn();

    FreeLibrary(hInst);
}


Who could've thought it actually was this simple!
Last edited on
I'd just like to point out that calling into a DLL doesn't cause the thread to change. Loading a DLL simply copies its code into memory, and calling a function from a DLL is exactly the same as calling any other function.
Did I write it wrong? Or is calling a DLL thread all that it does? I'm planning to use it to overwrite a process' memory by injecting into it and then calling my own functions to overwrite certain memory addresses.

I imagine I'll have to use CreateThread() at that point somehow.
Last edited on
Did I write it wrong?
That depends on what you intended to do. The code loads a DLL and calls a function that the DLL exports.

Or is calling a DLL thread all that it does?
There's no such thing as a "DLL thread".

I imagine I'll have to use CreateThread() at that point somehow.
No, injecting a DLL involves:
1. Allocating executable memory in the target process, using VirtualAllocEx().
2. Copying a small injector into this memory, using WriteProcessMemory(). The injector is usually written in Assembly (often at least partly dynamically generated to make it position-independent), since it needs to be small and simple: all it needs to do is load a DLL and execute some function in it.
3. Call CreateRemoteThread() from your process, passing a handle to the target process and using the executable memory as entry point. This will fire off a new thread in the target process starting from the injector, which will eventually jump into the DLL so you can run whatever you need.

You might want to take a look at this project: https://github.com/nektra/Deviare-InProc/
It's made for API hooking, but it does DLL injection, so it already has an injector implemented.
I have a solution in VS 2008 with 2 projects in it. One is a DLL written in C++ and the other is a simple C++ console application created from a blank project. I would like know how to call the functions in the DLL from the application.
Define the function in the export.h file.

int WINAPI IsolatedFunction(const char *title, const char *test);

Step 2: Define the function in the export.cpp file.

#include <windows.h>

int WINAPI IsolatedFunction(const char *title, const char *test)
{
MessageBox(0, title, test, MB_OK);
return 1;
}

Step 3: Define the function as an export in the export.def defintion file.

EXPORTS IsolatedFunction

Step 4: Create a DLL project and add the export.cpp and export.def files to this project. Building this project will create an export.dll and an export.lib file.

The following two steps link to the DLL at link time. If you don't want to define the entry points at link time, ignore the next two steps and use the LoadLibrary and GetProcAddress to load the function entry point at runtime.

Step 5: Create a Test application project to use the dll by adding the export.lib file to the project. Copy the export.dll file to ths same location as the Test console executable.

Step 6: Call the IsolatedFunction function from within the Test application as shown below.

#include "stdafx.h"

// get the function prototype of the imported function
#include "../export/export.h"

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// call the imported function found in the dll
int result = IsolatedFunction("hello", "world");

return 0;
}
Topic archived. No new replies allowed.