#include <Windows.h>

// UNICODE_STRING structure
typedef struct _UNICODE_STRING 
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

//LdrLoadDll function prototype 
typedef NTSTATUS (WINAPI *fLdrLoadDll) 
(
	IN PWCHAR PathToFile OPTIONAL,
	IN ULONG Flags OPTIONAL, 
	IN PUNICODE_STRING ModuleFileName, 
	OUT PHANDLE ModuleHandle 
); 

//RtlInitUnicodeString function prototype
typedef VOID (WINAPI *fRtlInitUnicodeString) 
(
	PUNICODE_STRING DestinationString,
	PCWSTR SourceString
);

HMODULE hNtDll;
fLdrLoadDll _LdrLoadDll;
fRtlInitUnicodeString _RtlInitUnicodeString;

//_____________________________________________
//
// LoadDll: LoadLibrary replacement
// 
// This function loads the specified DLL into our process.
// This function is a replacement for the Windows LoadLibrary() function. 
//
// PARAMETERS:
// szFileName: path of the DLL to load.
//
// RETURN VALUE:
// HMODULE DllHandle: An handle to the DLL module in memory.
//_____________________________________________
//
HMODULE LoadDll( LPCSTR szFileName) 
{  

   // Load required functions dinamically
   hNtDll = GetModuleHandleA("ntdll.dll");
   _LdrLoadDll = (fLdrLoadDll) GetProcAddress( hNtDll, "LdrLoadDll");
   _RtlInitUnicodeString = (fRtlInitUnicodeString) GetProcAddress( hNtDll, "RtlInitUnicodeString");

   int StrLen = lstrlenA(szFileName);
   BSTR WideStr = SysAllocStringLen(NULL, StrLen);
   MultiByteToWideChar(CP_ACP, 0, szFileName, StrLen, WideStr, StrLen);

   UNICODE_STRING usDllName;
   _RtlInitUnicodeString(&usDllName, WideStr);
   SysFreeString(WideStr);

   HANDLE DllHandle; 
   _LdrLoadDll(0, 0, &usDllName, &DllHandle);

   return (HMODULE)DllHandle;
}

int main() //Usage example
{
   HMODULE hmodule = LoadDll("Kernel32.dll");
   return (int)hmodule;
}