Click here to Skip to main content
15,897,315 members
Articles / Programming Languages / ASM

Loading Win32/64 DLLs "manually" without LoadLibrary()

Rate me:
Please Sign up or sign in to vote.
4.97/5 (31 votes)
8 Mar 2014CPOL5 min read 257.1K   8.1K   107  
How to load DLLs by allocating memory and loading the DLL from file/memory and then relocating/importing.
// This DLL has been compiled/linked without the standard library.
//
// Since there is no standard library some C/C++ features don't work.
// Several features (like debug runtime checks) are turned off on the "Code Generation"
// page since these features require the support of the default runtime library.
// The lack of the std lib is more painful in C++ than in C (for example static variable init
// and deinit doesn't work), no default new/delete operator, etc... You can use a mini
// standard lib to provide these.
// Still, being able to use C/C++ instead of assembly to write relocatable code patches is cool!!!
#include <windows.h>
#include <stdarg.h>
#include "TestDll.h"


// Since we have no standard C/C++ library just pure WinAPI...
int printf(const char* format, ...)
{
	int len, max_len;
	DWORD written;
	char buf[0x100];
	va_list args;

	va_start(args, format);
	len = wvsprintfA(buf, format, args);
	va_end(args);

	max_len = (int)sizeof(buf)-1;
	len = len < max_len ? len : max_len;
	buf[len] = 0;

	WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), buf, (DWORD)len, &written, NULL);
	return len;
}

int AddNumbers(int a, int b)
{
	printf("DLL: AddNumbers(%d, %d)\n", a, b);
	return a + b;
}

void MyMessageBox(const char* message)
{
	printf("DLL: MyMessageBox(\"%s\")\n", message);
	MessageBoxA(NULL, message, "DLL MessageBox!", MB_OK);
}

DLLInterface g_Interface =
{
	AddNumbers,
	MyMessageBox
};

__declspec(dllexport) const DLLInterface* GetDLLInterface()
{
	return &g_Interface;
}

// If you don't need a DllMain then you can delete this function and then use the /NOENTRY linker option.
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	// With manual DLL loading you can not use DLL_THREAD_ATTACH and DLL_THREAD_DETACH.
	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		printf("DLL: DLL_PROCESS_ATTACH\n");
		// TODO
		break;
	case DLL_PROCESS_DETACH:
		printf("DLL: DLL_PROCESS_DETACH\n");
		// TODO
		break;
	default:
		break;
	}
	return TRUE;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions