Giter VIP home page Giter VIP logo

memorymodule's Introduction

MemoryModule

Build StatusBuild status

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.

MemoryModule is a library that can be used to load a DLL completely from memory - without storing on the disk first.

See doc/readme.rst for more informations about the format of a DLL file and a tutorial how they can be loaded directly.

memorymodule's People

Contributors

cooloppo avatar dismantl avatar fancycode avatar fornever avatar fr0st-brutal avatar ianhbell avatar joankaradimov avatar kost avatar sakurai-youhei avatar scavanger avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

memorymodule's Issues

TLS not set correctly

This loader does not support __declspec(thread) variables at all.
Any attempt to access those variables will lead to a crash or memory corruption.
The reason is, that the loader does NOT initialize the implicit tls index (not to be confused with the conventional manual one) at all.
Please read http://www.nynaeve.net/?p=185 for a background on this.
Thanks for your attention.

LoadLibrary

Hi there- great library. One little comment... if the project settings are 'Unicode', it doesn't work because LoadLibraryW is called. Changing the MemoryModule.c 'LoadLibrary' call to 'LoadLibraryA' patches things up, at least on my system (MSVC10 & XP SP3)

Windows 10 wrong calculate reloc addr

Got problem again in windows 10 updated. Here is the code

typedef LONG(NTAPI *tNtProtectVirtualMemory)(
    IN HANDLE ProcessHandle,
    IN OUT PVOID *BaseAddress,
    IN OUT PULONG NumberOfBytesToProtect,
    IN ULONG NewAccessProtection,
    OUT PULONG OldAccessProtection);

tNtProtectVirtualMemory pNtProtectVirtualMemory;

void LoadFromMemory(void)
{
    void *data;
    size_t size;
    HMEMORYMODULE handle;
    addNumberProc addNumber;
    HMEMORYRSRC resourceInfo;
    DWORD resourceSize;
    LPVOID resourceData;
    TCHAR buffer[100];

    data = ReadLibrary(&size);
    if (data == NULL)
    {
        return;
    }

    handle = MemoryLoadLibrary(data, size);
    if (handle == NULL)
    {
        _tprintf(_T("Can't load library from memory.\n"));
        goto exit;
    }

    pNtProtectVirtualMemory = (tNtProtectVirtualMemory)MemoryGetProcAddress(handle, "NtProtectVirtualMemory");
    PVOID pAddr = (PVOID)GetModuleHandleA("Test.exe");
    ULONG pSize = (ULONG)4;
    DWORD Old;
    //pNtProtectVirtualMemory(GetCurrentProcess(), &pAddr, &pSize, PAGE_EXECUTE_READWRITE, &Old); //Crashed

    _tprintf(_T("From memory: %X\n"), pNtProtectVirtualMemory);

    resourceInfo = MemoryFindResource(handle, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
    _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);

    resourceSize = MemorySizeofResource(handle, resourceInfo);
    resourceData = MemoryLoadResource(handle, resourceInfo);
    _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);

    MemoryLoadString(handle, 1, buffer, sizeof(buffer));
    _tprintf(_T("String1: %s\n"), buffer);

    MemoryLoadString(handle, 20, buffer, sizeof(buffer));
    _tprintf(_T("String2: %s\n"), buffer);

    //MemoryFreeLibrary(handle);

exit:
    Sleep(0);
    //free(data);
}

Its load successfully, but when i use

PVOID pAddr = (PVOID)GetModuleHandleA("Test.exe");
ULONG pSize = (ULONG)4;
DWORD Old;

pNtProtectVirtualMemory(GetCurrentProcess(), &pAddr, &pSize, PAGE_EXECUTE_READWRITE, &Old); 

it's crashed. then i check is pNtProtectVirtualMemory address correct, here the result.

SS1 : http://prnt.sc/cmfgbk
SS2 : http://prnt.sc/cmfgeh

The relocation address wrong. it pointed to the null.

Crash when throwing exception inside loaded dll.

When throwing and catching an exception inside the "memory-loaded" dll the application crashes with "Unhandled exception at ...". Even though the appropriate catch is in place.

This is when using Visual Studio 2010. I've created a repository that demonstrates this problem. Hopefully i am the one who has missed something and the memory loading is working as intended.

Link to repo: https://github.com/Niblitlvl50/DLL-crash-when-loading-dll-into-memory

Thank you.

LoadLibrary()

MemoryLibrary.c:250

You make the incorrect assumption that LoadLibrary() returns INVALID_HANDLE_VALUE on failure. It actually returns NULL. INVALID_HANDLE_VALUE is 0xffffffff.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175%28v=vs.85%29.aspx

"If the specified module is a DLL that is not already loaded for the calling process, the system calls the DLL's DllMain function with the DLL_PROCESS_ATTACH value. If DllMain returns TRUE, LoadLibrary returns a handle to the module. If DllMain returns FALSE, the system unloads the DLL from the process address space and LoadLibrary returns NULL. It is not safe to call LoadLibrary from DllMain. For more information, see the Remarks section in DllMain."

Compile UNICODE error/fix

Just a heads up — On line 249 of MemoryModule.c you have the line:

HMODULE handle = LoadLibrary((LPCSTR) (codeBase + importDesc->Name));

If you are compiling for Unicode, this line fails. Unicode define is using LoadLibraryW() which expects a LPCWSTR as the first parameter. Simple fix is to explicitly use LoadLibraryA(), so the line would end up looking like this:

HMODULE handle = LoadLibraryA((LPCSTR) (codeBase + importDesc->Name));

Alternative LoadLibrary for BuildImportTable

Hello,

Thank you for sharing this great library!

To give a background of my question: I have a program which packages (as data) several extensions (extensions). These extensions will be loaded from memory using your library.

Problem is that those extensions depend on the DLL of my program (which is now part of the executable itself) and other DLLs that were bundled in the same package.

Now, I would like to replace LoadLibrary and GetProcAddress with my own versions, which will scan the package and load the bundled DLL or delegate to the original LoadLibrary and GetProcAddress if the DLL is not my program one or one bundled in the package.

Was thinking perhaps an alternate LoadLibrary and GetProcAddress functions can be provided to MemoryLoadLibrary and use those or fall back to system ones.

What you do think? sounds crazy?

Once again, thank you for creating and releasing this library.

cannot load UPX compressed python module

I don't know if it is py2exe specific issue or upstream(MemoryModule) issue so I create an issue here as well.
I found that py2exe cannot load any UPX compressed pyd modules and returns ERROR_DLL_INIT_FAILED (I have python runtime UPX compressed and embed into exe)

forget to mention, the issue happens when bundle_files = 1. (So the pyd DLL and python runtime DLL are both loaded from memory, and pyd DLL depends on python runtime DLL)
With bundle_files = 2, the problem does not exist.

Load SampleDLL.dll

I run the DLLoader on win7 64bits, however, when I see the result of resourceInfo
(resourceInfo = FindResource(handle, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);), It is )0x000000.. What is wrong ?

load user32.dll failed at windows 7 X64(with SP1)

my code:
typedef BOOL (WINAPI* P_EnumWindows)(
In WNDENUMPROC lpEnumFunc,
In LPARAM lParam
);
P_EnumWindows g_pEnumWindows = NULL;

BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
TCHAR lpWinTitle[MAX_PATH] = {0};
::GetWindowText(hWnd,lpWinTitle,MAX_PATH - 1);
return TRUE;
}

void TestReloadUser32(void)
{
FILE *fp;
unsigned char *data=NULL;
size_t size;
HMEMORYMODULE handle;

fp = _tfopen(_T("c:\\windows\\system32\\user32.dll"), _T("rb"));
if (fp == NULL)
{
    _tprintf(_T("Can't open DLL file \"%s\"."), DLL_FILE);
    goto exit;
}

fseek(fp, 0, SEEK_END);
size = ftell(fp);
data = (unsigned char *)malloc(size);
fseek(fp, 0, SEEK_SET);
fread(data, 1, size, fp);
fclose(fp);

handle = MemoryLoadLibrary(data);//!!!failed
if (handle == NULL)
{
    _tprintf(_T("Can't load library from memory.\n"));
    goto exit;
}

//if commented the following code at MemoryLoadLibraryEx (line 441),
//it will crash at g_pEnumWindows(EnumWndProc,NULL) with(0xC0000005)

//ExecuteTLS(result);

//// get entry point of loaded library
//if (result->headers->OptionalHeader.AddressOfEntryPoint != 0) {
//    DllEntry = (DllEntryProc) (code + result->headers->OptionalHeader.AddressOfEntryPoint);
//    // notify library about attaching to process
//    successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0);
//    if (!successfull) {
//        SetLastError(ERROR_DLL_INIT_FAILED);
//        goto error;
//    }
//    result->initialized = 1;
//}
g_pEnumWindows = (P_EnumWindows)MemoryGetProcAddress(handle,"EnumWindows");
if (NULL == g_pEnumWindows)
{
    goto exit;
}
g_pEnumWindows(EnumWndProc,NULL);//here!!

exit:
if (data)
free(data);
}

BuildImportTable fails on localized versions of Windows

For some reason, the BuildImportTable function fails on localized versions of Windows. This has been reported to fail on both Swedish and Italian versions.

Line #280 of memorymodule.c evaluates to true.

if (*funcRef == 0) {
                    result = 0;
                    break;
                }

Perhaps GetProcAddress functions differently on localized versions?

Issue with TLS callbacks if base address differs from 0x400000

I'm not an expert in all this PE stuff so I don't claim to be right

I noticed an issue with TLS callbacks when I was testing ExecuteTLS(). As far as I understood the callback addresses are hardcoded relying on the fact base image address is 0x400000 (at least all the callback pointers in the sample binaries were 0x40xxxx). Thus if base address differs, they become invalid.
But base address seems to change almost always because $400000 location is frequently occupied by the module of the executable itself! So all the modules it loads later occupy completely different addresses. Thus the base address of our memorymodule could have any value and the assumption that it always >= OptionalHeader.ImageBase becomes incorrect.
AFAIU, to fix the issue these changes must be done:

  1. Change locationdelta type to signed as VirtualAlloc(nil, ...) is likely to return the pointer < $400000
  2. Keep original ImageBase value (I'd recommend just not replacing the value of module.headers.OptionalHeader.ImageBase and using module.codeBase instead in FinalizeSection)
  3. In ExecuteTLS adjust all pointers (pointer to 1st callback and the callbacks themselves) as following:
    ptr_reloc = ptr - ImageBase_old + ImageBase_new

Unfortunately I can't provide a patch because I'm developing Delphi translation of your code but I performed these changes and all callback addresses have been determined correctly. For experiments I used this article (I actually have no idea how to create TLS callback so used sample binaries from there). Testing on TLS_Example_1.exe all five callback adresses were equal to the article ones and corrected callback pointers were pointing to memory blocks corresponding the code from the article (55 8BEC 6A 00, etc)

64 bit dll loading.

Will this work with 64 bit dll's.
Basically i am trying to load a 64 bit dll from a 32 bit application.

Dependencies dll

It's working well with single dll. But if "b.dll" depends on "a.dll", “a.dll” is load from memory, it throws an error. How to solve it?
Thank you forkindly reply.

Delay-load dependency support

It currently appears that MemoryModule doesn't support loading modules with delay-loaded dependencies (see here).

Currently the BuildImportTable function fails due to the following handle returning NULL:

HCUSTOMMODULE handle = module->loadLibrary((LPCSTR)(codeBase + importDesc->Name), module->userdata);

This is expected with a delay-loaded module, and should probably be handled appropriately. This was tested with python27.dll, the Python 2.7 release library.

Crash in MemoryLoadLibraryEx(): 0xC0000005: Access violation reading location 0x00000000.

I'm using the latest version of MemoryModule (f02a8e6).

To reproduce, replace SampleDLL.cpp with:

class Callable
{
public:
    virtual int call() { return 0; }
};

Callable * GetCallable()
{
    static Callable callable;
    return &callable;
}

int i = GetCallable()->call();

(this should be valid C++ code as far as I'm aware)

and DllLoader.cpp with:

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <malloc.h>

#include "../../MemoryModule.h"

#define DLL_FILE TEXT("..\\SampleDLL\\SampleDLL.dll")

void LoadFromFile(void)
{
    HINSTANCE handle = LoadLibrary(DLL_FILE);
    if (handle == NULL)
        return;

    FreeLibrary(handle);
}

void LoadFromMemory(void)
{
    FILE *fp;
    unsigned char *data=NULL;
    size_t size;
    HMEMORYMODULE handle;

    fp = _tfopen(DLL_FILE, _T("rb"));
    if (fp == NULL)
    {
        _tprintf(_T("Can't open DLL file \"%s\"."), DLL_FILE);
        goto exit;
    }

    fseek(fp, 0, SEEK_END);
    size = ftell(fp);
    data = (unsigned char *)malloc(size);
    fseek(fp, 0, SEEK_SET);
    fread(data, 1, size, fp);
    fclose(fp);

    handle = MemoryLoadLibrary(data);
    if (handle == NULL)
    {
        _tprintf(_T("Can't load library from memory.\n"));
        goto exit;
    }

    MemoryFreeLibrary(handle);

exit:
    if (data)
        free(data);
}

int main(int argc, char* argv[])
{
    //LoadFromFile();
    LoadFromMemory();
    return 0;
}

If LoadFromFile() is run, the program exits with 0.

However, if LoadFromMemory() is run, it crashes with:

Exception thrown at 0x0008146E in DllLoader.exe: 0xC0000005: Access violation reading location 0x00000000.

Stacktrace:

    0008146e()  Unknown
    [Frames below may be incorrect and/or missing]  
    ucrtbased.dll!__initterm�() Unknown
    00082d41()  Unknown
    00082be9()  Unknown
    00082fbd()  Unknown
    000831df()  Unknown
>   DllLoader.exe!MemoryLoadLibraryEx(const void * data, void * (const char *, void *) * loadLibrary, int (...) * (void *, const char *, void *) * getProcAddress, void (void *, void *) * freeLibrary, void * userdata) Line 560   C
    DllLoader.exe!MemoryLoadLibrary(const void * data) Line 433 C
    DllLoader.exe!LoadFromMemory() Line 42  C++
    DllLoader.exe!main(int argc, char * * argv) Line 60 C++
    DllLoader.exe!invoke_main() Line 74 C++
    DllLoader.exe!__scrt_common_main_seh() Line 264 C++
    DllLoader.exe!__scrt_common_main() Line 309 C++
    DllLoader.exe!mainCRTStartup() Line 17  C++
    kernel32.dll!@BaseThreadInitThunk@12�() Unknown
    ntdll.dll!___RtlUserThreadStart@8�()    Unknown
    ntdll.dll!__RtlUserThreadStart@8�() Unknown

Line 560 in MemoryModule.c:

// notify library about attaching to process
BOOL successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0);

Strangely enough, if both LoadFromLibrary() and LoadFromMemory() are run (and in that order!), there is no crash.

loop forever with the example dll loader

The binary search in _MemorySearchResourceEntry will loop forever if start == 0 and end == 1.

Fix code will like:
// at file MemoryModule.c line 561
while (end > start) {
WORD entryName;
middle = (start + end) >> 1;
entryName = (WORD) entries[middle].Name;
if (check < entryName) {
// _change below line_****
end = (end != middle ? middle : middle - 1);
} else if (check > entryName) {
// _change below line_****
start = (start != middle ? middle : middle + 1);
} else {
result = &entries[middle];
break;
}
}

The block at file MemoryModule.c line 601 should be fixed too.

ALIGN_DOWN produces wrong address on VS 2015 / x64 build

On x64 builds with VS 2015 the ALIGN_DOWN macro produces wrong addresses if the address is larger than 2^32. VS 2015 also produces a warning
MemoryModule.c(247): warning C4319: '~': zero extending 'DWORD' to 'uintptr_t' of greater size
The same applies to ALIGN_VALUE_UP.
A possible solution could be replacing the definition of ALIGN_DOWN and ALIGN_VALUE_UP by

define ALIGN_DOWN(address, alignment) (LPVOID)((uintptr_t)(address) & ~(((uintptr_t)(alignment)) - 1))

define ALIGN_VALUE_UP(value, alignment) (((value) + ((uintptr_t)(alignment)) - 1) & ~(((uintptr_t)(alignment)) - 1))

Could NOT load MFC regular DLL!

in MemoryLoadLibraryEx:
successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0);
will raise exception.
it's caused by below lines in MFC file appinit.cpp of function 'void CWinApp::SetCurrentHandles()':
TCHAR szBuff[_MAX_PATH];
VERIFY(::GetModuleFileName(m_hInstance, szBuff, _MAX_PATH)); --> return false
LPTSTR lpszExt = _tcsrchr(szBuff, '.');
ASSERT(lpszExt != NULL);
ASSERT(*lpszExt == '.');
*lpszExt = 0; // no suffix ---> lpszExt will be a null pointer

it seems that the 'code' variables in
successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0);
is not a valid HMODULE or HINSTANCE value.

any one can give me some advices? thanks!

Error if allocated memory spans over the address 0x100000000 (4GB)

FinalizeSections will fail if the allocated memory spans over the address 0x100000000 (4GB) since the addresses in the IMAGE_SECTION_HEADER are only 32-bit values.
I could fix it by putting the following code after the allocation of the variable "code":

#ifdef _WIN64
// check that memory-block does not span over the 4GB border
if(code < (LPVOID)0x100000000 && code + alignedImageSize >= (LPVOID)0x100000000)
{
auto old_code = code;
code = (unsigned char *)allocMemory(NULL,
alignedImageSize,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE,
userdata);
freeMemory(old_code, 0, MEM_RELEASE, userdata);
if(code == NULL) {
SetLastError(ERROR_OUTOFMEMORY);
return NULL;
}
}
#endif

Load EXE from memory

I don't really know if this is possible, but loading DLLs and then an EXE that depends on those libraries, and running it, would be a nice feature.

undeclared identifier: IMAGE_SIZEOF_BASE_RELOCATION, IMAGE_SIZEOF_BASE_RELOCATION

Hi,
i get the following errors while building current master:
y:\fancycode-memorymodule-d2e86ce\memorymodule.c(179) : error C2065: 'IMAGE_SIZEOF_BASE_RELOCATION' : undeclared identifier
y:\fancycode-memorymodule-d2e86ce\memorymodule.c(180) : error C2065: 'IMAGE_SIZEOF_BASE_RELOCATION' : undeclared identifier

build environment:
Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1

am i missing something?

Loading a C# Dll doesnt initialize CLR

When Loading a C# DLL the call to
the first PEDecoder::CheckNTHeaders in
PEDecoder::CheckFormat in
_CorDllMain(mscoreei.dll)
fails.
I think its one of the calls to PEDecoder::CheckSection. So something is not wrong with the sections?

Also
if (alignedImageSize != ALIGN_VALUE_UP(lastSectionEnd, sysInfo.dwPageSize))
fails because actually old_header->OptionalHeader.SectionAlignment is used for that. I Think atleast. SectionAlignment is 0x2000 and mscoree.dll checked that with a hardcoded 0x2000.

For ref:
https://github.com/dotnet/coreclr/blob/master/src/utilcode/pedecoder.cpp

C# MemoryModule

Hi,

Thanks for awesome project, Is great if ported to C#.

compiler requirements?

I am having issues compiling with this with gcc-4.8

my config line is CC=i586-mingw32-gcc CXX=i586-mingw32-g++ cmake ../

but when i run make I get errs from the src.

MemoryModule.c:112:58: error: ‘uintptr_t’ undeclared (first use in this function)
section->Misc.PhysicalAddress = (DWORD) (uintptr_t) dest;

Debugging

Is there a chance to debug functions which were loaded from memory?
I guess the debugger is not notified about the dynamically loaded module.

Great library!
Thank you 👍

Overwritten LastError

        SetLastError(ERROR_OUTOFMEMORY);
        VirtualFree(code, 0, MEM_RELEASE);

should be

        VirtualFree(code, 0, MEM_RELEASE);
        SetLastError(ERROR_OUTOFMEMORY);

I guess. Otherwise VirtualFree will overwrite LastError code

Remove stdint.h to enable build with VC++ 9.0 (VS2008) if it is unnecessary

If stdint.h in MemoryModule.c is unnecessary, it is nice to remove it to enable build with VC++ 9.0 (VS2008) which is still actively used by Python 2.7.

I'm building and roughly testing MemoryModule with removing the stdint.h and it seems to work without problem on VC++ 9.0, 10.0 and 14.0.

Compilation of MemoryModule (no stdint.h) with VC++ 9.0 32bit
https://ci.appveyor.com/project/sakurai_youhei/pymemorymodule/build/25/job/shv70h2w1pfxbakv#L79

Compilation of MemoryModule (no stdint.h) with VC++ 9.0 64bit
https://ci.appveyor.com/project/sakurai_youhei/pymemorymodule/build/25/job/lac6j3tgcupiruyr#L85

Executing EXE file with arguments

Hi,
first of all great job, this module works really well with all the DLL executables I created.

However I now want to execute EXE executables from memory with arguments. I saw your code is also able to execute EXE files, but I don't know were I should provide the arguments.

Could you tell me the right way to do this ?

License clarification

Hello! First off, I have to say that this repository has been absolutely amazing for me, allowing me to crack a DLL loading nut that has been bedeviling me for many years. It "just works", which is pretty awesome.

That said, I'm preparing to make publicly available a library that uses MemoryModule quite a bit. I had to revamp the ReadLibrary function to remove the macro definition (yuck), to read something like this

    /// Read the binary data from the shared library file as a blob of memory
    /// Taken from MemoryModule, under MPL 2.0 license
    void* ReadLibrary(const std::string &fname, size_t &pSize) {
        ...
    };

The guts of this function are basically what was in ReadLibrary before with some slight modifications to reduce some code smell.

Now my question is this: although I do not make any other modifications to the MemoryModule code other than making this function derived from your function, I'm a bit unclear on the terms of the MPLv2. I plan to make my library open-source (and therefore this function would be open-source too), which should fulfill the requirements of MPLv2, right? If we are unable to open-source the library, how much disclosure of source is required? I am of course fine with providing the source for MemoryModule, even if I can't provide the source for my library. The plan is to cite your work in our documentation as well.

wcsncpy

I'm getting this warning:
warning C4996: 'wcsncpy': This function or variable may be unsafe. Consider using wcsncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Reference counting behavior of LoadLibrary is missing

Maybe I'm just not looking in the right places but it looks like the reference counting is not implemented.

The system maintains a per-process reference count on all loaded modules. Calling LoadLibrary increments the reference count. Calling the FreeLibrary or FreeLibraryAndExitThread function decrements the reference count. The system unloads a module when its reference count reaches zero or when the process terminates (regardless of the reference count).

(from https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx)

I'm not sure how this would work without some more information passed into MemoryLoadLibraryEx but it definitely looks like a big missing piece.

Loading side-by-side assembly dependencies of modules

I recently tried to load a DLL that had a dependency on a Windows Side-by-side assembly, specifically MSVCRT90.DLL. Due to the way that WinSxS assemblies are loaded from the assembly cache by the Windows loader, the LoadLibrary() call for MSVCRT90.DLL in BuildImportTable() returned NULL.

I'm looking into a way this could be resolved, and right now it appears one solution is to extract and parse a DLL's manifest to look for WinSxS dependencies, set the activation context, call LoadLibrary(), then unset the activation context[1][2]. The only problem with that is that you need to write a temporary file to disk in order to set the activation context, which kind of defeats the memory-only purpose of MemoryModule. And I suppose another problem with this solution is that the OS must have the specific version of the WinSxS dependency installed in the assembly cache.

I'll see if I can find another solution, but I just wanted to flag this issue for now.

[1] http://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/comment-page-1/#comment-28901
[2] https://stackoverflow.com/questions/11175430/resolving-pe-sxs-imports-windows

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.