Browse Source

一个内存加载DLL的源码:https://github.com/clcarwin/LoadMemoryDLL

sat23 3 năm trước cách đây
mục cha
commit
a4d9d81d6e
32 tập tin đã thay đổi với 3275 bổ sung0 xóa
  1. 5 0
      DLLInjection/LoadMemoryDLL-master/.gitignore
  2. 41 0
      DLLInjection/LoadMemoryDLL-master/.travis.yml
  3. 2 0
      DLLInjection/LoadMemoryDLL-master/CMakeLists.txt
  4. 373 0
      DLLInjection/LoadMemoryDLL-master/LICENSE.txt
  5. 17 0
      DLLInjection/LoadMemoryDLL-master/Makefile
  6. 974 0
      DLLInjection/LoadMemoryDLL-master/MemoryModule.c
  7. 148 0
      DLLInjection/LoadMemoryDLL-master/MemoryModule.h
  8. 50 0
      DLLInjection/LoadMemoryDLL-master/appveyor.yml
  9. 546 0
      DLLInjection/LoadMemoryDLL-master/doc/readme.rst
  10. 2 0
      DLLInjection/LoadMemoryDLL-master/example/CMakeLists.txt
  11. 2 0
      DLLInjection/LoadMemoryDLL-master/example/DllLoader/.gitignore
  12. 26 0
      DLLInjection/LoadMemoryDLL-master/example/DllLoader/CMakeLists.txt
  13. 115 0
      DLLInjection/LoadMemoryDLL-master/example/DllLoader/DllLoader.cpp
  14. 138 0
      DLLInjection/LoadMemoryDLL-master/example/DllLoader/DllLoader.vcproj
  15. 64 0
      DLLInjection/LoadMemoryDLL-master/example/DllLoader/DllLoaderLoader.cpp
  16. 42 0
      DLLInjection/LoadMemoryDLL-master/example/DllLoader/Makefile
  17. 30 0
      DLLInjection/LoadMemoryDLL-master/example/DllMemory.sln
  18. 17 0
      DLLInjection/LoadMemoryDLL-master/example/Makefile
  19. 3 0
      DLLInjection/LoadMemoryDLL-master/example/SampleDLL/.gitignore
  20. 12 0
      DLLInjection/LoadMemoryDLL-master/example/SampleDLL/CMakeLists.txt
  21. 39 0
      DLLInjection/LoadMemoryDLL-master/example/SampleDLL/Makefile
  22. 10 0
      DLLInjection/LoadMemoryDLL-master/example/SampleDLL/SampleDLL.cpp
  23. 11 0
      DLLInjection/LoadMemoryDLL-master/example/SampleDLL/SampleDLL.h
  24. 34 0
      DLLInjection/LoadMemoryDLL-master/example/SampleDLL/SampleDLL.rc
  25. 137 0
      DLLInjection/LoadMemoryDLL-master/example/SampleDLL/SampleDLL.vcproj
  26. 20 0
      DLLInjection/LoadMemoryDLL-master/readme.md
  27. 233 0
      DLLInjection/LoadMemoryDLL-master/tests/LoadDll.cpp
  28. 81 0
      DLLInjection/LoadMemoryDLL-master/tests/Makefile
  29. 10 0
      DLLInjection/LoadMemoryDLL-master/tests/SampleDLL.cpp
  30. 11 0
      DLLInjection/LoadMemoryDLL-master/tests/SampleDLL.h
  31. 58 0
      DLLInjection/LoadMemoryDLL-master/tests/SampleDLL.rc
  32. 24 0
      DLLInjection/LoadMemoryDLL-master/tests/runtests.sh

+ 5 - 0
DLLInjection/LoadMemoryDLL-master/.gitignore

@@ -0,0 +1,5 @@
+*.o
+*.obj
+*.exe
+tests/*.dll
+tests/*.res

+ 41 - 0
DLLInjection/LoadMemoryDLL-master/.travis.yml

@@ -0,0 +1,41 @@
+sudo: false
+
+env:
+  - PLATFORM=x86_64 WINE=wine64 UNICODE=  CMAKE=
+  - PLATFORM=i686   WINE=wine   UNICODE=  CMAKE=
+  - PLATFORM=x86_64 WINE=wine64 UNICODE=1 CMAKE=
+  - PLATFORM=i686   WINE=wine   UNICODE=1 CMAKE=
+  - PLATFORM=x86_64 WINE=wine64 UNICODE=  CMAKE=1
+  - PLATFORM=i686   WINE=wine   UNICODE=  CMAKE=1
+  - PLATFORM=x86_64 WINE=wine64 UNICODE=1 CMAKE=1
+  - PLATFORM=i686   WINE=wine   UNICODE=1 CMAKE=1
+
+language: cpp
+
+cache:
+  - apt
+  - ccache
+
+addons:
+  apt:
+    packages:
+    - binutils-mingw-w64-i686
+    - binutils-mingw-w64-x86-64
+    - cmake
+    - mingw-w64-dev
+    - g++-mingw-w64-i686
+    - g++-mingw-w64-x86-64
+    - gcc-mingw-w64-i686
+    - gcc-mingw-w64-x86-64
+    - wine
+
+before_script:
+  - if [ ! -z "$CMAKE" ]; then cmake -DPLATFORM=$PLATFORM -D UNICODE=$UNICODE -H. -B.; fi
+
+script:
+  - if [ -z "$CMAKE" ]; then make PLATFORM=$PLATFORM UNICODE=$UNICODE; fi
+  - if [ -z "$CMAKE" ]; then make test PLATFORM=$PLATFORM UNICODE=$UNICODE; fi
+  - if [ ! -z "$CMAKE" ]; then cmake --build .; fi
+  - cd example/DllLoader
+  - WINEPREFIX=`pwd`/$WINE WINEPATH=/usr/lib/gcc/$PLATFORM-w64-mingw32/4.6/ $WINE ./DllLoader.exe
+  - WINEPREFIX=`pwd`/$WINE WINEPATH=/usr/lib/gcc/$PLATFORM-w64-mingw32/4.6/ $WINE ./DllLoaderLoader.exe

+ 2 - 0
DLLInjection/LoadMemoryDLL-master/CMakeLists.txt

@@ -0,0 +1,2 @@
+add_subdirectory (DllLoader)
+add_subdirectory (SampleDLL)

+ 373 - 0
DLLInjection/LoadMemoryDLL-master/LICENSE.txt

@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in 
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.

+ 17 - 0
DLLInjection/LoadMemoryDLL-master/Makefile

@@ -0,0 +1,17 @@
+SUBDIRS = DllLoader SampleDLL
+
+.PHONY: subdirs $(SUBDIRS)
+
+subdirs: $(SUBDIRS)
+
+$(SUBDIRS):
+	$(MAKE) -C $@
+
+CLEANDIRS = $(SUBDIRS:%=clean-%)
+
+clean: $(CLEANDIRS)
+$(CLEANDIRS):
+	$(MAKE) -C $(@:clean-%=%) clean
+
+.PHONY: subdirs $(INSTALLDIRS)
+.PHONY: clean

+ 974 - 0
DLLInjection/LoadMemoryDLL-master/MemoryModule.c

@@ -0,0 +1,974 @@
+/*
+ * Memory DLL loading code
+ * Version 0.0.4
+ *
+ * Copyright (c) 2004-2015 by Joachim Bauch / mail@joachim-bauch.de
+ * http://www.joachim-bauch.de
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is MemoryModule.c
+ *
+ * The Initial Developer of the Original Code is Joachim Bauch.
+ *
+ * Portions created by Joachim Bauch are Copyright (C) 2004-2015
+ * Joachim Bauch. All Rights Reserved.
+ *
+ */
+
+#include <windows.h>
+#include <winnt.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <tchar.h>
+#ifdef DEBUG_OUTPUT
+#include <stdio.h>
+#endif
+
+#if _MSC_VER
+// Disable warning about data -> function pointer conversion
+#pragma warning(disable:4055)
+#endif
+
+#ifndef IMAGE_SIZEOF_BASE_RELOCATION
+// Vista SDKs no longer define IMAGE_SIZEOF_BASE_RELOCATION!?
+#define IMAGE_SIZEOF_BASE_RELOCATION (sizeof(IMAGE_BASE_RELOCATION))
+#endif
+
+#include "MemoryModule.h"
+
+typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
+typedef int (WINAPI *ExeEntryProc)(void);
+
+typedef struct {
+    PIMAGE_NT_HEADERS headers;
+    unsigned char *codeBase;
+    HCUSTOMMODULE *modules;
+    int numModules;
+    BOOL initialized;
+    BOOL isDLL;
+    BOOL isRelocated;
+    CustomLoadLibraryFunc loadLibrary;
+    CustomGetProcAddressFunc getProcAddress;
+    CustomFreeLibraryFunc freeLibrary;
+    void *userdata;
+    ExeEntryProc exeEntry;
+    DWORD pageSize;
+} MEMORYMODULE, *PMEMORYMODULE;
+
+typedef struct {
+    LPVOID address;
+    LPVOID alignedAddress;
+    DWORD size;
+    DWORD characteristics;
+    BOOL last;
+} SECTIONFINALIZEDATA, *PSECTIONFINALIZEDATA;
+
+#define GET_HEADER_DICTIONARY(module, idx)  &(module)->headers->OptionalHeader.DataDirectory[idx]
+#define ALIGN_DOWN(address, alignment)      (LPVOID)((uintptr_t)(address) & ~((alignment) - 1))
+#define ALIGN_VALUE_UP(value, alignment)    (((value) + (alignment) - 1) & ~((alignment) - 1))
+
+#ifdef DEBUG_OUTPUT
+static void
+OutputLastError(const char *msg)
+{
+    LPVOID tmp;
+    char *tmpmsg;
+    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+        NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&tmp, 0, NULL);
+    tmpmsg = (char *)LocalAlloc(LPTR, strlen(msg) + strlen(tmp) + 3);
+    sprintf(tmpmsg, "%s: %s", msg, tmp);
+    OutputDebugString(tmpmsg);
+    LocalFree(tmpmsg);
+    LocalFree(tmp);
+}
+#endif
+
+static BOOL
+CheckSize(size_t size, size_t expected) {
+    if (size < expected) {
+        SetLastError(ERROR_INVALID_DATA);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static BOOL
+CopySections(const unsigned char *data, size_t size, PIMAGE_NT_HEADERS old_headers, PMEMORYMODULE module)
+{
+    int i, section_size;
+    unsigned char *codeBase = module->codeBase;
+    unsigned char *dest;
+    PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
+    for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++) {
+        if (section->SizeOfRawData == 0) {
+            // section doesn't contain data in the dll itself, but may define
+            // uninitialized data
+            section_size = old_headers->OptionalHeader.SectionAlignment;
+            if (section_size > 0) {
+                dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
+                    section_size,
+                    MEM_COMMIT,
+                    PAGE_READWRITE);
+                if (dest == NULL) {
+                    return FALSE;
+                }
+
+                // Always use position from file to support alignments smaller
+                // than page size.
+                dest = codeBase + section->VirtualAddress;
+                section->Misc.PhysicalAddress = (DWORD) (uintptr_t) dest;
+                memset(dest, 0, section_size);
+            }
+
+            // section is empty
+            continue;
+        }
+
+        if (!CheckSize(size, section->PointerToRawData + section->SizeOfRawData)) {
+            return FALSE;
+        }
+
+        // commit memory block and copy data from dll
+        dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
+                            section->SizeOfRawData,
+                            MEM_COMMIT,
+                            PAGE_READWRITE);
+        if (dest == NULL) {
+            return FALSE;
+        }
+
+        // Always use position from file to support alignments smaller
+        // than page size.
+        dest = codeBase + section->VirtualAddress;
+        memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData);
+        section->Misc.PhysicalAddress = (DWORD) (uintptr_t) dest;
+    }
+
+    return TRUE;
+}
+
+// Protection flags for memory pages (Executable, Readable, Writeable)
+static int ProtectionFlags[2][2][2] = {
+    {
+        // not executable
+        {PAGE_NOACCESS, PAGE_WRITECOPY},
+        {PAGE_READONLY, PAGE_READWRITE},
+    }, {
+        // executable
+        {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY},
+        {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE},
+    },
+};
+
+static DWORD
+GetRealSectionSize(PMEMORYMODULE module, PIMAGE_SECTION_HEADER section) {
+    DWORD size = section->SizeOfRawData;
+    if (size == 0) {
+        if (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) {
+            size = module->headers->OptionalHeader.SizeOfInitializedData;
+        } else if (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
+            size = module->headers->OptionalHeader.SizeOfUninitializedData;
+        }
+    }
+    return size;
+}
+
+static BOOL
+FinalizeSection(PMEMORYMODULE module, PSECTIONFINALIZEDATA sectionData) {
+    DWORD protect, oldProtect;
+    BOOL executable;
+    BOOL readable;
+    BOOL writeable;
+
+    if (sectionData->size == 0) {
+        return TRUE;
+    }
+
+    if (sectionData->characteristics & IMAGE_SCN_MEM_DISCARDABLE) {
+        // section is not needed any more and can safely be freed
+        if (sectionData->address == sectionData->alignedAddress &&
+            (sectionData->last ||
+             module->headers->OptionalHeader.SectionAlignment == module->pageSize ||
+             (sectionData->size % module->pageSize) == 0)
+           ) {
+            // Only allowed to decommit whole pages
+            VirtualFree(sectionData->address, sectionData->size, MEM_DECOMMIT);
+        }
+        return TRUE;
+    }
+
+    // determine protection flags based on characteristics
+    executable = (sectionData->characteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
+    readable =   (sectionData->characteristics & IMAGE_SCN_MEM_READ) != 0;
+    writeable =  (sectionData->characteristics & IMAGE_SCN_MEM_WRITE) != 0;
+    protect = ProtectionFlags[executable][readable][writeable];
+    if (sectionData->characteristics & IMAGE_SCN_MEM_NOT_CACHED) {
+        protect |= PAGE_NOCACHE;
+    }
+
+    // change memory access flags
+    if (VirtualProtect(sectionData->address, sectionData->size, protect, &oldProtect) == 0) {
+#ifdef DEBUG_OUTPUT
+        OutputLastError("Error protecting memory page")
+#endif
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static BOOL
+FinalizeSections(PMEMORYMODULE module)
+{
+    int i;
+    PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
+#ifdef _WIN64
+    uintptr_t imageOffset = (module->headers->OptionalHeader.ImageBase & 0xffffffff00000000);
+#else
+    #define imageOffset 0
+#endif
+    SECTIONFINALIZEDATA sectionData;
+    sectionData.address = (LPVOID)((uintptr_t)section->Misc.PhysicalAddress | imageOffset);
+    sectionData.alignedAddress = ALIGN_DOWN(sectionData.address, module->pageSize);
+    sectionData.size = GetRealSectionSize(module, section);
+    sectionData.characteristics = section->Characteristics;
+    sectionData.last = FALSE;
+    section++;
+
+    // loop through all sections and change access flags
+    for (i=1; i<module->headers->FileHeader.NumberOfSections; i++, section++) {
+        LPVOID sectionAddress = (LPVOID)((uintptr_t)section->Misc.PhysicalAddress | imageOffset);
+        LPVOID alignedAddress = ALIGN_DOWN(sectionAddress, module->pageSize);
+        DWORD sectionSize = GetRealSectionSize(module, section);
+        // Combine access flags of all sections that share a page
+        // TODO(fancycode): We currently share flags of a trailing large section
+        //   with the page of a first small section. This should be optimized.
+        if (sectionData.alignedAddress == alignedAddress || (uintptr_t) sectionData.address + sectionData.size > (uintptr_t) alignedAddress) {
+            // Section shares page with previous
+            if ((section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0 || (sectionData.characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0) {
+                sectionData.characteristics = (sectionData.characteristics | section->Characteristics) & ~IMAGE_SCN_MEM_DISCARDABLE;
+            } else {
+                sectionData.characteristics |= section->Characteristics;
+            }
+            sectionData.size = (((uintptr_t)sectionAddress) + sectionSize) - (uintptr_t) sectionData.address;
+            continue;
+        }
+
+        if (!FinalizeSection(module, &sectionData)) {
+            return FALSE;
+        }
+        sectionData.address = sectionAddress;
+        sectionData.alignedAddress = alignedAddress;
+        sectionData.size = sectionSize;
+        sectionData.characteristics = section->Characteristics;
+    }
+    sectionData.last = TRUE;
+    if (!FinalizeSection(module, &sectionData)) {
+        return FALSE;
+    }
+#ifndef _WIN64
+#undef imageOffset
+#endif
+    return TRUE;
+}
+
+static BOOL
+ExecuteTLS(PMEMORYMODULE module)
+{
+    unsigned char *codeBase = module->codeBase;
+    PIMAGE_TLS_DIRECTORY tls;
+    PIMAGE_TLS_CALLBACK* callback;
+
+    PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_TLS);
+    if (directory->VirtualAddress == 0) {
+        return TRUE;
+    }
+
+    tls = (PIMAGE_TLS_DIRECTORY) (codeBase + directory->VirtualAddress);
+    callback = (PIMAGE_TLS_CALLBACK *) tls->AddressOfCallBacks;
+    if (callback) {
+        while (*callback) {
+            (*callback)((LPVOID) codeBase, DLL_PROCESS_ATTACH, NULL);
+            callback++;
+        }
+    }
+    return TRUE;
+}
+
+static BOOL
+PerformBaseRelocation(PMEMORYMODULE module, ptrdiff_t delta)
+{
+    unsigned char *codeBase = module->codeBase;
+    PIMAGE_BASE_RELOCATION relocation;
+
+    PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC);
+    if (directory->Size == 0) {
+        return (delta == 0);
+    }
+
+    relocation = (PIMAGE_BASE_RELOCATION) (codeBase + directory->VirtualAddress);
+    for (; relocation->VirtualAddress > 0; ) {
+        DWORD i;
+        unsigned char *dest = codeBase + relocation->VirtualAddress;
+        unsigned short *relInfo = (unsigned short *)((unsigned char *)relocation + IMAGE_SIZEOF_BASE_RELOCATION);
+        for (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++) {
+            DWORD *patchAddrHL;
+#ifdef _WIN64
+            ULONGLONG *patchAddr64;
+#endif
+            int type, offset;
+
+            // the upper 4 bits define the type of relocation
+            type = *relInfo >> 12;
+            // the lower 12 bits define the offset
+            offset = *relInfo & 0xfff;
+
+            switch (type)
+            {
+            case IMAGE_REL_BASED_ABSOLUTE:
+                // skip relocation
+                break;
+
+            case IMAGE_REL_BASED_HIGHLOW:
+                // change complete 32 bit address
+                patchAddrHL = (DWORD *) (dest + offset);
+                *patchAddrHL += (DWORD) delta;
+                break;
+
+#ifdef _WIN64
+            case IMAGE_REL_BASED_DIR64:
+                patchAddr64 = (ULONGLONG *) (dest + offset);
+                *patchAddr64 += (ULONGLONG) delta;
+                break;
+#endif
+
+            default:
+                //printf("Unknown relocation: %d\n", type);
+                break;
+            }
+        }
+
+        // advance to next relocation block
+        relocation = (PIMAGE_BASE_RELOCATION) (((char *) relocation) + relocation->SizeOfBlock);
+    }
+    return TRUE;
+}
+
+static BOOL
+BuildImportTable(PMEMORYMODULE module)
+{
+    unsigned char *codeBase = module->codeBase;
+    PIMAGE_IMPORT_DESCRIPTOR importDesc;
+    BOOL result = TRUE;
+
+    PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT);
+    if (directory->Size == 0) {
+        return TRUE;
+    }
+
+    importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (codeBase + directory->VirtualAddress);
+    for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) {
+        uintptr_t *thunkRef;
+        FARPROC *funcRef;
+        HCUSTOMMODULE *tmp;
+        HCUSTOMMODULE handle = module->loadLibrary((LPCSTR) (codeBase + importDesc->Name), module->userdata);
+        if (handle == NULL) {
+            SetLastError(ERROR_MOD_NOT_FOUND);
+            result = FALSE;
+            break;
+        }
+
+        tmp = (HCUSTOMMODULE *) realloc(module->modules, (module->numModules+1)*(sizeof(HCUSTOMMODULE)));
+        if (tmp == NULL) {
+            module->freeLibrary(handle, module->userdata);
+            SetLastError(ERROR_OUTOFMEMORY);
+            result = FALSE;
+            break;
+        }
+        module->modules = tmp;
+
+        module->modules[module->numModules++] = handle;
+        if (importDesc->OriginalFirstThunk) {
+            thunkRef = (uintptr_t *) (codeBase + importDesc->OriginalFirstThunk);
+            funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk);
+        } else {
+            // no hint table
+            thunkRef = (uintptr_t *) (codeBase + importDesc->FirstThunk);
+            funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk);
+        }
+        for (; *thunkRef; thunkRef++, funcRef++) {
+            if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) {
+                *funcRef = module->getProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef), module->userdata);
+            } else {
+                PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME) (codeBase + (*thunkRef));
+                *funcRef = module->getProcAddress(handle, (LPCSTR)&thunkData->Name, module->userdata);
+            }
+            if (*funcRef == 0) {
+                result = FALSE;
+                break;
+            }
+        }
+
+        if (!result) {
+            module->freeLibrary(handle, module->userdata);
+            SetLastError(ERROR_PROC_NOT_FOUND);
+            break;
+        }
+    }
+
+    return result;
+}
+
+HCUSTOMMODULE MemoryDefaultLoadLibrary(LPCSTR filename, void *userdata)
+{
+    HMODULE result;
+    UNREFERENCED_PARAMETER(userdata);
+    result = LoadLibraryA(filename);
+    if (result == NULL) {
+        return NULL;
+    }
+
+    return (HCUSTOMMODULE) result;
+}
+
+FARPROC MemoryDefaultGetProcAddress(HCUSTOMMODULE module, LPCSTR name, void *userdata)
+{
+    UNREFERENCED_PARAMETER(userdata);
+    return (FARPROC) GetProcAddress((HMODULE) module, name);
+}
+
+void MemoryDefaultFreeLibrary(HCUSTOMMODULE module, void *userdata)
+{
+    UNREFERENCED_PARAMETER(userdata);
+    FreeLibrary((HMODULE) module);
+}
+
+HMEMORYMODULE MemoryLoadLibrary(const void *data, size_t size)
+{
+    return MemoryLoadLibraryEx(data, size, MemoryDefaultLoadLibrary, MemoryDefaultGetProcAddress, MemoryDefaultFreeLibrary, NULL);
+}
+
+HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
+    CustomLoadLibraryFunc loadLibrary,
+    CustomGetProcAddressFunc getProcAddress,
+    CustomFreeLibraryFunc freeLibrary,
+    void *userdata)
+{
+    PMEMORYMODULE result = NULL;
+    PIMAGE_DOS_HEADER dos_header;
+    PIMAGE_NT_HEADERS old_header;
+    unsigned char *code, *headers;
+    ptrdiff_t locationDelta;
+    SYSTEM_INFO sysInfo;
+    PIMAGE_SECTION_HEADER section;
+    DWORD i;
+    size_t optionalSectionSize;
+    size_t lastSectionEnd = 0;
+    size_t alignedImageSize;
+
+    if (!CheckSize(size, sizeof(IMAGE_DOS_HEADER))) {
+        return NULL;
+    }
+    dos_header = (PIMAGE_DOS_HEADER)data;
+    if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
+        SetLastError(ERROR_BAD_EXE_FORMAT);
+        return NULL;
+    }
+
+    if (!CheckSize(size, dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS))) {
+        return NULL;
+    }
+    old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(data))[dos_header->e_lfanew];
+    if (old_header->Signature != IMAGE_NT_SIGNATURE) {
+        SetLastError(ERROR_BAD_EXE_FORMAT);
+        return NULL;
+    }
+
+#ifdef _WIN64
+    if (old_header->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) {
+#else
+    if (old_header->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) {
+#endif
+        SetLastError(ERROR_BAD_EXE_FORMAT);
+        return NULL;
+    }
+
+    if (old_header->OptionalHeader.SectionAlignment & 1) {
+        // Only support section alignments that are a multiple of 2
+        SetLastError(ERROR_BAD_EXE_FORMAT);
+        return NULL;
+    }
+
+    section = IMAGE_FIRST_SECTION(old_header);
+    optionalSectionSize = old_header->OptionalHeader.SectionAlignment;
+    for (i=0; i<old_header->FileHeader.NumberOfSections; i++, section++) {
+        size_t endOfSection;
+        if (section->SizeOfRawData == 0) {
+            // Section without data in the DLL
+            endOfSection = section->VirtualAddress + optionalSectionSize;
+        } else {
+            endOfSection = section->VirtualAddress + section->SizeOfRawData;
+        }
+
+        if (endOfSection > lastSectionEnd) {
+            lastSectionEnd = endOfSection;
+        }
+    }
+
+    GetNativeSystemInfo(&sysInfo);
+    alignedImageSize = ALIGN_VALUE_UP(old_header->OptionalHeader.SizeOfImage, sysInfo.dwPageSize);
+    if (alignedImageSize != ALIGN_VALUE_UP(lastSectionEnd, sysInfo.dwPageSize)) {
+        SetLastError(ERROR_BAD_EXE_FORMAT);
+        return NULL;
+    }
+
+    // reserve memory for image of library
+    // XXX: is it correct to commit the complete memory region at once?
+    //      calling DllEntry raises an exception if we don't...
+    code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase),
+        alignedImageSize,
+        MEM_RESERVE | MEM_COMMIT,
+        PAGE_READWRITE);
+
+    if (code == NULL) {
+        // try to allocate memory at arbitrary position
+        code = (unsigned char *)VirtualAlloc(NULL,
+            alignedImageSize,
+            MEM_RESERVE | MEM_COMMIT,
+            PAGE_READWRITE);
+        if (code == NULL) {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return NULL;
+        }
+    }
+
+    result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MEMORYMODULE));
+    if (result == NULL) {
+        VirtualFree(code, 0, MEM_RELEASE);
+        SetLastError(ERROR_OUTOFMEMORY);
+        return NULL;
+    }
+
+    result->codeBase = code;
+    result->isDLL = (old_header->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0;
+    result->loadLibrary = loadLibrary;
+    result->getProcAddress = getProcAddress;
+    result->freeLibrary = freeLibrary;
+    result->userdata = userdata;
+    result->pageSize = sysInfo.dwPageSize;
+
+    if (!CheckSize(size, old_header->OptionalHeader.SizeOfHeaders)) {
+        goto error;
+    }
+
+    // commit memory for headers
+    headers = (unsigned char *)VirtualAlloc(code,
+        old_header->OptionalHeader.SizeOfHeaders,
+        MEM_COMMIT,
+        PAGE_READWRITE);
+
+    // copy PE header to code
+    memcpy(headers, dos_header, old_header->OptionalHeader.SizeOfHeaders);
+    result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew];
+
+    // update position
+    result->headers->OptionalHeader.ImageBase = (uintptr_t)code;
+
+    // copy sections from DLL file block to new memory location
+    if (!CopySections((const unsigned char *) data, size, old_header, result)) {
+        goto error;
+    }
+
+    // adjust base address of imported data
+    locationDelta = (ptrdiff_t)(result->headers->OptionalHeader.ImageBase - old_header->OptionalHeader.ImageBase);
+    if (locationDelta != 0) {
+        result->isRelocated = PerformBaseRelocation(result, locationDelta);
+    } else {
+        result->isRelocated = TRUE;
+    }
+
+    // load required dlls and adjust function table of imports
+    if (!BuildImportTable(result)) {
+        goto error;
+    }
+
+    // mark memory pages depending on section headers and release
+    // sections that are marked as "discardable"
+    if (!FinalizeSections(result)) {
+        goto error;
+    }
+
+    // TLS callbacks are executed BEFORE the main loading
+    if (!ExecuteTLS(result)) {
+        goto error;
+    }
+
+    // get entry point of loaded library
+    if (result->headers->OptionalHeader.AddressOfEntryPoint != 0) {
+        if (result->isDLL) {
+            DllEntryProc DllEntry = (DllEntryProc)(LPVOID)(code + result->headers->OptionalHeader.AddressOfEntryPoint);
+            // notify library about attaching to process
+            BOOL successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0);
+            if (!successfull) {
+                SetLastError(ERROR_DLL_INIT_FAILED);
+                goto error;
+            }
+            result->initialized = TRUE;
+        } else {
+            result->exeEntry = (ExeEntryProc)(LPVOID)(code + result->headers->OptionalHeader.AddressOfEntryPoint);
+        }
+    } else {
+        result->exeEntry = NULL;
+    }
+
+    return (HMEMORYMODULE)result;
+
+error:
+    // cleanup
+    MemoryFreeLibrary(result);
+    return NULL;
+}
+
+FARPROC MemoryGetProcAddress(HMEMORYMODULE module, LPCSTR name)
+{
+    unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase;
+    DWORD idx = 0;
+    PIMAGE_EXPORT_DIRECTORY exports;
+    PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT);
+    if (directory->Size == 0) {
+        // no export table found
+        SetLastError(ERROR_PROC_NOT_FOUND);
+        return NULL;
+    }
+
+    exports = (PIMAGE_EXPORT_DIRECTORY) (codeBase + directory->VirtualAddress);
+    if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0) {
+        // DLL doesn't export anything
+        SetLastError(ERROR_PROC_NOT_FOUND);
+        return NULL;
+    }
+
+    if (HIWORD(name) == 0) {
+        // load function by ordinal value
+        if (LOWORD(name) < exports->Base) {
+            SetLastError(ERROR_PROC_NOT_FOUND);
+            return NULL;
+        }
+
+        idx = LOWORD(name) - exports->Base;
+    } else {
+        // search function name in list of exported names
+        DWORD i;
+        DWORD *nameRef = (DWORD *) (codeBase + exports->AddressOfNames);
+        WORD *ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals);
+        BOOL found = FALSE;
+        for (i=0; i<exports->NumberOfNames; i++, nameRef++, ordinal++) {
+            if (_stricmp(name, (const char *) (codeBase + (*nameRef))) == 0) {
+                idx = *ordinal;
+                found = TRUE;
+                break;
+            }
+        }
+
+        if (!found) {
+            // exported symbol not found
+            SetLastError(ERROR_PROC_NOT_FOUND);
+            return NULL;
+        }
+    }
+
+    if (idx > exports->NumberOfFunctions) {
+        // name <-> ordinal number don't match
+        SetLastError(ERROR_PROC_NOT_FOUND);
+        return NULL;
+    }
+
+    // AddressOfFunctions contains the RVAs to the "real" functions
+    return (FARPROC)(LPVOID)(codeBase + (*(DWORD *) (codeBase + exports->AddressOfFunctions + (idx*4))));
+}
+
+void MemoryFreeLibrary(HMEMORYMODULE mod)
+{
+    PMEMORYMODULE module = (PMEMORYMODULE)mod;
+
+    if (module == NULL) {
+        return;
+    }
+    if (module->initialized) {
+        // notify library about detaching from process
+        DllEntryProc DllEntry = (DllEntryProc)(LPVOID)(module->codeBase + module->headers->OptionalHeader.AddressOfEntryPoint);
+        (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0);
+    }
+
+    if (module->modules != NULL) {
+        // free previously opened libraries
+        int i;
+        for (i=0; i<module->numModules; i++) {
+            if (module->modules[i] != NULL) {
+                module->freeLibrary(module->modules[i], module->userdata);
+            }
+        }
+
+        free(module->modules);
+    }
+
+    if (module->codeBase != NULL) {
+        // release memory of library
+        VirtualFree(module->codeBase, 0, MEM_RELEASE);
+    }
+
+    HeapFree(GetProcessHeap(), 0, module);
+}
+
+int MemoryCallEntryPoint(HMEMORYMODULE mod)
+{
+    PMEMORYMODULE module = (PMEMORYMODULE)mod;
+
+    if (module == NULL || module->isDLL || module->exeEntry == NULL || !module->isRelocated) {
+        return -1;
+    }
+
+    return module->exeEntry();
+}
+
+#define DEFAULT_LANGUAGE        MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
+
+HMEMORYRSRC MemoryFindResource(HMEMORYMODULE module, LPCTSTR name, LPCTSTR type)
+{
+    return MemoryFindResourceEx(module, name, type, DEFAULT_LANGUAGE);
+}
+
+static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntry(
+    void *root,
+    PIMAGE_RESOURCE_DIRECTORY resources,
+    LPCTSTR key)
+{
+    PIMAGE_RESOURCE_DIRECTORY_ENTRY entries = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (resources + 1);
+    PIMAGE_RESOURCE_DIRECTORY_ENTRY result = NULL;
+    DWORD start;
+    DWORD end;
+    DWORD middle;
+
+    if (!IS_INTRESOURCE(key) && key[0] == TEXT('#')) {
+        // special case: resource id given as string
+        TCHAR *endpos = NULL;
+        long int tmpkey = (WORD) _tcstol((TCHAR *) &key[1], &endpos, 10);
+        if (tmpkey <= 0xffff && lstrlen(endpos) == 0) {
+            key = MAKEINTRESOURCE(tmpkey);
+        }
+    }
+
+    // entries are stored as ordered list of named entries,
+    // followed by an ordered list of id entries - we can do
+    // a binary search to find faster...
+    if (IS_INTRESOURCE(key)) {
+        WORD check = (WORD) (uintptr_t) key;
+        start = resources->NumberOfNamedEntries;
+        end = start + resources->NumberOfIdEntries;
+
+        while (end > start) {
+            WORD entryName;
+            middle = (start + end) >> 1;
+            entryName = (WORD) entries[middle].Name;
+            if (check < entryName) {
+                end = (end != middle ? middle : middle-1);
+            } else if (check > entryName) {
+                start = (start != middle ? middle : middle+1);
+            } else {
+                result = &entries[middle];
+                break;
+            }
+        }
+    } else {
+        LPCWSTR searchKey;
+        size_t searchKeyLen = _tcslen(key);
+#if defined(UNICODE)
+        searchKey = key;
+#else
+        // Resource names are always stored using 16bit characters, need to
+        // convert string we search for.
+#define MAX_LOCAL_KEY_LENGTH 2048
+        // In most cases resource names are short, so optimize for that by
+        // using a pre-allocated array.
+        wchar_t _searchKeySpace[MAX_LOCAL_KEY_LENGTH+1];
+        LPWSTR _searchKey;
+        if (searchKeyLen > MAX_LOCAL_KEY_LENGTH) {
+            size_t _searchKeySize = (searchKeyLen + 1) * sizeof(wchar_t);
+            _searchKey = (LPWSTR) malloc(_searchKeySize);
+            if (_searchKey == NULL) {
+                SetLastError(ERROR_OUTOFMEMORY);
+                return NULL;
+            }
+        } else {
+            _searchKey = &_searchKeySpace[0];
+        }
+
+        mbstowcs(_searchKey, key, searchKeyLen);
+        _searchKey[searchKeyLen] = 0;
+        searchKey = _searchKey;
+#endif
+        start = 0;
+        end = resources->NumberOfNamedEntries;
+        while (end > start) {
+            int cmp;
+            PIMAGE_RESOURCE_DIR_STRING_U resourceString;
+            middle = (start + end) >> 1;
+            resourceString = (PIMAGE_RESOURCE_DIR_STRING_U) (((char *) root) + (entries[middle].Name & 0x7FFFFFFF));
+            cmp = _wcsnicmp(searchKey, resourceString->NameString, resourceString->Length);
+            if (cmp == 0) {
+                // Handle partial match
+                cmp = searchKeyLen - resourceString->Length;
+            }
+            if (cmp < 0) {
+                end = (middle != end ? middle : middle-1);
+            } else if (cmp > 0) {
+                start = (middle != start ? middle : middle+1);
+            } else {
+                result = &entries[middle];
+                break;
+            }
+        }
+#if !defined(UNICODE)
+        if (searchKeyLen > MAX_LOCAL_KEY_LENGTH) {
+            free(_searchKey);
+        }
+#undef MAX_LOCAL_KEY_LENGTH
+#endif
+    }
+
+    return result;
+}
+
+HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE module, LPCTSTR name, LPCTSTR type, WORD language)
+{
+    unsigned char *codeBase = ((PMEMORYMODULE) module)->codeBase;
+    PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE) module, IMAGE_DIRECTORY_ENTRY_RESOURCE);
+    PIMAGE_RESOURCE_DIRECTORY rootResources;
+    PIMAGE_RESOURCE_DIRECTORY nameResources;
+    PIMAGE_RESOURCE_DIRECTORY typeResources;
+    PIMAGE_RESOURCE_DIRECTORY_ENTRY foundType;
+    PIMAGE_RESOURCE_DIRECTORY_ENTRY foundName;
+    PIMAGE_RESOURCE_DIRECTORY_ENTRY foundLanguage;
+    if (directory->Size == 0) {
+        // no resource table found
+        SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+        return NULL;
+    }
+
+    if (language == DEFAULT_LANGUAGE) {
+        // use language from current thread
+        language = LANGIDFROMLCID(GetThreadLocale());
+    }
+
+    // resources are stored as three-level tree
+    // - first node is the type
+    // - second node is the name
+    // - third node is the language
+    rootResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress);
+    foundType = _MemorySearchResourceEntry(rootResources, rootResources, type);
+    if (foundType == NULL) {
+        SetLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
+        return NULL;
+    }
+
+    typeResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress + (foundType->OffsetToData & 0x7fffffff));
+    foundName = _MemorySearchResourceEntry(rootResources, typeResources, name);
+    if (foundName == NULL) {
+        SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
+        return NULL;
+    }
+
+    nameResources = (PIMAGE_RESOURCE_DIRECTORY) (codeBase + directory->VirtualAddress + (foundName->OffsetToData & 0x7fffffff));
+    foundLanguage = _MemorySearchResourceEntry(rootResources, nameResources, (LPCTSTR) (uintptr_t) language);
+    if (foundLanguage == NULL) {
+        // requested language not found, use first available
+        if (nameResources->NumberOfIdEntries == 0) {
+            SetLastError(ERROR_RESOURCE_LANG_NOT_FOUND);
+            return NULL;
+        }
+
+        foundLanguage = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (nameResources + 1);
+    }
+
+    return (codeBase + directory->VirtualAddress + (foundLanguage->OffsetToData & 0x7fffffff));
+}
+
+DWORD MemorySizeofResource(HMEMORYMODULE module, HMEMORYRSRC resource)
+{
+    PIMAGE_RESOURCE_DATA_ENTRY entry;
+    UNREFERENCED_PARAMETER(module);
+    entry = (PIMAGE_RESOURCE_DATA_ENTRY) resource;
+    if (entry == NULL) {
+        return 0;
+    }
+
+    return entry->Size;
+}
+
+LPVOID MemoryLoadResource(HMEMORYMODULE module, HMEMORYRSRC resource)
+{
+    unsigned char *codeBase = ((PMEMORYMODULE) module)->codeBase;
+    PIMAGE_RESOURCE_DATA_ENTRY entry = (PIMAGE_RESOURCE_DATA_ENTRY) resource;
+    if (entry == NULL) {
+        return NULL;
+    }
+
+    return codeBase + entry->OffsetToData;
+}
+
+int
+MemoryLoadString(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize)
+{
+    return MemoryLoadStringEx(module, id, buffer, maxsize, DEFAULT_LANGUAGE);
+}
+
+int
+MemoryLoadStringEx(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize, WORD language)
+{
+    HMEMORYRSRC resource;
+    PIMAGE_RESOURCE_DIR_STRING_U data;
+    DWORD size;
+    if (maxsize == 0) {
+        return 0;
+    }
+
+    resource = MemoryFindResourceEx(module, MAKEINTRESOURCE((id >> 4) + 1), RT_STRING, language);
+    if (resource == NULL) {
+        buffer[0] = 0;
+        return 0;
+    }
+
+    data = (PIMAGE_RESOURCE_DIR_STRING_U) MemoryLoadResource(module, resource);
+    id = id & 0x0f;
+    while (id--) {
+        data = (PIMAGE_RESOURCE_DIR_STRING_U) (((char *) data) + (data->Length + 1) * sizeof(WCHAR));
+    }
+    if (data->Length == 0) {
+        SetLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
+        buffer[0] = 0;
+        return 0;
+    }
+
+    size = data->Length;
+    if (size >= (DWORD) maxsize) {
+        size = maxsize;
+    } else {
+        buffer[size] = 0;
+    }
+#if defined(UNICODE)
+    wcsncpy(buffer, data->NameString, size);
+#else
+    wcstombs(buffer, data->NameString, size);
+#endif
+    return size;
+}

+ 148 - 0
DLLInjection/LoadMemoryDLL-master/MemoryModule.h

@@ -0,0 +1,148 @@
+/*
+ * Memory DLL loading code
+ * Version 0.0.4
+ *
+ * Copyright (c) 2004-2015 by Joachim Bauch / mail@joachim-bauch.de
+ * http://www.joachim-bauch.de
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is MemoryModule.h
+ *
+ * The Initial Developer of the Original Code is Joachim Bauch.
+ *
+ * Portions created by Joachim Bauch are Copyright (C) 2004-2015
+ * Joachim Bauch. All Rights Reserved.
+ *
+ */
+
+#ifndef __MEMORY_MODULE_HEADER
+#define __MEMORY_MODULE_HEADER
+
+#include <windows.h>
+
+typedef void *HMEMORYMODULE;
+
+typedef void *HMEMORYRSRC;
+
+typedef void *HCUSTOMMODULE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef HCUSTOMMODULE (*CustomLoadLibraryFunc)(LPCSTR, void *);
+typedef FARPROC (*CustomGetProcAddressFunc)(HCUSTOMMODULE, LPCSTR, void *);
+typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE, void *);
+
+/**
+ * Load EXE/DLL from memory location with the given size.
+ *
+ * All dependencies are resolved using default LoadLibrary/GetProcAddress
+ * calls through the Windows API.
+ */
+HMEMORYMODULE MemoryLoadLibrary(const void *, size_t);
+
+/**
+ * Load EXE/DLL from memory location with the given size using custom dependency
+ * resolvers.
+ *
+ * Dependencies will be resolved using passed callback methods.
+ */
+HMEMORYMODULE MemoryLoadLibraryEx(const void *, size_t,
+    CustomLoadLibraryFunc,
+    CustomGetProcAddressFunc,
+    CustomFreeLibraryFunc,
+    void *);
+
+/**
+ * Get address of exported method. Supports loading both by name and by
+ * ordinal value.
+ */
+FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR);
+
+/**
+ * Free previously loaded EXE/DLL.
+ */
+void MemoryFreeLibrary(HMEMORYMODULE);
+
+/**
+ * Execute entry point (EXE only). The entry point can only be executed
+ * if the EXE has been loaded to the correct base address or it could
+ * be relocated (i.e. relocation information have not been stripped by
+ * the linker).
+ *
+ * Important: calling this function will not return, i.e. once the loaded
+ * EXE finished running, the process will terminate.
+ *
+ * Returns a negative value if the entry point could not be executed.
+ */
+int MemoryCallEntryPoint(HMEMORYMODULE);
+
+/**
+ * Find the location of a resource with the specified type and name.
+ */
+HMEMORYRSRC MemoryFindResource(HMEMORYMODULE, LPCTSTR, LPCTSTR);
+
+/**
+ * Find the location of a resource with the specified type, name and language.
+ */
+HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE, LPCTSTR, LPCTSTR, WORD);
+
+/**
+ * Get the size of the resource in bytes.
+ */
+DWORD MemorySizeofResource(HMEMORYMODULE, HMEMORYRSRC);
+
+/**
+ * Get a pointer to the contents of the resource.
+ */
+LPVOID MemoryLoadResource(HMEMORYMODULE, HMEMORYRSRC);
+
+/**
+ * Load a string resource.
+ */
+int MemoryLoadString(HMEMORYMODULE, UINT, LPTSTR, int);
+
+/**
+ * Load a string resource with a given language.
+ */
+int MemoryLoadStringEx(HMEMORYMODULE, UINT, LPTSTR, int, WORD);
+
+/**
+ * Default implementation of CustomLoadLibraryFunc that calls LoadLibraryA
+ * internally to load an additional libary.
+ *
+ * This is the default as used by MemoryLoadLibrary.
+ */
+HCUSTOMMODULE MemoryDefaultLoadLibrary(LPCSTR, void *);
+
+/**
+ * Default implementation of CustomGetProcAddressFunc that calls GetProcAddress
+ * internally to get the address of an exported function.
+ *
+ * This is the default as used by MemoryLoadLibrary.
+ */
+FARPROC MemoryDefaultGetProcAddress(HCUSTOMMODULE, LPCSTR, void *);
+
+/**
+ * Default implementation of CustomFreeLibraryFunc that calls FreeLibrary
+ * internally to release an additional libary.
+ *
+ * This is the default as used by MemoryLoadLibrary.
+ */
+void MemoryDefaultFreeLibrary(HCUSTOMMODULE, void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __MEMORY_MODULE_HEADER

+ 50 - 0
DLLInjection/LoadMemoryDLL-master/appveyor.yml

@@ -0,0 +1,50 @@
+# Status available at
+# https://ci.appveyor.com/project/fancycode/memorymodule
+version: #{build}
+
+os:
+  - Visual Studio 2015
+
+environment:
+  matrix:
+    - GENERATOR: "Visual Studio 10 2010"
+      UNICODE: ON
+    - GENERATOR: "Visual Studio 10 2010"
+      UNICODE: OFF
+    - GENERATOR: "Visual Studio 11 2012"
+      UNICODE: ON
+    - GENERATOR: "Visual Studio 11 2012"
+      UNICODE: OFF
+    - GENERATOR: "Visual Studio 12 2013"
+      UNICODE: ON
+    - GENERATOR: "Visual Studio 12 2013"
+      UNICODE: OFF
+    - GENERATOR: "Visual Studio 14 2015"
+      UNICODE: ON
+    - GENERATOR: "Visual Studio 14 2015"
+      UNICODE: OFF
+
+platform:
+  - x86
+  - x64
+
+configuration:
+  - Debug
+
+build:
+  verbosity: normal
+
+build_script:
+  - ps: if($env:PLATFORM -eq "x64") { $env:CMAKE_GEN_SUFFIX=" Win64" }
+  - cmake "-G%GENERATOR%%CMAKE_GEN_SUFFIX%" -H. -Bbuild
+  - cmake --build build --config %CONFIGURATION%
+
+before_test:
+  - copy /y build\example\DllLoader\%CONFIGURATION%\DllLoader.exe build\example\DllLoader\
+  - copy /y build\example\DllLoader\%CONFIGURATION%\DllLoaderLoader.exe build\example\DllLoader\
+  - copy /y build\example\SampleDLL\%CONFIGURATION%\SampleDLL.dll build\example\SampleDLL\
+
+test_script:
+  - cd build\example\DllLoader
+  - DllLoader.exe
+  - DllLoaderLoader.exe

+ 546 - 0
DLLInjection/LoadMemoryDLL-master/doc/readme.rst

@@ -0,0 +1,546 @@
+:author:    Joachim Bauch
+:contact:   mail@joachim-bauch.de
+:copyright: `Creative Commons License (by-sa)`__
+
+__ http://creativecommons.org/licenses/by-sa/2.5/
+
+
+.. contents::
+
+
+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;
+
+.. _OptionalHeader:
+
+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;
+
+.. _DataDirectory:
+
+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 *, size_t);
+    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/
+
+
+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.
+
+
+Copyright
+==========
+
+The MemoryModule library and this tutorial are
+Copyright (c) 2004-2015 by Joachim Bauch.

+ 2 - 0
DLLInjection/LoadMemoryDLL-master/example/CMakeLists.txt

@@ -0,0 +1,2 @@
+add_subdirectory (DllLoader)
+add_subdirectory (SampleDLL)

+ 2 - 0
DLLInjection/LoadMemoryDLL-master/example/DllLoader/.gitignore

@@ -0,0 +1,2 @@
+*.o
+*.exe

+ 26 - 0
DLLInjection/LoadMemoryDLL-master/example/DllLoader/CMakeLists.txt

@@ -0,0 +1,26 @@
+set (sources_dllloader
+  DllLoader.cpp
+)
+
+set (sources_dllloaderloader
+  DllLoaderLoader.cpp
+)
+
+if (NOT MSVC)
+    set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-static")
+    set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-static")
+endif ()
+
+add_executable (DllLoader ${sources_dllloader})
+target_link_libraries ("DllLoader" "MemoryModule")
+if (NOT MSVC)
+    set_target_properties ("DllLoader" PROPERTIES SUFFIX ".exe")
+    set_target_properties ("DllLoader" PROPERTIES LINK_FLAGS "-Wl,--image-base -Wl,0x20000000")
+endif ()
+
+add_executable (DllLoaderLoader ${sources_dllloaderloader})
+target_link_libraries ("DllLoaderLoader" "MemoryModule")
+if (NOT MSVC)
+    set_target_properties ("DllLoaderLoader" PROPERTIES SUFFIX ".exe")
+    set_target_properties ("DllLoaderLoader" PROPERTIES LINK_FLAGS "-Wl,--image-base -Wl,0x10000000")
+endif ()

+ 115 - 0
DLLInjection/LoadMemoryDLL-master/example/DllLoader/DllLoader.cpp

@@ -0,0 +1,115 @@
+#define WIN32_LEAN_AND_MEAN
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <malloc.h>
+
+#include "../../MemoryModule.h"
+
+typedef int (*addNumberProc)(int, int);
+
+#define DLL_FILE TEXT("..\\SampleDLL\\SampleDLL.dll")
+
+void LoadFromFile(void)
+{
+    addNumberProc addNumber;
+    HRSRC resourceInfo;
+    DWORD resourceSize;
+    LPVOID resourceData;
+    TCHAR buffer[100];
+
+    HINSTANCE handle = LoadLibrary(DLL_FILE);
+    if (handle == NULL)
+        return;
+
+    addNumber = (addNumberProc)GetProcAddress(handle, "addNumbers");
+    _tprintf(_T("From file: %d\n"), addNumber(1, 2));
+
+    resourceInfo = FindResource(handle, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
+    _tprintf(_T("FindResource returned 0x%p\n"), resourceInfo);
+
+    resourceSize = SizeofResource(handle, resourceInfo);
+    resourceData = LoadResource(handle, resourceInfo);
+    _tprintf(_T("Resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);
+
+    LoadString(handle, 1, buffer, sizeof(buffer));
+    _tprintf(_T("String1: %s\n"), buffer);
+
+    LoadString(handle, 20, buffer, sizeof(buffer));
+    _tprintf(_T("String2: %s\n"), buffer);
+
+    FreeLibrary(handle);
+}
+
+void LoadFromMemory(void)
+{
+    FILE *fp;
+    unsigned char *data=NULL;
+    long size;
+    size_t read;
+    HMEMORYMODULE handle;
+    addNumberProc addNumber;
+    HMEMORYRSRC resourceInfo;
+    DWORD resourceSize;
+    LPVOID resourceData;
+    TCHAR buffer[100];
+
+    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);
+    assert(size >= 0);
+    data = (unsigned char *)malloc(size);
+    assert(data != NULL);
+    fseek(fp, 0, SEEK_SET);
+    read = fread(data, 1, size, fp);
+    assert(read == static_cast<size_t>(size));
+    fclose(fp);
+
+    handle = MemoryLoadLibrary(data, size);
+    if (handle == NULL)
+    {
+        _tprintf(_T("Can't load library from memory.\n"));
+        goto exit;
+    }
+
+    addNumber = (addNumberProc)MemoryGetProcAddress(handle, "addNumbers");
+    _tprintf(_T("From memory: %d\n"), addNumber(1, 2));
+
+    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:
+    free(data);
+}
+
+int main()
+{
+    LoadFromFile();
+    printf("\n\n");
+    LoadFromMemory();
+    return 0;
+}
+

+ 138 - 0
DLLInjection/LoadMemoryDLL-master/example/DllLoader/DllLoader.vcproj

@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="DllLoader"
+	ProjectGUID="{D0226BB5-3A02-4C91-893A-F36567AED5C5}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/DllLoader.exe"
+				LinkIncremental="2"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/DllLoader.pdb"
+				SubSystem="1"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="4"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/DllLoader.exe"
+				LinkIncremental="1"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Quelldateien"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\DllLoader.cpp">
+			</File>
+			<File
+				RelativePath="..\..\MemoryModule.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Headerdateien"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath="..\..\MemoryModule.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Ressourcendateien"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 64 - 0
DLLInjection/LoadMemoryDLL-master/example/DllLoader/DllLoaderLoader.cpp

@@ -0,0 +1,64 @@
+#define WIN32_LEAN_AND_MEAN
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <malloc.h>
+
+#include "../../MemoryModule.h"
+
+#define EXE_FILE TEXT("DllLoader.exe")
+
+int RunFromMemory(void)
+{
+    FILE *fp;
+    unsigned char *data=NULL;
+    long size;
+    size_t read;
+    HMEMORYMODULE handle;
+    int result = -1;
+
+    fp = _tfopen(EXE_FILE, _T("rb"));
+    if (fp == NULL)
+    {
+        _tprintf(_T("Can't open executable \"%s\"."), EXE_FILE);
+        goto exit;
+    }
+
+    fseek(fp, 0, SEEK_END);
+    size = ftell(fp);
+    assert(size >= 0);
+    data = (unsigned char *)malloc(size);
+    assert(data != NULL);
+    fseek(fp, 0, SEEK_SET);
+    read = fread(data, 1, size, fp);
+    assert(read == static_cast<size_t>(size));
+    fclose(fp);
+
+    handle = MemoryLoadLibrary(data, size);
+    if (handle == NULL)
+    {
+        _tprintf(_T("Can't load library from memory.\n"));
+        goto exit;
+    }
+
+    result = MemoryCallEntryPoint(handle);
+    if (result < 0) {
+        _tprintf(_T("Could not execute entry point: %d\n"), result);
+    }
+    MemoryFreeLibrary(handle);
+
+exit:
+    free(data);
+    return result;
+}
+
+int main()
+{
+    return RunFromMemory();
+}
+

+ 42 - 0
DLLInjection/LoadMemoryDLL-master/example/DllLoader/Makefile

@@ -0,0 +1,42 @@
+UNAME := $(shell uname)
+
+ifeq ($(UNAME), Linux)
+ifndef PLATFORM
+PLATFORM = i686
+endif
+CC = $(PLATFORM)-w64-mingw32-g++
+CXX = $(PLATFORM)-w64-mingw32-g++
+LINK = $(PLATFORM)-w64-mingw32-ld
+else
+CC = g++
+CXX = g++
+LINK = ld
+endif
+
+RM = rm
+CFLAGS  = -Wall -g
+LDFLAGS = -static
+
+ifdef UNICODE
+CFLAGS += -DUNICODE -D_UNICODE
+endif
+
+OBJ = DllLoader.o ../../MemoryModule.o
+OBJ_LOADER = DllLoaderLoader.o ../../MemoryModule.o
+
+all: DllLoader.exe DllLoaderLoader.exe
+
+DllLoader.exe: $(OBJ)
+	$(CC) $(LDFLAGS) -Wl,--image-base -Wl,0x20000000 -o DllLoader.exe $(OBJ)
+
+DllLoaderLoader.exe: $(OBJ_LOADER)
+	$(CC) $(LDFLAGS) -Wl,--image-base -Wl,0x10000000 -o DllLoaderLoader.exe $(OBJ_LOADER)
+
+%.o: %.cpp
+	$(CXX) $(CFLAGS) -c $<
+
+%.o: %.cc
+	$(CC) $(CFLAGS) -c $<
+
+clean:
+	$(RM) -rf $(OBJ) $(OBJ_LOADER) DllLoader.exe DllLoaderLoader.exe

+ 30 - 0
DLLInjection/LoadMemoryDLL-master/example/DllMemory.sln

@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SampleDLL", "SampleDLL\SampleDLL.vcproj", "{B293DAC4-5BCA-4413-9B7B-92CB56459875}"
+	ProjectSection(ProjectDependencies) = postProject
+		{D0226BB5-3A02-4C91-893A-F36567AED5C5} = {D0226BB5-3A02-4C91-893A-F36567AED5C5}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DllLoader", "DllLoader\DllLoader.vcproj", "{D0226BB5-3A02-4C91-893A-F36567AED5C5}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		Debug = Debug
+		Release = Release
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{B293DAC4-5BCA-4413-9B7B-92CB56459875}.Debug.ActiveCfg = Debug|Win32
+		{B293DAC4-5BCA-4413-9B7B-92CB56459875}.Debug.Build.0 = Debug|Win32
+		{B293DAC4-5BCA-4413-9B7B-92CB56459875}.Release.ActiveCfg = Release|Win32
+		{B293DAC4-5BCA-4413-9B7B-92CB56459875}.Release.Build.0 = Release|Win32
+		{D0226BB5-3A02-4C91-893A-F36567AED5C5}.Debug.ActiveCfg = Debug|Win32
+		{D0226BB5-3A02-4C91-893A-F36567AED5C5}.Debug.Build.0 = Debug|Win32
+		{D0226BB5-3A02-4C91-893A-F36567AED5C5}.Release.ActiveCfg = Release|Win32
+		{D0226BB5-3A02-4C91-893A-F36567AED5C5}.Release.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal

+ 17 - 0
DLLInjection/LoadMemoryDLL-master/example/Makefile

@@ -0,0 +1,17 @@
+SUBDIRS = DllLoader SampleDLL
+
+.PHONY: subdirs $(SUBDIRS)
+
+subdirs: $(SUBDIRS)
+
+$(SUBDIRS):
+	$(MAKE) -C $@
+
+CLEANDIRS = $(SUBDIRS:%=clean-%)
+
+clean: $(CLEANDIRS)
+$(CLEANDIRS):
+	$(MAKE) -C $(@:clean-%=%) clean
+
+.PHONY: subdirs $(INSTALLDIRS)
+.PHONY: clean

+ 3 - 0
DLLInjection/LoadMemoryDLL-master/example/SampleDLL/.gitignore

@@ -0,0 +1,3 @@
+*.o
+*.dll
+*.res

+ 12 - 0
DLLInjection/LoadMemoryDLL-master/example/SampleDLL/CMakeLists.txt

@@ -0,0 +1,12 @@
+set (sources
+  SampleDLL.cpp
+  SampleDLL.h
+  SampleDLL.rc
+)
+
+add_definitions (-DSAMPLEDLL_EXPORTS)
+add_library (SampleDLL MODULE ${sources})
+if (NOT MSVC)
+    set_target_properties ("SampleDLL" PROPERTIES PREFIX "")
+    set_target_properties ("SampleDLL" PROPERTIES SUFFIX ".dll")
+endif ()

+ 39 - 0
DLLInjection/LoadMemoryDLL-master/example/SampleDLL/Makefile

@@ -0,0 +1,39 @@
+UNAME := $(shell uname)
+
+ifeq ($(UNAME), Linux)
+ifndef PLATFORM
+PLATFORM = i686
+endif
+CC = $(PLATFORM)-w64-mingw32-g++
+CXX = $(PLATFORM)-w64-mingw32-g++
+LINK = $(PLATFORM)-w64-mingw32-g++
+RC = $(PLATFORM)-w64-mingw32-windres
+else
+CC = g++
+CXX = g++
+LINK = ld
+RC = rc
+endif
+
+RM = rm
+CFLAGS  = -Wall -g -DSAMPLEDLL_EXPORTS
+LDFLAGS = -shared
+RCFLAGS = -O coff
+
+ifdef UNICODE
+CFLAGS += -DUNICODE -D_UNICODE
+endif
+
+OBJ = SampleDLL.o SampleDLL.res
+
+SampleDLL.dll: $(OBJ)
+	$(LINK) $(LDFLAGS) -o SampleDLL.dll $(OBJ)
+
+%.o: %.cpp
+	$(CXX) $(CFLAGS) -c $<
+
+%.res: %.rc
+	$(RC) $(RCFLAGS) -o $*.res $<
+
+clean:
+	$(RM) -rf $(OBJ) SampleDLL.dll

+ 10 - 0
DLLInjection/LoadMemoryDLL-master/example/SampleDLL/SampleDLL.cpp

@@ -0,0 +1,10 @@
+#include "SampleDLL.h"
+
+extern "C" {
+
+SAMPLEDLL_API int addNumbers(int a, int b)
+{
+    return a + b;
+}
+
+}

+ 11 - 0
DLLInjection/LoadMemoryDLL-master/example/SampleDLL/SampleDLL.h

@@ -0,0 +1,11 @@
+extern "C" {
+
+#ifdef SAMPLEDLL_EXPORTS
+#define SAMPLEDLL_API __declspec(dllexport)
+#else
+#define SAMPLEDLL_API __declspec(dllimport)
+#endif
+
+SAMPLEDLL_API int addNumbers(int a, int b);
+
+}

+ 34 - 0
DLLInjection/LoadMemoryDLL-master/example/SampleDLL/SampleDLL.rc

@@ -0,0 +1,34 @@
+1 VERSIONINFO
+FILEVERSION     1,0,0,0
+PRODUCTVERSION  1,0,0,0
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    BEGIN
+      VALUE "CompanyName", "fancy.code"
+      VALUE "FileDescription", "SampleDLL"
+      VALUE "FileVersion", "1.0"
+      VALUE "InternalName", "SampleDLL"
+      VALUE "LegalCopyright", "Copyright (c) 2004-2015 Joachim Bauch"
+      VALUE "OriginalFilename", "SampleDLL.dll"
+      VALUE "ProductName", "MemoryModule"
+      VALUE "ProductVersion", "0.0.4"
+    END
+  END
+
+  BLOCK "VarFileInfo"
+  BEGIN
+    VALUE "Translation", 0x409, 1252
+  END
+END
+
+
+#define IDS_HELLO   1
+#define IDS_WORLD   20
+
+STRINGTABLE
+{
+    IDS_HELLO,  "Hello"
+    IDS_WORLD,  "World!"
+}

+ 137 - 0
DLLInjection/LoadMemoryDLL-master/example/SampleDLL/SampleDLL.vcproj

@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="SampleDLL"
+	ProjectGUID="{B293DAC4-5BCA-4413-9B7B-92CB56459875}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SAMPLEDLL_EXPORTS"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/SampleDLL.dll"
+				LinkIncremental="2"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/SampleDLL.pdb"
+				SubSystem="2"
+				ImportLibrary="$(OutDir)/SampleDLL.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SAMPLEDLL_EXPORTS"
+				RuntimeLibrary="0"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/SampleDLL.dll"
+				LinkIncremental="1"
+				GenerateDebugInformation="TRUE"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				ImportLibrary="$(OutDir)/SampleDLL.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Quelldateien"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath=".\SampleDLL.cpp">
+			</File>
+		</Filter>
+		<Filter
+			Name="Headerdateien"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath=".\SampleDLL.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Ressourcendateien"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 20 - 0
DLLInjection/LoadMemoryDLL-master/readme.md

@@ -0,0 +1,20 @@
+MemoryModule
+============
+
+[![Build Status](https://travis-ci.org/fancycode/MemoryModule.svg?branch=master)](https://travis-ci.org/fancycode/MemoryModule)[![Build status](https://ci.appveyor.com/api/projects/status/qcrfxbno0jbbl9cx/branch/master?svg=true)](https://ci.appveyor.com/project/fancycode/memorymodule)
+
+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.txt` for more informations about the format of a DLL file and
+a tutorial how they can be loaded directly.

+ 233 - 0
DLLInjection/LoadMemoryDLL-master/tests/LoadDll.cpp

@@ -0,0 +1,233 @@
+#define WIN32_LEAN_AND_MEAN
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <assert.h>
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <malloc.h>
+
+#include "../MemoryModule.h"
+
+typedef int (*addNumberProc)(int, int);
+
+// Thanks to Tim Cooper (from http://stackoverflow.com/a/8584708)
+const char *sstrstr(const char *haystack, const char *needle, size_t length) {
+    size_t needle_length = strlen(needle);
+    size_t i;
+
+    for (i = 0; i < length; i++) {
+        if (i + needle_length > length) {
+            return NULL;
+        }
+
+        if (strncmp(&haystack[i], needle, needle_length) == 0) {
+            return &haystack[i];
+        }
+    }
+    return NULL;
+}
+
+const wchar_t *swcsstr(const wchar_t *haystack, const wchar_t *needle, size_t length) {
+    size_t needle_length = wcslen(needle);
+    size_t i;
+
+    for (i = 0; i < length; i++) {
+        if (i + needle_length > length) {
+            return NULL;
+        }
+
+        if (wcsncmp(&haystack[i], needle, needle_length) == 0) {
+            return &haystack[i];
+        }
+    }
+    return NULL;
+}
+
+BOOL CheckResourceStrings(LPVOID data, DWORD size, const char *first, const wchar_t *second) {
+    const char *first_pos;
+    const wchar_t *second_pos;
+    const wchar_t *src;
+
+    if (data == NULL || size == 0) {
+        return FALSE;
+    }
+
+    first_pos = sstrstr((const char *) data, first, size);
+    if (first_pos == NULL) {
+        fprintf(stderr, "ERROR: data doesn't start with %s\n", first);
+        return FALSE;
+    }
+
+    src = (const wchar_t *) (((const char *) data) + strlen(first) + 1);
+    second_pos = swcsstr(src, second, (size - strlen(first) - 1) / sizeof(wchar_t));
+    if (second_pos == NULL) {
+        fwprintf(stderr, L"ERROR: data doesn't continue with %s\n", second);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+BOOL LoadFromMemory(char *filename)
+{
+    FILE *fp;
+    unsigned char *data=NULL;
+    long size;
+    size_t read;
+    HMEMORYMODULE handle = NULL;
+    addNumberProc addNumber;
+    addNumberProc addNumber2;
+    HMEMORYRSRC resourceInfo;
+    DWORD resourceSize;
+    LPVOID resourceData;
+    TCHAR buffer[100];
+    BOOL result = TRUE;
+
+    fp = fopen(filename, "rb");
+    if (fp == NULL)
+    {
+        printf("Can't open DLL file \"%s\".", filename);
+        result = FALSE;
+        goto exit;
+    }
+
+    fseek(fp, 0, SEEK_END);
+    size = ftell(fp);
+    assert(size > 0);
+    data = (unsigned char *)malloc(size);
+    assert(data != NULL);
+    fseek(fp, 0, SEEK_SET);
+    read = fread(data, 1, size, fp);
+    assert(read == static_cast<size_t>(size));
+    fclose(fp);
+
+    handle = MemoryLoadLibrary(data, size);
+    if (handle == NULL)
+    {
+        _tprintf(_T("Can't load library from memory.\n"));
+        result = FALSE;
+        goto exit;
+    }
+
+    addNumber = (addNumberProc)MemoryGetProcAddress(handle, NULL);
+    if (addNumber != NULL) {
+        _tprintf(_T("MemoryGetProcAddress(NULL) returned %p\n"), addNumber);
+        result = FALSE;
+        goto exit;
+    }
+
+    addNumber = (addNumberProc)MemoryGetProcAddress(handle, reinterpret_cast<LPCSTR>(0xff));
+    if (addNumber != NULL) {
+        _tprintf(_T("MemoryGetProcAddress(0xff) returned %p\n"), addNumber);
+        result = FALSE;
+        goto exit;
+    }
+
+    addNumber = (addNumberProc)MemoryGetProcAddress(handle, "addNumbers");
+    _tprintf(_T("From memory: %d\n"), addNumber(1, 2));
+
+    // the DLL only exports one function, try to load by ordinal value
+    addNumber2 = (addNumberProc)MemoryGetProcAddress(handle, reinterpret_cast<LPCSTR>(0x01));
+    if (addNumber != addNumber2) {
+        _tprintf(_T("MemoryGetProcAddress(0x01) returned %p (expected %p)\n"), addNumber2, addNumber);
+        result = FALSE;
+        goto exit;
+    }
+
+    resourceInfo = MemoryFindResource(handle, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
+    _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);
+
+    if (resourceInfo != NULL) {
+        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);
+    } else {
+        result = FALSE;
+    }
+
+    resourceInfo = MemoryFindResource(handle, _T("stringres"), RT_RCDATA);
+    _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);
+    if (resourceInfo != NULL) {
+        resourceSize = MemorySizeofResource(handle, resourceInfo);
+        resourceData = MemoryLoadResource(handle, resourceInfo);
+
+        _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);
+        if (!CheckResourceStrings(resourceData, resourceSize, "This is a ANSI string", L"This is a UNICODE string")) {
+            result = FALSE;
+        }
+    } else {
+        result = FALSE;
+    }
+
+    resourceInfo = MemoryFindResource(handle, _T("stringres1"), RT_RCDATA);
+    _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);
+    if (resourceInfo != NULL) {
+        resourceSize = MemorySizeofResource(handle, resourceInfo);
+        resourceData = MemoryLoadResource(handle, resourceInfo);
+
+        _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);
+        if (!CheckResourceStrings(resourceData, resourceSize, "This is ANSI string 1", L"This is UNICODE string 1")) {
+            result = FALSE;
+        }
+    } else {
+        result = FALSE;
+    }
+
+
+    resourceInfo = MemoryFindResource(handle, _T("stringres2"), RT_RCDATA);
+    _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);
+    if (resourceInfo != NULL) {
+        resourceSize = MemorySizeofResource(handle, resourceInfo);
+        resourceData = MemoryLoadResource(handle, resourceInfo);
+
+        _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);
+        if (!CheckResourceStrings(resourceData, resourceSize, "This is ANSI string 2", L"This is UNICODE string 2")) {
+            result = FALSE;
+        }
+    } else {
+        result = FALSE;
+    }
+
+
+    resourceInfo = MemoryFindResource(handle, _T("stringres3"), RT_RCDATA);
+    _tprintf(_T("MemoryFindResource returned 0x%p\n"), resourceInfo);
+    if (resourceInfo != NULL) {
+        resourceSize = MemorySizeofResource(handle, resourceInfo);
+        resourceData = MemoryLoadResource(handle, resourceInfo);
+
+        _tprintf(_T("Memory resource data: %ld bytes at 0x%p\n"), resourceSize, resourceData);
+        if (!CheckResourceStrings(resourceData, resourceSize, "This is ANSI string 3", L"This is UNICODE string 3")) {
+            result = FALSE;
+        }
+    } else {
+        result = FALSE;
+    }
+
+exit:
+    MemoryFreeLibrary(handle);
+    free(data);
+    return result;
+}
+
+int main(int argc, char* argv[])
+{
+    if (argc < 2) {
+        fprintf(stderr, "USAGE: %s <filename.dll>\n", argv[0]);
+        return 1;
+    }
+
+    if (!LoadFromMemory(argv[1])) {
+        return 2;
+    }
+
+    return 0;
+}

+ 81 - 0
DLLInjection/LoadMemoryDLL-master/tests/Makefile

@@ -0,0 +1,81 @@
+UNAME := $(shell uname)
+
+ifeq ($(UNAME), Linux)
+ifndef PLATFORM
+PLATFORM = i686
+endif
+CC = $(PLATFORM)-w64-mingw32-g++
+CXX = $(PLATFORM)-w64-mingw32-g++
+LD = $(PLATFORM)-w64-mingw32-ld
+RC = $(PLATFORM)-w64-mingw32-windres
+else
+CC = g++
+CXX = g++
+LD = ld
+RC = rc
+endif
+
+RM = rm
+CFLAGS  = -Wall -g
+LDFLAGS =
+RCFLAGS = -O coff
+
+ifdef UNICODE
+CFLAGS += -DUNICODE -D_UNICODE
+endif
+
+CFLAGS_DLL = -DSAMPLEDLL_EXPORTS
+CFLAGS_EXE =
+LDFLAGS_DLL = -shared
+LDFLAGS_EXE = -static
+
+TEST_DLLS = \
+	test-align-128.dll \
+	test-align-256.dll \
+	test-align-512.dll \
+	test-align-768.dll \
+	test-align-1024.dll \
+	test-align-2048.dll \
+	test-align-3072.dll \
+	test-align-4096.dll \
+	test-align-100.dll \
+	test-align-200.dll \
+	test-align-300.dll \
+	test-align-400.dll \
+	test-align-500.dll \
+	test-align-600.dll \
+	test-align-800.dll \
+	test-align-900.dll \
+	test-relocate.dll \
+
+LOADDLL_OBJ = LoadDll.o ../MemoryModule.o
+DLL_OBJ = SampleDLL.o SampleDLL.res
+
+all: LoadDll.exe $(TEST_DLLS)
+
+LoadDll.exe: $(LOADDLL_OBJ)
+	$(CC) $(LDFLAGS_EXE) $(LDFLAGS) -Wl,--image-base -Wl,0x20000000 -o LoadDll.exe $(LOADDLL_OBJ)
+
+LoadDll.o: LoadDll.cpp
+	$(CXX) $(CFLAGS) $(CFLAGS_EXE) -c $<
+
+test-align-%.dll: $(DLL_OBJ)
+	$(LD) $(LDFLAGS_DLL) $(LDFLAGS) --file-alignment $* --section-alignment $* -o $@ $(DLL_OBJ)
+
+test-relocate.dll: $(DLL_OBJ)
+	$(CXX) $(LDFLAGS_DLL) $(LDFLAGS) -Wl,--image-base -Wl,0x20000000 -o $@ $(DLL_OBJ)
+
+%.o: %.cpp
+	$(CXX) $(CFLAGS) $(CFLAGS_DLL) -c $<
+
+%.o: %.cc
+	$(CC) $(CFLAGS) $(CFLAGS_DLL) -c $<
+
+%.res: %.rc
+	$(RC) $(RCFLAGS) -o $*.res $<
+
+clean:
+	$(RM) -rf LoadDll.exe $(TEST_DLLS) $(LOADDLL_OBJ) $(DLL_OBJ)
+
+test: all
+	./runtests.sh $(PLATFORM) "$(TEST_DLLS)"

+ 10 - 0
DLLInjection/LoadMemoryDLL-master/tests/SampleDLL.cpp

@@ -0,0 +1,10 @@
+#include "SampleDLL.h"
+
+extern "C" {
+
+SAMPLEDLL_API int addNumbers(int a, int b)
+{
+    return a + b;
+}
+
+}

+ 11 - 0
DLLInjection/LoadMemoryDLL-master/tests/SampleDLL.h

@@ -0,0 +1,11 @@
+extern "C" {
+
+#ifdef SAMPLEDLL_EXPORTS
+#define SAMPLEDLL_API __declspec(dllexport)
+#else
+#define SAMPLEDLL_API __declspec(dllimport)
+#endif
+
+SAMPLEDLL_API int addNumbers(int a, int b);
+
+}

+ 58 - 0
DLLInjection/LoadMemoryDLL-master/tests/SampleDLL.rc

@@ -0,0 +1,58 @@
+1 VERSIONINFO
+FILEVERSION     1,0,0,0
+PRODUCTVERSION  1,0,0,0
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    BEGIN
+      VALUE "CompanyName", "fancy.code"
+      VALUE "FileDescription", "SampleDLL"
+      VALUE "FileVersion", "1.0"
+      VALUE "InternalName", "SampleDLL"
+      VALUE "LegalCopyright", "Copyright (c) 2004-2015 Joachim Bauch"
+      VALUE "OriginalFilename", "SampleDLL.dll"
+      VALUE "ProductName", "MemoryModule"
+      VALUE "ProductVersion", "0.0.4"
+    END
+  END
+
+  BLOCK "VarFileInfo"
+  BEGIN
+    VALUE "Translation", 0x409, 1252
+  END
+END
+
+
+#define IDS_HELLO   1
+#define IDS_WORLD   20
+
+STRINGTABLE
+{
+    IDS_HELLO,  "Hello"
+    IDS_WORLD,  "World!"
+}
+
+STRINGRES RCDATA
+{
+   "This is a ANSI string\0",
+   L"This is a UNICODE string\0",
+}
+
+STRINGRES1 RCDATA
+{
+   "This is ANSI string 1\0",
+   L"This is UNICODE string 1\0",
+}
+
+STRINGRES2 RCDATA
+{
+   "This is ANSI string 2\0",
+   L"This is UNICODE string 2\0",
+}
+
+STRINGRES3 RCDATA
+{
+   "This is ANSI string 3\0",
+   L"This is UNICODE string 3\0",
+}

+ 24 - 0
DLLInjection/LoadMemoryDLL-master/tests/runtests.sh

@@ -0,0 +1,24 @@
+#!/bin/bash
+PLATFORM=$1
+if [ "${PLATFORM}" = "x86_64" ]; then
+    export WINEPREFIX=${HOME}/.wine64/
+    WINE=wine64
+else
+    export WINEPREFIX=${HOME}/.wine/
+    WINE=wine
+fi
+export WINEPATH=/usr/lib/gcc/${PLATFORM}-w64-mingw32/4.6/
+
+read -a TEST_DLLS <<< $2
+
+for filename in "${TEST_DLLS[@]}"
+do
+    :
+    echo "Testing $filename"
+    ${WINE} ./LoadDll.exe $filename
+    if [ "$?" != "0" ]; then
+        exit 1
+    fi
+done
+
+echo "${#TEST_DLLS[@]} tests completed successfully"