Didier Stevens

Friday 8 September 2017

Quickpost: DllDemo

Filed under: Quickpost — Didier Stevens @ 0:00

This is a quick demo on loading DLLs with standard Windows tools.

I wrote a DLL for this demo:

#include <windows.h>

extern "C" __declspec(dllexport) void ExportedFunction(void)
	MessageBox(NULL, "Hello from ExportedFunction, DemoDll!", "DemoDll", MB_OK);;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
	switch (fdwReason)
		MessageBox(NULL, "Hello from DllMain, DemoDll!", "DemoDll", MB_OK);;




	return TRUE;

A message box is displayed when DllMain (the entrypoint for DLLs) is called when the DLL is loaded into a process, and another message box is displayed when function ExportedFunction is executed.

Function ExportedFunction is prefixed by __declspec(dllexport) to export the function, and with extern “C” to prevent C++ name mangling.

One method to load this DLL into a process, is to use the rundll32 command (since I’m doing this demo on Windows 10, I’m using the 64-bit version of my DLL):

No message box is displayed: the DLL was not loaded. The reason is that rundll32 requires you to specify an exported function that it needs to call.

With dumpbin, we can get an overview of the exported functions of a DLL:

We can specify the name of the exported function we want to call like this:

We can see the message box from the entrypoint, and then the message box from the exported function we called:

This means that the DLL was loaded into the rundll32 process, and that the called function was executed.

Exported functions have an ordinal too (a number to identify exported functions), and that number can be used too to specify the function, like this:

If we use rundll32 with a function that is not exported by the DLL, then the DLL is loaded:

rundll32 will display an error because it could not find the exported function:

But as we could see, the DLL got loaded.

Despite the name would make you think (rundll32), the version of rundll32 I used is a 64-bit executable, and that’s why I used a 64-bit DLL.

32-bit DLLs have to be loaded into 32-bit processses, and 64-bit DLLs into 64-bit processes.

However, rundll32 will start a “proxy” process if you mix bitness, so that DLLs will always be loaded.

Let’s look at the 4 possible combinations:

64-bit rundll32 with 32-bit DLL:

Taking a look with process explorer, we see that 64-bit rundll32 started 32-bit rundll32 to load the 32-bit DLL:

64-bit rundll32 with 64-bit DLL:

In this case, there is no need for a “proxy” process:

32-bit rundll32 with 32-bit DLL:

In this case too, there is no need for a “proxy” process:

And finally, 32-bit rundll32 with 64-bit DLL:

Here we see that 32-bit rundll32 started 64-bit rundll32 to load the 64-bit DLL:

The following is another method: rundll32 shell32.dll,Control_RunDLL C:\Demo\DemoDLL-64-bit.dll

You have to provide an absolute path.

Finally, another method to load a DLL is with regsvr32. I’ve started to use regsvr32 long ago, when I developed ActiveX object: you used it to deploy ActiveX objects on machines.

By default, regsvr32 will load the DLL and call exported function DllRegisterServer:

Since function DllRegisterServer is not exported by the demo DLL, we get an error:

But the DLL was loaded. If we export a function named DllRegisterServer in our DLL, it would get executed.

regsvr32 can be used to call other exported functions too (DllUnRegisterServer and DllInstall), as can be seen from the help dialog when you run regsvr32 without arguments:

DemoDll_V0_0_0_1.zip (https)
MD5: 51ED8255B71097269BFF9B5ADBFDC392
SHA256: 599BA297705B15580A297C3F47429225C38EA9FAA4A8DF27BCE49C918964AD30

Quickpost info


  1. […] Quickpost: DllDemo […]

    Pingback by Overview of Content Published In September | Didier Stevens — Sunday 15 October 2017 @ 16:09

  2. […] compile the DLLs from this quickpost with MinGW on Kali, you first have to install […]

    Pingback by Quickpost: Compiling DLLs with MinGW on Kali | Didier Stevens — Tuesday 10 July 2018 @ 0:00

  3. […] Luckily, Microsoft has a built-in DLL loader called rundlll32.exe, but rundll32.exe can be annoying if you don’t have any exported functions (= functions to be used by other programs) in your DLL. My colleague Didier Stevens explains DLL entrypoints quite nicely in his own blogpost. If you are interested in l… […]

    Pingback by Debugging DLL’s – 3 techniques to help you get started – NVISO Labs — Tuesday 4 August 2020 @ 16:51

RSS feed for comments on this post. TrackBack URI

Leave a Reply (comments are moderated)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.