Ldrloaddll Problem

I am trying to code an alternative to LoadLibrary function, based on the idea of calling the function LdrLoadDll from ntdll. This function needs as a parameter the dll file to load, in a UNICODE_STRING format. I really can't get what I am doing wrong here (string seems to be correctly initialized), but when LdrLoadDll is called, I get the following error:

Unhandled exception in "Test.exe" (NTDLL.DLL): 0xC0000005: Access Violation.

I use Visual C++ 6.0 for this test, and I am using Windows 7 64 bit.

I post full code here, thanks in advance for any help:

#include <Windows.h>


typedef LONG NTSTATUS; //To be used with VC++ 6, since NTSTATUS type is not defined



typedef struct _UNICODE_STRING { //UNICODE_STRING structure
  USHORT  Length;
  USHORT  MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;




typedef NTSTATUS (WINAPI *fLdrLoadDll) //LdrLoadDll function prototype 
    (
         IN PWCHAR PathToFile OPTIONAL,
         IN ULONG Flags OPTIONAL, 
         IN PUNICODE_STRING ModuleFileName, 
         OUT PHANDLE ModuleHandle 
    ); 





/**************************************************************************
  *      RtlInitUnicodeString   (NTDLL.@)
  *
  * Initializes a buffered unicode string.
  *
  * RETURNS
  *  Nothing.
  *
  * NOTES
  *  Assigns source to target->Buffer. The length of source is assigned to
  *  target->Length and target->MaximumLength. If source is NULL the length
  *  of source is assumed to be 0.
  */
 void WINAPI RtlInitUnicodeString(
     PUNICODE_STRING target, /* [I/O] Buffered unicode string to be initialized */
     PCWSTR source)          /* [I]   '\0' terminated unicode string used to initialize target */
 {
     if ((target->Buffer = (PWSTR) source))
     {
         unsigned int length = lstrlenW(source) * sizeof(WCHAR);
         if (length > 0xfffc)
             length = 0xfffc;
         target->Length = length;
         target->MaximumLength = target->Length + sizeof(WCHAR);
     }
     else target->Length = target->MaximumLength = 0;
 }



NTSTATUS LoadDll( LPCSTR lpFileName)
{
  HMODULE hmodule = GetModuleHandleA("ntdll.dll");
  fLdrLoadDll   _LdrLoadDll = (fLdrLoadDll) GetProcAddress ( hmodule, "LdrLoadDll" );

  int AnsiLen = lstrlenA(lpFileName);
  BSTR WideStr = SysAllocStringLen(NULL, AnsiLen);
  ::MultiByteToWideChar(CP_ACP, 0, lpFileName, AnsiLen, WideStr, AnsiLen);

  UNICODE_STRING usDllFile;
  RtlInitUnicodeString(&usDllFile, WideStr); //Initialize UNICODE_STRING for LdrLoadDll function
  ::SysFreeString(WideStr);

  NTSTATUS result = _LdrLoadDll(NULL, LOAD_WITH_ALTERED_SEARCH_PATH, &usDllFile,0); //Error on this line!

  return result;
}



void main()
{
  LoadDll("Kernel32.dll");
}
2

2 Answers

in _LdrLoadDll(NULL, LOAD_WITH_ALTERED_SEARCH_PATH, &usDllFile,0); last parameter can't be zero

1

you can't call SysFreeString before you call _LdrLoadDll, since the usDllFile.buffer parameter points to this string

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

David Miller

David Miller

Executive Financial & Market Analyst

David Miller brings 15 years of experience in global economics, personal finance strategy, and market dynamics. He specializes in turning complex economic trends into actionable insights for everyday readers.

Share this article
Twitter Facebook Pinterest