Rss Feed
Tweeter button
Facebook button
Technorati button
Reddit button
Myspace button
Linkedin button
Webonews button
Delicious button
Digg button
Flickr button
Stumbleupon button
Newsvine button

Loading a DLL from memory

This tutorial describes a technique how a dynamic link library (DLL) can be loaded from memory without storing it on the hard-disk first.

Overview

The default windows API functions to load external libraries into a program (LoadLibrary, LoadLibraryEx) only work with files on the filesystem. It’s therefore impossible to load a DLL from memory. But sometimes, you need exactly this functionality (e.g. you don’t want to distribute a lot of files or want to make disassembling harder). Common workarounds for this problems are to write the DLL into a temporary file first and import it from there. When the program terminates, the temporary file gets deleted.

In this tutorial, I will describe first, how DLL files are structured and will present some code that can be used to load a DLL completely from memory – without storing on the disk first.

Windows executables – the PE format

Most windows binaries that can contain executable code (.exe, .dll, .sys) share a common file format that consists of the following parts:

DOS header

DOS stub

PE header
Section header
Section 1
Section 2
. . .
Section n

All structures given below can be found in the header file winnt.h.

DOS header / stub

The DOS header is only used for backwards compatibility. It precedes the DOS stub that normally just displays an error message about the program not being able to be run from DOS mode.

Microsoft defines the DOS header as follows:

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // File address of new exe header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

PE header

The PE header contains informations about the different sections inside the executable that are used to store code and data or to define imports from other libraries or exports this libraries provides.

It’s defined as follows:

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

The FileHeader describes the physical format of the file, i.e. contents, informations about symbols, etc:

typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

The OptionalHeader contains informations about the logical format of the library, including required OS version, memory requirements and entry points:

typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;

    //
    // NT additional fields.
    //

    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

The DataDirectory contains 16 (IMAGE_NUMBEROF_DIRECTORY_ENTRIES) entries defining the logical components of the library:

Index Description
0 Exported functions
1 Imported functions
2 Resources
3 Exception informations
4 Security informations
5 Base relocation table
6 Debug informations
7 Architecture specific data
8 Global pointer
9 Thread local storage
10 Load configuration
11 Bound imports
12 Import address table
13 Delay load imports
14 COM runtime descriptor

For importing the DLL we only need the entries describing the imports and the base relocation table. In order to provide access to the exported functions, the exports entry is required.

Section header

The section header is stored after the OptionalHeader structure in the PE header. Microsoft provides the macro IMAGE_FIRST_SECTION to get the start address based on the PE header.

Actually, the section header is a list of informations about each section in the file:

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

A section can contain code, data, relocation informations, resources, export or import definitions, etc.

Loading the library

To emulate the PE loader, we must first understand, which steps are neccessary to load the file to memory and prepare the structures so they can be called from other programs.

When issuing the API call LoadLibrary, Windows basically performs these tasks:

  1. Open the given file and check the DOS and PE headers.
  2. Try to allocate a memory block of PEHeader.OptionalHeader.SizeOfImage bytes at position PEHeader.OptionalHeader.ImageBase.
  3. Parse section headers and copy sections to their addresses. The destination address for each section, relative to the base of the allocated memory block, is stored in the VirtualAddress attribute of the IMAGE_SECTION_HEADER structure.
  4. If the allocated memory block differs from ImageBase, various references in the code and/or data sections must be adjusted. This is called Base relocation.
  5. The required imports for the library must be resolved by loading the corresponding libraries.
  6. The memory regions of the different sections must be protected depending on the section’s characteristics. Some sections are marked as discardable and therefore can be safely freed at this point. These sections normally contain temporary data that is only needed during the import, like the informations for the base relocation.
  7. Now the library is loaded completely. It must be notified about this by calling the entry point using the flag DLL_PROCESS_ATTACH.

In the following paragraphs, each step is described.

Allocate memory

All memory required for the library must be reserved / allocated using VirtualAlloc, as Windows provides functions to protect these memory blocks. This is required to restrict access to the memory, like blocking write access to the code or constant data.

The OptionalHeader structure defines the size of the required memory block for the library. It must be reserved at the address specified by ImageBase if possible:

memory = VirtualAlloc((LPVOID)(PEHeader->OptionalHeader.ImageBase),
    PEHeader->OptionalHeader.SizeOfImage,
    MEM_RESERVE,
    PAGE_READWRITE);

If the reserved memory differs from the address given in ImageBase, base relocation as described below must be done.

Copy sections

Once the memory has been reserved, the file contents can be copied to the system. The section header must get evaluated in order to determine the position in the file and the target area in memory.

Before copying the data, the memory block must get committed:

dest = VirtualAlloc(baseAddress + section->VirtualAddress,
    section->SizeOfRawData,
    MEM_COMMIT,
    PAGE_READWRITE);

Sections without data in the file (like data sections for the used variables) have a SizeOfRawData of 0, so you can use the SizeOfInitializedData or SizeOfUninitializedData of the OptionalHeader. Which one must get choosen depending on the bit flags IMAGE_SCN_CNT_INITIALIZED_DATA and IMAGE_SCN_CNT_UNINITIALIZED_DATA that may be set in the section`s characteristics.

Base relocation

All memory addresses in the code / data sections of a library are stored relative to the address defined by ImageBase in the OptionalHeader. If the library can’t be imported to this memory address, the references must get adjusted => relocated. The file format helps for this by storing informations about all these references in the base relocation table, which can be found in the directory entry 5 of the DataDirectory in the OptionalHeader.

This table consists of a series of this structure

typedef struct _IMAGE_BASE_RELOCATION {
    DWORD   VirtualAddress;
    DWORD   SizeOfBlock;
} IMAGE_BASE_RELOCATION;

It contains (SizeOfBlock – IMAGE_SIZEOF_BASE_RELOCATION) / 2 entries of 16 bits each. The upper 4 bits define the type of relocation, the lower 12 bits define the offset relative to the VirtualAddress.

The only types that seem to be used in DLLs are

IMAGE_REL_BASED_ABSOLUTE
No operation relocation. Used for padding.
IMAGE_REL_BASED_HIGHLOW
Add the delta between the ImageBase and the allocated memory block to the 32 bits found at the offset.

Resolve imports

The directory entry 1 of the DataDirectory in the OptionalHeader specifies a list of libraries to import symbols from. Each entry in this list is defined as follows:

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;            // 0 for terminating null import descriptor
        DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
    };
    DWORD   TimeDateStamp;                  // 0 if not bound,
                                            // -1 if bound, and real date\time stamp
                                            //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                            // O.W. date/time stamp of DLL bound to (Old BIND)

    DWORD   ForwarderChain;                 // -1 if no forwarders
    DWORD   Name;
    DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;

The Name entry describes the offset to the NULL-terminated string of the library name (e.g. KERNEL32.DLL). The OriginalFirstThunk entry points to a list of references to the function names to import from the external library. FirstThunk points to a list of addresses that gets filled with pointers to the imported symbols.

When we resolve the imports, we walk both lists in parallel, import the function defined by the name in the first list and store the pointer to the symbol in the second list:

nameRef = (DWORD *)(baseAddress + importDesc->OriginalFirstThunk);
symbolRef = (DWORD *)(baseAddress + importDesc->FirstThunk);
for (; *nameRef; nameRef++, symbolRef++)
{
    PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)(codeBase + *nameRef);
    *symbolRef = (DWORD)GetProcAddress(handle, (LPCSTR)&thunkData->Name);
    if (*funcRef == 0)
    {
        handleImportError();
        return;
    }
}

Protect memory

Every section specifies permission flags in it’s Characteristics entry. These flags can be one or a combination of

IMAGE_SCN_MEM_EXECUTE
The section contains data that can be executed.
IMAGE_SCN_MEM_READ
The section contains data that is readable.
IMAGE_SCN_MEM_WRITE
The section contains data that is writeable.

These flags must get mapped to the protection flags

  • PAGE_NOACCESS
  • PAGE_WRITECOPY
  • PAGE_READONLY
  • PAGE_READWRITE
  • PAGE_EXECUTE
  • PAGE_EXECUTE_WRITECOPY
  • PAGE_EXECUTE_READ
  • PAGE_EXECUTE_READWRITE

Now, the function VirtualProtect can be used to limit access to the memory. If the program tries to access it in a unauthorized way, an exception gets raised by Windows.

In addition the section flags above, the following can be added:

IMAGE_SCN_MEM_DISCARDABLE
The data in this section can be freed after the import. Usually this is specified for relocation data.
IMAGE_SCN_MEM_NOT_CACHED
The data in this section must not get cached by Windows. Add the bit flag PAGE_NOCACHE to the protection flags above.

Notify library

The last thing to do is to call the DLL entry point (defined by AddressOfEntryPoint) and so notifying the library about being attached to a process.

The function at the entry point is defined as

typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);

So the last code we need to execute is

DllEntryProc entry = (DllEntryProc)(baseAddress + PEHeader->OptionalHeader.AddressOfEntryPoint);
(*entry)((HINSTANCE)baseAddress, DLL_PROCESS_ATTACH, 0);

Afterwards we can use the exported functions as with any normal library.

Exported functions

If you want to access the functions that are exported by the library, you need to find the entry point to a symbol, i.e. the name of the function to call.

The directory entry 0 of the DataDirectory in the OptionalHeader contains informations about the exported functions. It’s defined as follows:

typedef struct _IMAGE_EXPORT_DIRECTORY {
    DWORD   Characteristics;
    DWORD   TimeDateStamp;
    WORD    MajorVersion;
    WORD    MinorVersion;
    DWORD   Name;
    DWORD   Base;
    DWORD   NumberOfFunctions;
    DWORD   NumberOfNames;
    DWORD   AddressOfFunctions;     // RVA from base of image
    DWORD   AddressOfNames;         // RVA from base of image
    DWORD   AddressOfNameOrdinals;  // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

First thing to do, is to map the name of the function to the ordinal number of the exported symbol. Therefore, just walk the arrays defined by AddressOfNames and AddressOfNameOrdinals parallel until you found the required name.

Now you can use the ordinal number to read the address by evaluating the n-th element of the AddressOfFunctions array.

Freeing the library

To free the custom loaded library, perform the steps

  • Call entry point to notify library about being detached:
    DllEntryProc entry = (DllEntryProc)(baseAddress + PEHeader->OptionalHeader.AddressOfEntryPoint);
    (*entry)((HINSTANCE)baseAddress, DLL_PROCESS_ATTACH, 0);
  • Free external libraries used to resolve imports.
  • Free allocated memory.

MemoryModule

MemoryModule is a C-library that can be used to load a DLL from memory.

The interface is very similar to the standard methods for loading of libraries:

typedef void *HMEMORYMODULE;

HMEMORYMODULE MemoryLoadLibrary(const void *);
FARPROC MemoryGetProcAddress(HMEMORYMODULE, const char *);
void MemoryFreeLibrary(HMEMORYMODULE);

Downloads

The latest development release can always be grabbed from Github at http://github.com/fancycode/MemoryModule

All tagged versions can be downloaded from GitHub.

Known issues

  • All memory that is not protected by section flags is gets committed using PAGE_READWRITE. I don’t know if this is correct.

License

Since version 0.0.2, the MemoryModule library is released under the Mozilla Public License (MPL). Version 0.0.1 has been released unter the Lesser General Public License (LGPL).

It is provided as-is without ANY warranty. You may use it at your own risk.

Ports

Thomas Heller added MemoryModule to py2exe to create single file executables from Python scripts.

Martin Offenwanger did a port to Delphi which is available on this page.

Wednesday, April 7th, 2010 80 Comments

80 Comments to Loading a DLL from memory

  • […] version would never exist on the disk. I found something that does almost exactly what I want at http://www.joachim-bauch.de/tutorial…l-from-memory/ But it only works using FILE classes and is rather stick with winapi, not to mention it throws an […]

  • […] Reverse Engineering, reverse code engineering Leave a Comment  While I was trying the code by Joachim Bauch I noticed a strange behaviour loading user32.dll. The test program I’m using […]

  • Protean says:

    Nice library!
    Maybe it will be better in function BuildImportTable replace LoadLibrary with LoadLibraryA.
    In project with default UNICODE support it makes error during BuildImportTable.
    Best regards!

  • liht215 says:

    Hello, i test your code, it’s very nice, but it doesn’t support MFC, if i want make it support MFC, how can i do? please email me, thank you!

  • wat says:

    you do not maintain PEB_LDR_DATA *modulelist members

    also, use memorymapping with SEC_IMAGE flag like the loader does, instead of allocating everything yourself

    can it also load and run exe?

  • china says:

    Can’t find the downloads address.

  • merlin_de says:

    hi,
    i try your code do load a dll from a resource.

    BuildImportTable(PMEMORYMODULE module)
    {
    ….
    FARPROC *funcRef;
    HMODULE handle = LoadLibrary((LPCSTR) (codeBase + importDesc->Name));

    i commpile with _UNICOODE LoadLibrary use LoadLibraryW and get a compile error.
    does you mean LoadLibraryA, or is your whole code only design without unicode support?

    i ask coz i always get a crash (exeption) at
    // notify library about attaching to process
    successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0);

    DllEntry 0x11062036 int (HINSTANCE__ *, unsigned long, void *)*

    code 0x11000000 “MZ” unsigned char *
    error 0x0123efac error void *
    dos_header 0x01261660 {e_magic=0x5a4d e_cblp=0x0090 e_cp=0x0003 …} _IMAGE_DOS_HEADER *

    my code for loading from rc is:

    HMEMORYMODULE ResourceLoadLibrary (HMODULE hInst, int rcID) {
    HRSRC hrsrc;
    DWORD cb;
    HGLOBAL hRes;
    // BYTE* dataRes;
    LPVOID dataRes;

    /* load dll data resources */
    hrsrc=FindResource(hInst,MAKEINTRESOURCE(rcID),_T(“DLL”));
    cb=SizeofResource(hInst,hrsrc);
    hRes = LoadResource(hInst,hrsrc);

    dataRes=LockResource(hRes);
    if(cb<=sizeof(DWORD) || dataRes==NULL) {
    UnlockResource(dataRes);
    FreeResource(hRes);
    return 0;
    }
    /* Load lib from mem */
    HMEMORYMODULE result = MemoryLoadLibrary(dataRes);
    UnlockResource(dataRes);
    FreeResource(hRes);
    return result;
    }

    • merlin_de says:

      hi, i find the bug.
      FinalizeSections(..) DECOMMIT (freed) on IMAGE_SCN_MEM_DISCARDABLE.

      thats the bug. IMAGE_SCN_MEM_DISCARDABLE flag has nothing to do with mem allocation for the image !! the wole image must always commit and NEVER has holes inside !!!

      in my dll the section that include the dllmain entry and the common dll code has IMAGE_SCN_MEM_DISCARDABLE flag on the section.

      the FinalizeSections(..) is realy nonsense by this way. the sections flags mostly has nothing to do with the VirtualProtect flags.

      if we alloc by this way at the beginning of MemoryLoadLibrary(..)
      VirtualAlloc(code,
      old_header->OptionalHeader.SizeOfImage,
      MEM_COMMIT,
      PAGE_EXECUTE_READWRITE);

      we dont need to change the security anny more and we dont need to VirtualAlloc anny more.

      this is not exact what LoadLibrary do during the mapping of the image coz the mapping use SEC_IMAGE flag, but this works for common.

      it is unposible to do the same coz we copy the data to the image and the image is not a image with SEC_IMAGE flag. set the SEC_IMAGE flag prevent us fom copy data to the image.

      its a security feature from MS that we cant use the SEC_IMAGE flag for CreatNamedSharedMemory by CreateFileMapping with INVALID_HANDLE_VALUE
      CreateFileMapping with SEC_IMAGE always need a valid HANDLE (hfile from CreateFile)

      if the dll we load with MemoryLoadLibrary make some security check during dllEntry like eg bass.dll this dll cant be load by MemoryLoadLibrary

      • SkyDiver says:

        What’s the bottom line?
        I find it hard to compile you explanation.
        Can you please post the updated code or fix it in the GitHub?

  • merlin_de says:

    hi
    it seems that MemoryModule only support static compiled dll’s

    i compile SampleDLL static -> DllLoader works
    i compile SampleDLL dynamic -> DllLoader fail read from mem

    can you fix this problem (support dynamic compiled dll’s)

    • merlin_de says:

      hi, after i debug a little bit, i find the problem (bug)
      BuildImportTable use LoadLibrary(..)

      but LoadLibrary use only the default dll search order for the path to locate the dll.

      if we try to load a dll that was inside eg windows\winsx\…
      like msvcp90d.dll LoadLibrary always fail (if not loadet by the main process prior) coz we need a full path and not only LoadLibrary(“msvcp90d.dll”)

      maybe try to get the full path from the reg?!

      • SkyDiver says:

        Also this one – I bumped into the same problem.
        The code doesn’t seems to be UNICODE-ready.
        Did you find a solution for this?

        • SkyDiver says:

          Found the solution!
          LoadLibrary must always be invoked using the ANSI version – not the UNICODE one.

          So in BuildImportTable, replace:

          LoadLibrary((LPCTSTR) … );

          with:

          LoadLibraryA((const char *) … );

  • John Smith says:

    E2197 Constant object cannot be passed as var parameter in statment:
    BTMemoryLoadLibary(ms.Memory, ms.Size)
    !!!

  • zhuo says:

    I found a bug.
    In API CopySections()
    Line95 ; PAGE_READWRITE Need to changed to : PAGE_EXECUTE_READWRITE.

  • zhuo says:

    It works on the Windows that set the DEP always on?

  • zzptichka says:

    Hi,
    When trying to implement this for MFC project I’m getting “_pActualRawDllMain cannot be in R/W section” exception after calling function from loaded DLL.
    Can you recommend something?
    Thanks

  • Zuzu Corneliu says:

    Hello Joachim. Your code is invaluable!
    I am actually using it inside my application
    and it works excellent with an exception.
    I will try to go straight to the point and
    be concise. One particular DLL library crashes
    my application when I’m trying to load it from memory.
    I have made an archive with a text document describing
    the problem and the DLL. I am hoping you can investigate the problem.

    Here’s the uploaded archive: http://www.megaupload.com/?d=1SWOVYW2
    Note: the libraries are 32-bit modules and I’m using
    Windows XP SP3 32-bit.

    Thanks in advance, Zozel!

  • Zuzu Corneliu says:

    Hello Joachim. I am back.
    I investigated a bit more the code and
    I found no major issues with it. It should work with
    the above DLL with some CONDITIONS.
    Thinking about the issues that could supervene in loading a DLL from memory made me realize what was the problem. The problem is that the above DLL calls in its entry function the _CRT_INIT function to init the C-Runtime. The call-form of it is _CRT_INIT(hModule, fdwReason, lpReserved) so the problem must certainly be that the function does something with the hModule and doesn’t succeed. This doesn’t happen with LoadLibrary though. I believe LoadLibrary somehow “registers” the DLL somewhere else also – my question is: how come when I load a DLL file with LoadLibrary, it appears in the debugger (using Olly Debugger and others), but loading it from memory doesn’t enable that?
    LoadLibrary must do something else that enables the debugger to “see” the loaded module, and most importantly, it “enables” the CRT_INIT function to see it.
    Can’t we simulate the behaviour of LoadLibrary? What is it that it does in addition to our common registering of the DLL library? How does it make the DLL “public” for every other function?

  • wuthehe says:

    does it handle forwarded imports ?

  • There are some fascinating deadlines in this article however I don’t know if I see all of them center to heart. There’s some validity but I will take maintain opinion till I look into it further. Good article , thanks and we want extra! Added to FeedBurner as well

  • shlomi says:

    hello,
    this a great tutorial, excellent job!!
    could you please recommend some good reading about this topic? either a book or on the web..
    thanks,
    shlomi

  • Gelbaerchen says:

    Hi Joachim,

    thanks for this great piece of code.

    Please let me make two comments:

    – first I had the same Unicode problems as already mentioned, but this could be easily resolved by using LoadLibraryA

    – somehow more tricky was to solve a problem concerning MFC and WinSxS. Now I solved this by explicitly using CreateActCtx() and ActivateActCtx() before I call MemoryLoadLibrary(). The problem is that sometimes the imported dlls cannot be loaded, if the activation context is not set according to the manifest of the dll that should be loaded from memory.

    Perhaps it could be a future improvement to automatically extract the manifest from the memory dll and set the activation context before calling LoadLibrary inside BuildImportTable?

    But still … thanks a lot ;-))

    • Roger says:

      Hi Gelbaerchen,

      How did you solve that problem exactly? The DLL I’m trying to MemoryLoadLibrary() depends on msvcr90.dll and msvcp90.dll. LoadLibrary fails to load these because (i’m assuming) of this manifest issue.

      • Gelbaerchen says:

        Hi Roger,

        first I extracted the manifest from the dll I want to load with some kind of resource extractor and save this to a temporary file. Then ..

        ACTCTX actctx = {sizeof(actctx)};
        ZeroMemory(&actctx, sizeof(actctx));
        actctx.cbSize = sizeof(actctx);
        actctx.lpSource = static_cast(TempFilename);
        HANDLE hActCtx = CreateActCtx( &actctx );
        ULONG_PTR cookie = 0;
        if ( ActivateActCtx( hActCtx, &cookie ) )
        {
        hMemModule = MemoryLoadLibrary( pBuffer );
        DeactivateActCtx( 0, cookie );
        ReleaseActCtx( hActCtx );
        }

        HTH 😉
        Gelbaerchen
        }

  • Fami says:

    Sometimes I can’t use globle variables to store module handle.
    But MemoryLoadLibrary Load the same dll multiply return different module handle.

    GetModuleHandle also can’t get the module handle loded by MemoryLoadLibrary.

  • jingtao says:

    if the 64 bit dll is build from DelphiXE2.the Load’s app would crash.

  • Roger says:

    I get this error…

    Unhandled exception at 0x75f4d36f in DllLoader.exe: Microsoft C++ exception: Debug::Error at memory location 0x001dde5c..

    I’m loading a DLL that seems to depend on QT. This is what gets put to the console before the above runtime error is displayed:

    QFileInfo::absolutePath: Constructed with empty filename

  • Roger says:

    I get this error…

    Unhandled exception at 0x75f4d36f in DllLoader.exe: Microsoft C++ exception: Debug::Error at memory location 0x001dde5c..

    I’m loading a DLL that seems to depend on QT. This is what gets put to the console before the above runtime error is displayed:

    QFileInfo::absolutePath: Constructed with empty filename

  • Roger says:

    Is anyone having issues running a DLL function via MemoryModule that uses SEH (structured exception handling)? For me I get a windows uncaught exception error.

    • Roger II says:

      Please roger if you solve this error write me

    • Niklas Damberg says:

      Yes, i have the same problem! Did you find any solution to it? I’ve made a ticket in the github repository that describes the problem and with a link to another repository that i created that reproduce this issue.

      Im not sure if i made something wrong when using the MemoryModule or if it is a bug.

      Please reply if you found a solution.

      /Niklas

    • A Developer says:

      Yes. It is an issue with the MemoryModule because the kernel checks if the given module is valid by calling RtlIsValidHandler. Exception handling basically does not work at all.

  • Der müde Joe says:

    Hallo Joachim,

    INVALID_HANDLE_VALUE wird nur bei z.B. CreateFile() zurückgegeben.
    LoadLibrary() gibt NULL zurück! (in LoadFromFile).

    Gruß

  • Der müde Joe says:

    #define DLL_FILE “..\\SampleDLL\\SampleDLL.dll”

    müsste bei der derzeitigen Konfiguration:

    #define DLL_FILE “..\\..\\SampleDLL\\Debug\\SampleDLL.dll”

    heißen!

  • […] (LPCSTR)&thunkData->Name); if (*funcRef == 0) { handleImportError(); return; } } Taken From: http://www.joachim-bauch.de/tutorial…l-from-memory/ You might also want to look at: http://win32assembly.online.fr/pe-tut6.html Reply […]

  • Gelbaerchen says:

    Hi Joachim,

    I’d like to load a dll from memory that’s needed later on by another library (which is a ocx control). But this ocx control always loads the original dll and not the one which has been already preloaded from memory. So probably I need a way to define a “filename” for the dll loaded from memory, that is used by the win32 LoadLibrary() to check, whether this dll is already loaded. Is there any chance to do this?

    Thanks and best regards,
    Gelbaerchen

  • Gelbaerchen says:

    Hi,

    meanwhile I succeeded in loading a ocx from memory, but I had to solve some issues, which also partly affected MemoryModule.

    First I ran into a problem as the OCX DLL invokes GetModuleFileName() using the instance handle passed in DllEntry(), which cannot work, as this is not a valid instance handle for the OS.

    Second I always ended in a runtime error R6002 inside the memory loaded DLL, which means, there’s no FPU support loaded. I finally found that the DLL calls _IsNonwritableInCurrentImage() before the FPU initialisation and this didn’t work correct. I ended up inside MemoryModule.c CopySections() where the section structs union member PhysicalAddress is set. On the DLL side this union is interpreted as VirtualSize, which is not correct any more. After removing the lines which set PhysicalAddress the FPU support was loaded correctly. So my question is, whether you know if it’s necessary to set PhysicalAddress or if it’s OK to keep it as VirtualSize?

    Perhaps this is also some kind of help for other developers,
    Gelbaerchen

  • […] Is there another way to load a module other than calling LoadLibrary ? Read DLL from disk and http://www.joachim-bauch.de/tutorial…l-from-memory/ Reply With Quote     + Reply to […]

  • junkykrolik says:

    Hi,
    Did someone solved the problem with MFC
    i get always error “pAcutalRawDllMain cannot be in a R/W section” when i call MemoryLoadLibrary()

  • […] most of the documentation I needed to write this was taken from this wonderful article written by Joachim Bauch: here is reported all the needed information needed to […]

  • Ling says:

    I have several dlls,and one of them is depends on others,how can I load it from memory? I found the BuildImportTable function will fail,because the dlls are not in my harddisk.

  • OBones says:

    Hello,

    Have you ever managed to get this working for x64 dlls being loaded by x64 exe files?
    I modified the port from Martin Offenwangern so that it takes into account what I believe is most of the PE32+ specification but I still get a crash when calling dllmain.
    Basically, I did this:

    – Fixed many declarations to use the portable type names
    – Fixed GetImageSnapByOrdinal so that it uses IMAGE_ORDINAL_FLAG64 under x64
    – Changed CopySection so that it writes real x64 addresses into a fp_module structure
    – Made PerformBaseRelocation support IMAGE_REL_BASED_ABSOLUTE and IMAGE_REL_BASED_DIR64 relocations
    – Changed FinalizeSections so that it calls VirtualProtect on every instance, not just when SizeOfRawData is 0
    – Changed BTMemoryLoadLibary so that the memory delta is a signed number because it does happen that the retrieved memory is before the preferred one.

    If you want I can send you the modified file, but in the end, I still can’t get it to work, it crashes deep inside the DllMain call. I traced the assembler but I could not make much of it.

  • Roger II says:

    A have this error too:

    “Is anyone having issues running a DLL function via MemoryModule that uses SEH (structured exception handling)? For me I get a windows uncaught exception error.”

    Please some help

  • […] From joachim bauch This entry was posted in Uncategorized by xonitor. Bookmark the permalink. […]

  • Dórian C. Langbeck says:

    Line 347 you says:
    “XXX: is it correct to commit the complete memory region at once? calling DllEntry raises an exception if we don’t…”

    You just have use the combination of (MEM_RESERVE | MEM_COMMIT) when you try reserve memory for image of library, and then you dont need anymore call VirtualAlloc after.

    Sorry for my bad english.

  • Nick T says:

    Perfect! Just what I was looking for. However, I found that BuildImportTable() would fail on Windows 7. Changing the LoadLibrary() call within that function to LoadLibraryA() fixes the issue. :-)

  • In
    “Freeing the library” part the DLL_PROCESS_DETACH must have been used instead of DLL_PROCESS_ATTACH I guess.

    Regards,

  • Justin Arndt says:

    I ran into the same MFC issue, is there a workaround for that yet??

  • […] Memory Module – http://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/ Share this:TwitterFacebookLike this:LikeBe the first to like this. This entry was posted in […]

  • Entrada Aviso says:

    Hello alright ..
    Dear friends since ja wanna thank not only more praise this MemoryModule’s great use in everything that I can use very good. I finally just a problem in version 0.0.1 creating the dll in memory using an executable. funcitona EXE perfect but when I try to create a dll from another dll error and dynamic occurs following line (l_successfull: l_DllEntry = (Cardinal (l_code) DLL_PROCESS_ATTACH, nil)) within the function BTMemoryLoadLibary
    execpt and he comes calling BTMemoryFreeLibrary (l_result); … Well that and my problem would be very grateful if you could ever help me …. from already thank you dear friends await response.

  • prazetto says:

    wang rui have been written

    Load library in memory. X86/X64.WIN32/WIN64. Delphi Code.

    http://code.google.com/p/delphi-memory-module/
    http://cc.embarcadero.com/Item/28914

    It’s great because that support x32 and x64 bit

  • […] resources. Application would load this dll straight from memory using techniques from this […]

  • […] I also have run into a few scary solutions as defined here […]

  • Leave a Reply