From 65553f955851724bb0ccf87525fa0a0a6fe97387 Mon Sep 17 00:00:00 2001
From: LycorisGuard <984022254@qq.com>
Date: Wed, 15 Aug 2018 00:35:11 +0800
Subject: [PATCH] ReflectiveDLLInjection
ReflectiveDLLInjection
---
Inject/ReflectiveDLLInjection/ReadMe.txt | 1 +
.../dll/reflective_dll.sln | 20 +
.../dll/reflective_dll.vcxproj | 193 +++++++
.../dll/reflective_dll.vcxproj.filters | 29 +
.../dll/src/ReflectiveDLLInjection.h | 51 ++
.../dll/src/ReflectiveDll.c | 32 ++
.../dll/src/ReflectiveLoader.c | 496 ++++++++++++++++++
.../dll/src/ReflectiveLoader.h | 203 +++++++
.../ReflectiveDLLInjection/inject/inject.sln | 20 +
.../inject/inject.vcxproj | 190 +++++++
.../inject/inject.vcxproj.filters | 35 ++
.../inject/src/GetProcAddressR.c | 116 ++++
.../inject/src/GetProcAddressR.h | 36 ++
.../inject/src/Inject.c | 120 +++++
.../inject/src/LoadLibraryR.c | 234 +++++++++
.../inject/src/LoadLibraryR.h | 41 ++
.../inject/src/ReflectiveDLLInjection.h | 53 ++
17 files changed, 1870 insertions(+)
create mode 100644 Inject/ReflectiveDLLInjection/ReadMe.txt
create mode 100644 Inject/ReflectiveDLLInjection/dll/reflective_dll.sln
create mode 100644 Inject/ReflectiveDLLInjection/dll/reflective_dll.vcxproj
create mode 100644 Inject/ReflectiveDLLInjection/dll/reflective_dll.vcxproj.filters
create mode 100644 Inject/ReflectiveDLLInjection/dll/src/ReflectiveDLLInjection.h
create mode 100644 Inject/ReflectiveDLLInjection/dll/src/ReflectiveDll.c
create mode 100644 Inject/ReflectiveDLLInjection/dll/src/ReflectiveLoader.c
create mode 100644 Inject/ReflectiveDLLInjection/dll/src/ReflectiveLoader.h
create mode 100644 Inject/ReflectiveDLLInjection/inject/inject.sln
create mode 100644 Inject/ReflectiveDLLInjection/inject/inject.vcxproj
create mode 100644 Inject/ReflectiveDLLInjection/inject/inject.vcxproj.filters
create mode 100644 Inject/ReflectiveDLLInjection/inject/src/GetProcAddressR.c
create mode 100644 Inject/ReflectiveDLLInjection/inject/src/GetProcAddressR.h
create mode 100644 Inject/ReflectiveDLLInjection/inject/src/Inject.c
create mode 100644 Inject/ReflectiveDLLInjection/inject/src/LoadLibraryR.c
create mode 100644 Inject/ReflectiveDLLInjection/inject/src/LoadLibraryR.h
create mode 100644 Inject/ReflectiveDLLInjection/inject/src/ReflectiveDLLInjection.h
diff --git a/Inject/ReflectiveDLLInjection/ReadMe.txt b/Inject/ReflectiveDLLInjection/ReadMe.txt
new file mode 100644
index 0000000..f4b20ae
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/ReadMe.txt
@@ -0,0 +1 @@
+Save ReflectiveDLLInjection to load dll no need to call loadlibrary.
\ No newline at end of file
diff --git a/Inject/ReflectiveDLLInjection/dll/reflective_dll.sln b/Inject/ReflectiveDLLInjection/dll/reflective_dll.sln
new file mode 100644
index 0000000..c667f6a
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/dll/reflective_dll.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reflective_dll", "reflective_dll.vcxproj", "{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.ActiveCfg = Release|Win32
+ {3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.Build.0 = Release|Win32
+ {3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.ActiveCfg = Release|Win32
+ {3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Inject/ReflectiveDLLInjection/dll/reflective_dll.vcxproj b/Inject/ReflectiveDLLInjection/dll/reflective_dll.vcxproj
new file mode 100644
index 0000000..dc17fc0
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/dll/reflective_dll.vcxproj
@@ -0,0 +1,193 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}
+ reflective_dll
+ Win32Proj
+
+
+
+ DynamicLibrary
+ MultiByte
+ true
+
+
+ DynamicLibrary
+ Unicode
+
+
+ DynamicLibrary
+ MultiByte
+ false
+
+
+ DynamicLibrary
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ true
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ true
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ false
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ false
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+
+
+
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+ EditAndContinue
+
+
+ true
+ Windows
+ MachineX86
+
+
+
+
+ X64
+
+
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+ ProgramDatabase
+
+
+ true
+ Windows
+ MachineX64
+
+
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ true
+ WIN32;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)
+ MultiThreaded
+ true
+
+
+ Level3
+ ProgramDatabase
+
+
+ true
+ Windows
+ true
+ true
+ MachineX86
+
+
+ copy ..\Release\reflective_dll.dll ..\bin\
+
+
+
+
+ X64
+
+
+ MaxSpeed
+ OnlyExplicitInline
+ true
+ Size
+ false
+ WIN64;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;_WIN64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)
+ MultiThreaded
+ true
+
+
+ Level3
+ ProgramDatabase
+ CompileAsCpp
+
+
+ $(OutDir)$(ProjectName).x64.dll
+ true
+ Windows
+ true
+ true
+ MachineX64
+
+
+ copy $(OutDir)$(ProjectName).x64.dll ..\bin\
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Inject/ReflectiveDLLInjection/dll/reflective_dll.vcxproj.filters b/Inject/ReflectiveDLLInjection/dll/reflective_dll.vcxproj.filters
new file mode 100644
index 0000000..de491b9
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/dll/reflective_dll.vcxproj.filters
@@ -0,0 +1,29 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/Inject/ReflectiveDLLInjection/dll/src/ReflectiveDLLInjection.h b/Inject/ReflectiveDLLInjection/dll/src/ReflectiveDLLInjection.h
new file mode 100644
index 0000000..ac01be2
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/dll/src/ReflectiveDLLInjection.h
@@ -0,0 +1,51 @@
+//===============================================================================================//
+// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are permitted
+// provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// * Neither the name of Harmony Security nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//===============================================================================================//
+#ifndef _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
+#define _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
+//===============================================================================================//
+#define WIN32_LEAN_AND_MEAN
+#include
+
+// we declare some common stuff in here...
+
+#define DLL_QUERY_HMODULE 6
+
+#define DEREF( name )*(UINT_PTR *)(name)
+#define DEREF_64( name )*(DWORD64 *)(name)
+#define DEREF_32( name )*(DWORD *)(name)
+#define DEREF_16( name )*(WORD *)(name)
+#define DEREF_8( name )*(BYTE *)(name)
+
+typedef ULONG_PTR (WINAPI * REFLECTIVELOADER)( VOID );
+typedef BOOL (WINAPI * DLLMAIN)( HINSTANCE, DWORD, LPVOID );
+
+#define DLLEXPORT __declspec( dllexport )
+
+//===============================================================================================//
+#endif
+//===============================================================================================//
diff --git a/Inject/ReflectiveDLLInjection/dll/src/ReflectiveDll.c b/Inject/ReflectiveDLLInjection/dll/src/ReflectiveDll.c
new file mode 100644
index 0000000..db3abb7
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/dll/src/ReflectiveDll.c
@@ -0,0 +1,32 @@
+//===============================================================================================//
+// This is a stub for the actuall functionality of the DLL.
+//===============================================================================================//
+#include "ReflectiveLoader.h"
+
+// Note: REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR and REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN are
+// defined in the project properties (Properties->C++->Preprocessor) so as we can specify our own
+// DllMain and use the LoadRemoteLibraryR() API to inject this DLL.
+
+// You can use this value as a pseudo hinstDLL value (defined and set via ReflectiveLoader.c)
+extern HINSTANCE hAppInstance;
+//===============================================================================================//
+BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
+{
+ BOOL bReturnValue = TRUE;
+ switch( dwReason )
+ {
+ case DLL_QUERY_HMODULE:
+ if( lpReserved != NULL )
+ *(HMODULE *)lpReserved = hAppInstance;
+ break;
+ case DLL_PROCESS_ATTACH:
+ hAppInstance = hinstDLL;
+ MessageBoxA( NULL, "Hello from DllMain!", "Reflective Dll Injection", MB_OK );
+ break;
+ case DLL_PROCESS_DETACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ break;
+ }
+ return bReturnValue;
+}
\ No newline at end of file
diff --git a/Inject/ReflectiveDLLInjection/dll/src/ReflectiveLoader.c b/Inject/ReflectiveDLLInjection/dll/src/ReflectiveLoader.c
new file mode 100644
index 0000000..662b166
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/dll/src/ReflectiveLoader.c
@@ -0,0 +1,496 @@
+//===============================================================================================//
+// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are permitted
+// provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// * Neither the name of Harmony Security nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//===============================================================================================//
+#include "ReflectiveLoader.h"
+//===============================================================================================//
+// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
+HINSTANCE hAppInstance = NULL;
+//===============================================================================================//
+#pragma intrinsic( _ReturnAddress )
+// This function can not be inlined by the compiler or we will not get the address we expect. Ideally
+// this code will be compiled with the /O2 and /Ob1 switches. Bonus points if we could take advantage of
+// RIP relative addressing in this instance but I dont believe we can do so with the compiler intrinsics
+// available (and no inline asm available under x64).
+__declspec(noinline) ULONG_PTR caller( VOID ) { return (ULONG_PTR)_ReturnAddress(); }
+//===============================================================================================//
+
+// Note 1: If you want to have your own DllMain, define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN,
+// otherwise the DllMain at the end of this file will be used.
+
+// Note 2: If you are injecting the DLL via LoadRemoteLibraryR, define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR,
+// otherwise it is assumed you are calling the ReflectiveLoader via a stub.
+
+// This is our position independent reflective DLL loader/injector
+#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
+DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( LPVOID lpParameter )
+#else
+DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader( VOID )
+#endif
+{
+ // the functions we need
+ LOADLIBRARYA pLoadLibraryA = NULL;
+ GETPROCADDRESS pGetProcAddress = NULL;
+ VIRTUALALLOC pVirtualAlloc = NULL;
+ NTFLUSHINSTRUCTIONCACHE pNtFlushInstructionCache = NULL;
+
+ USHORT usCounter;
+
+ // the initial location of this image in memory
+ ULONG_PTR uiLibraryAddress;
+ // the kernels base address and later this images newly loaded base address
+ ULONG_PTR uiBaseAddress;
+
+ // variables for processing the kernels export table
+ ULONG_PTR uiAddressArray;
+ ULONG_PTR uiNameArray;
+ ULONG_PTR uiExportDir;
+ ULONG_PTR uiNameOrdinals;
+ DWORD dwHashValue;
+
+ // variables for loading this image
+ ULONG_PTR uiHeaderValue;
+ ULONG_PTR uiValueA;
+ ULONG_PTR uiValueB;
+ ULONG_PTR uiValueC;
+ ULONG_PTR uiValueD;
+ ULONG_PTR uiValueE;
+
+ // STEP 0: calculate our images current base address
+
+ // we will start searching backwards from our callers return address.
+ uiLibraryAddress = caller();
+
+ // loop through memory backwards searching for our images base address
+ // we dont need SEH style search as we shouldnt generate any access violations with this
+ while( TRUE )
+ {
+ if( ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_magic == IMAGE_DOS_SIGNATURE )
+ {
+ uiHeaderValue = ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
+ // some x64 dll's can trigger a bogus signature (IMAGE_DOS_SIGNATURE == 'POP r10'),
+ // we sanity check the e_lfanew with an upper threshold value of 1024 to avoid problems.
+ if( uiHeaderValue >= sizeof(IMAGE_DOS_HEADER) && uiHeaderValue < 1024 )
+ {
+ uiHeaderValue += uiLibraryAddress;
+ // break if we have found a valid MZ/PE header
+ if( ((PIMAGE_NT_HEADERS)uiHeaderValue)->Signature == IMAGE_NT_SIGNATURE )
+ break;
+ }
+ }
+ uiLibraryAddress--;
+ }
+
+ // STEP 1: process the kernels exports for the functions our loader needs...
+
+ // get the Process Enviroment Block
+#ifdef WIN_X64
+ uiBaseAddress = __readgsqword( 0x60 );
+#else
+#ifdef WIN_X86
+ uiBaseAddress = __readfsdword( 0x30 );
+#else WIN_ARM
+ uiBaseAddress = *(DWORD *)( (BYTE *)_MoveFromCoprocessor( 15, 0, 13, 0, 2 ) + 0x30 );
+#endif
+#endif
+
+ // get the processes loaded modules. ref: http://msdn.microsoft.com/en-us/library/aa813708(VS.85).aspx
+ uiBaseAddress = (ULONG_PTR)((_PPEB)uiBaseAddress)->pLdr;
+
+ // get the first entry of the InMemoryOrder module list
+ uiValueA = (ULONG_PTR)((PPEB_LDR_DATA)uiBaseAddress)->InMemoryOrderModuleList.Flink;
+ while( uiValueA )
+ {
+ // get pointer to current modules name (unicode string)
+ uiValueB = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.pBuffer;
+ // set bCounter to the length for the loop
+ usCounter = ((PLDR_DATA_TABLE_ENTRY)uiValueA)->BaseDllName.Length;
+ // clear uiValueC which will store the hash of the module name
+ uiValueC = 0;
+
+ // compute the hash of the module name...
+ do
+ {
+ uiValueC = ror( (DWORD)uiValueC );
+ // normalize to uppercase if the madule name is in lowercase
+ if( *((BYTE *)uiValueB) >= 'a' )
+ uiValueC += *((BYTE *)uiValueB) - 0x20;
+ else
+ uiValueC += *((BYTE *)uiValueB);
+ uiValueB++;
+ } while( --usCounter );
+
+ // compare the hash with that of kernel32.dll
+ if( (DWORD)uiValueC == KERNEL32DLL_HASH )
+ {
+ // get this modules base address
+ uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase;
+
+ // get the VA of the modules NT Header
+ uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
+
+ // uiNameArray = the address of the modules export directory entry
+ uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
+
+ // get the VA of the export directory
+ uiExportDir = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
+
+ // get the VA for the array of name pointers
+ uiNameArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames );
+
+ // get the VA for the array of name ordinals
+ uiNameOrdinals = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals );
+
+ usCounter = 3;
+
+ // loop while we still have imports to find
+ while( usCounter > 0 )
+ {
+ // compute the hash values for this function name
+ dwHashValue = hash( (char *)( uiBaseAddress + DEREF_32( uiNameArray ) ) );
+
+ // if we have found a function we want we get its virtual address
+ if( dwHashValue == LOADLIBRARYA_HASH || dwHashValue == GETPROCADDRESS_HASH || dwHashValue == VIRTUALALLOC_HASH )
+ {
+ // get the VA for the array of addresses
+ uiAddressArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
+
+ // use this functions name ordinal as an index into the array of name pointers
+ uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
+
+ // store this functions VA
+ if( dwHashValue == LOADLIBRARYA_HASH )
+ pLoadLibraryA = (LOADLIBRARYA)( uiBaseAddress + DEREF_32( uiAddressArray ) );
+ else if( dwHashValue == GETPROCADDRESS_HASH )
+ pGetProcAddress = (GETPROCADDRESS)( uiBaseAddress + DEREF_32( uiAddressArray ) );
+ else if( dwHashValue == VIRTUALALLOC_HASH )
+ pVirtualAlloc = (VIRTUALALLOC)( uiBaseAddress + DEREF_32( uiAddressArray ) );
+
+ // decrement our counter
+ usCounter--;
+ }
+
+ // get the next exported function name
+ uiNameArray += sizeof(DWORD);
+
+ // get the next exported function name ordinal
+ uiNameOrdinals += sizeof(WORD);
+ }
+ }
+ else if( (DWORD)uiValueC == NTDLLDLL_HASH )
+ {
+ // get this modules base address
+ uiBaseAddress = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)uiValueA)->DllBase;
+
+ // get the VA of the modules NT Header
+ uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
+
+ // uiNameArray = the address of the modules export directory entry
+ uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
+
+ // get the VA of the export directory
+ uiExportDir = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
+
+ // get the VA for the array of name pointers
+ uiNameArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames );
+
+ // get the VA for the array of name ordinals
+ uiNameOrdinals = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals );
+
+ usCounter = 1;
+
+ // loop while we still have imports to find
+ while( usCounter > 0 )
+ {
+ // compute the hash values for this function name
+ dwHashValue = hash( (char *)( uiBaseAddress + DEREF_32( uiNameArray ) ) );
+
+ // if we have found a function we want we get its virtual address
+ if( dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH )
+ {
+ // get the VA for the array of addresses
+ uiAddressArray = ( uiBaseAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
+
+ // use this functions name ordinal as an index into the array of name pointers
+ uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
+
+ // store this functions VA
+ if( dwHashValue == NTFLUSHINSTRUCTIONCACHE_HASH )
+ pNtFlushInstructionCache = (NTFLUSHINSTRUCTIONCACHE)( uiBaseAddress + DEREF_32( uiAddressArray ) );
+
+ // decrement our counter
+ usCounter--;
+ }
+
+ // get the next exported function name
+ uiNameArray += sizeof(DWORD);
+
+ // get the next exported function name ordinal
+ uiNameOrdinals += sizeof(WORD);
+ }
+ }
+
+ // we stop searching when we have found everything we need.
+ if( pLoadLibraryA && pGetProcAddress && pVirtualAlloc && pNtFlushInstructionCache )
+ break;
+
+ // get the next entry
+ uiValueA = DEREF( uiValueA );
+ }
+
+ // STEP 2: load our image into a new permanent location in memory...
+
+ // get the VA of the NT Header for the PE to be loaded
+ uiHeaderValue = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
+
+ // allocate all the memory for the DLL to be loaded into. we can load at any address because we will
+ // relocate the image. Also zeros all memory and marks it as READ, WRITE and EXECUTE to avoid any problems.
+ uiBaseAddress = (ULONG_PTR)pVirtualAlloc( NULL, ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfImage, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+
+ // we must now copy over the headers
+ uiValueA = ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.SizeOfHeaders;
+ uiValueB = uiLibraryAddress;
+ uiValueC = uiBaseAddress;
+
+ while( uiValueA-- )
+ *(BYTE *)uiValueC++ = *(BYTE *)uiValueB++;
+
+ // STEP 3: load in all of our sections...
+
+ // uiValueA = the VA of the first section
+ uiValueA = ( (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader + ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.SizeOfOptionalHeader );
+
+ // itterate through all sections, loading them into memory.
+ uiValueE = ((PIMAGE_NT_HEADERS)uiHeaderValue)->FileHeader.NumberOfSections;
+ while( uiValueE-- )
+ {
+ // uiValueB is the VA for this section
+ uiValueB = ( uiBaseAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->VirtualAddress );
+
+ // uiValueC if the VA for this sections data
+ uiValueC = ( uiLibraryAddress + ((PIMAGE_SECTION_HEADER)uiValueA)->PointerToRawData );
+
+ // copy the section over
+ uiValueD = ((PIMAGE_SECTION_HEADER)uiValueA)->SizeOfRawData;
+
+ while( uiValueD-- )
+ *(BYTE *)uiValueB++ = *(BYTE *)uiValueC++;
+
+ // get the VA of the next section
+ uiValueA += sizeof( IMAGE_SECTION_HEADER );
+ }
+
+ // STEP 4: process our images import table...
+
+ // uiValueB = the address of the import directory
+ uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ];
+
+ // we assume their is an import table to process
+ // uiValueC is the first entry in the import table
+ uiValueC = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress );
+
+ // itterate through all imports
+ while( ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name )
+ {
+ // use LoadLibraryA to load the imported module into memory
+ uiLibraryAddress = (ULONG_PTR)pLoadLibraryA( (LPCSTR)( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->Name ) );
+
+ // uiValueD = VA of the OriginalFirstThunk
+ uiValueD = ( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->OriginalFirstThunk );
+
+ // uiValueA = VA of the IAT (via first thunk not origionalfirstthunk)
+ uiValueA = ( uiBaseAddress + ((PIMAGE_IMPORT_DESCRIPTOR)uiValueC)->FirstThunk );
+
+ // itterate through all imported functions, importing by ordinal if no name present
+ while( DEREF(uiValueA) )
+ {
+ // sanity check uiValueD as some compilers only import by FirstThunk
+ if( uiValueD && ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal & IMAGE_ORDINAL_FLAG )
+ {
+ // get the VA of the modules NT Header
+ uiExportDir = uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew;
+
+ // uiNameArray = the address of the modules export directory entry
+ uiNameArray = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
+
+ // get the VA of the export directory
+ uiExportDir = ( uiLibraryAddress + ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress );
+
+ // get the VA for the array of addresses
+ uiAddressArray = ( uiLibraryAddress + ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions );
+
+ // use the import ordinal (- export ordinal base) as an index into the array of addresses
+ uiAddressArray += ( ( IMAGE_ORDINAL( ((PIMAGE_THUNK_DATA)uiValueD)->u1.Ordinal ) - ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->Base ) * sizeof(DWORD) );
+
+ // patch in the address for this imported function
+ DEREF(uiValueA) = ( uiLibraryAddress + DEREF_32(uiAddressArray) );
+ }
+ else
+ {
+ // get the VA of this functions import by name struct
+ uiValueB = ( uiBaseAddress + DEREF(uiValueA) );
+
+ // use GetProcAddress and patch in the address for this imported function
+ DEREF(uiValueA) = (ULONG_PTR)pGetProcAddress( (HMODULE)uiLibraryAddress, (LPCSTR)((PIMAGE_IMPORT_BY_NAME)uiValueB)->Name );
+ }
+ // get the next imported function
+ uiValueA += sizeof( ULONG_PTR );
+ if( uiValueD )
+ uiValueD += sizeof( ULONG_PTR );
+ }
+
+ // get the next import
+ uiValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR );
+ }
+
+ // STEP 5: process all of our images relocations...
+
+ // calculate the base address delta and perform relocations (even if we load at desired image base)
+ uiLibraryAddress = uiBaseAddress - ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.ImageBase;
+
+ // uiValueB = the address of the relocation directory
+ uiValueB = (ULONG_PTR)&((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ];
+
+ // check if their are any relocations present
+ if( ((PIMAGE_DATA_DIRECTORY)uiValueB)->Size )
+ {
+ // uiValueC is now the first entry (IMAGE_BASE_RELOCATION)
+ uiValueC = ( uiBaseAddress + ((PIMAGE_DATA_DIRECTORY)uiValueB)->VirtualAddress );
+
+ // and we itterate through all entries...
+ while( ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock )
+ {
+ // uiValueA = the VA for this relocation block
+ uiValueA = ( uiBaseAddress + ((PIMAGE_BASE_RELOCATION)uiValueC)->VirtualAddress );
+
+ // uiValueB = number of entries in this relocation block
+ uiValueB = ( ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION) ) / sizeof( IMAGE_RELOC );
+
+ // uiValueD is now the first entry in the current relocation block
+ uiValueD = uiValueC + sizeof(IMAGE_BASE_RELOCATION);
+
+ // we itterate through all the entries in the current block...
+ while( uiValueB-- )
+ {
+ // perform the relocation, skipping IMAGE_REL_BASED_ABSOLUTE as required.
+ // we dont use a switch statement to avoid the compiler building a jump table
+ // which would not be very position independent!
+ if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_DIR64 )
+ *(ULONG_PTR *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += uiLibraryAddress;
+ else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGHLOW )
+ *(DWORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += (DWORD)uiLibraryAddress;
+#ifdef WIN_ARM
+ // Note: On ARM, the compiler optimization /O2 seems to introduce an off by one issue, possibly a code gen bug. Using /O1 instead avoids this problem.
+ else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_ARM_MOV32T )
+ {
+ register DWORD dwInstruction;
+ register DWORD dwAddress;
+ register WORD wImm;
+ // get the MOV.T instructions DWORD value (We add 4 to the offset to go past the first MOV.W which handles the low word)
+ dwInstruction = *(DWORD *)( uiValueA + ((PIMAGE_RELOC)uiValueD)->offset + sizeof(DWORD) );
+ // flip the words to get the instruction as expected
+ dwInstruction = MAKELONG( HIWORD(dwInstruction), LOWORD(dwInstruction) );
+ // sanity chack we are processing a MOV instruction...
+ if( (dwInstruction & ARM_MOV_MASK) == ARM_MOVT )
+ {
+ // pull out the encoded 16bit value (the high portion of the address-to-relocate)
+ wImm = (WORD)( dwInstruction & 0x000000FF);
+ wImm |= (WORD)((dwInstruction & 0x00007000) >> 4);
+ wImm |= (WORD)((dwInstruction & 0x04000000) >> 15);
+ wImm |= (WORD)((dwInstruction & 0x000F0000) >> 4);
+ // apply the relocation to the target address
+ dwAddress = ( (WORD)HIWORD(uiLibraryAddress) + wImm ) & 0xFFFF;
+ // now create a new instruction with the same opcode and register param.
+ dwInstruction = (DWORD)( dwInstruction & ARM_MOV_MASK2 );
+ // patch in the relocated address...
+ dwInstruction |= (DWORD)(dwAddress & 0x00FF);
+ dwInstruction |= (DWORD)(dwAddress & 0x0700) << 4;
+ dwInstruction |= (DWORD)(dwAddress & 0x0800) << 15;
+ dwInstruction |= (DWORD)(dwAddress & 0xF000) << 4;
+ // now flip the instructions words and patch back into the code...
+ *(DWORD *)( uiValueA + ((PIMAGE_RELOC)uiValueD)->offset + sizeof(DWORD) ) = MAKELONG( HIWORD(dwInstruction), LOWORD(dwInstruction) );
+ }
+ }
+#endif
+ else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_HIGH )
+ *(WORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += HIWORD(uiLibraryAddress);
+ else if( ((PIMAGE_RELOC)uiValueD)->type == IMAGE_REL_BASED_LOW )
+ *(WORD *)(uiValueA + ((PIMAGE_RELOC)uiValueD)->offset) += LOWORD(uiLibraryAddress);
+
+ // get the next entry in the current relocation block
+ uiValueD += sizeof( IMAGE_RELOC );
+ }
+
+ // get the next entry in the relocation directory
+ uiValueC = uiValueC + ((PIMAGE_BASE_RELOCATION)uiValueC)->SizeOfBlock;
+ }
+ }
+
+ // STEP 6: call our images entry point
+
+ // uiValueA = the VA of our newly loaded DLL/EXE's entry point
+ uiValueA = ( uiBaseAddress + ((PIMAGE_NT_HEADERS)uiHeaderValue)->OptionalHeader.AddressOfEntryPoint );
+
+ // We must flush the instruction cache to avoid stale code being used which was updated by our relocation processing.
+ pNtFlushInstructionCache( (HANDLE)-1, NULL, 0 );
+
+ // call our respective entry point, fudging our hInstance value
+#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
+ // if we are injecting a DLL via LoadRemoteLibraryR we call DllMain and pass in our parameter (via the DllMain lpReserved parameter)
+ ((DLLMAIN)uiValueA)( (HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, lpParameter );
+#else
+ // if we are injecting an DLL via a stub we call DllMain with no parameter
+ ((DLLMAIN)uiValueA)( (HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, NULL );
+#endif
+
+ // STEP 8: return our new entry point address so whatever called us can call DllMain() if needed.
+ return uiValueA;
+}
+//===============================================================================================//
+#ifndef REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
+
+BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
+{
+ BOOL bReturnValue = TRUE;
+ switch( dwReason )
+ {
+ case DLL_QUERY_HMODULE:
+ if( lpReserved != NULL )
+ *(HMODULE *)lpReserved = hAppInstance;
+ break;
+ case DLL_PROCESS_ATTACH:
+ hAppInstance = hinstDLL;
+ break;
+ case DLL_PROCESS_DETACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ break;
+ }
+ return bReturnValue;
+}
+
+#endif
+//===============================================================================================//
diff --git a/Inject/ReflectiveDLLInjection/dll/src/ReflectiveLoader.h b/Inject/ReflectiveDLLInjection/dll/src/ReflectiveLoader.h
new file mode 100644
index 0000000..700c335
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/dll/src/ReflectiveLoader.h
@@ -0,0 +1,203 @@
+//===============================================================================================//
+// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are permitted
+// provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// * Neither the name of Harmony Security nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//===============================================================================================//
+#ifndef _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H
+#define _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H
+//===============================================================================================//
+#define WIN32_LEAN_AND_MEAN
+#include
+#include
+#include
+
+#include "ReflectiveDLLInjection.h"
+
+typedef HMODULE (WINAPI * LOADLIBRARYA)( LPCSTR );
+typedef FARPROC (WINAPI * GETPROCADDRESS)( HMODULE, LPCSTR );
+typedef LPVOID (WINAPI * VIRTUALALLOC)( LPVOID, SIZE_T, DWORD, DWORD );
+typedef DWORD (NTAPI * NTFLUSHINSTRUCTIONCACHE)( HANDLE, PVOID, ULONG );
+
+#define KERNEL32DLL_HASH 0x6A4ABC5B
+#define NTDLLDLL_HASH 0x3CFA685D
+
+#define LOADLIBRARYA_HASH 0xEC0E4E8E
+#define GETPROCADDRESS_HASH 0x7C0DFCAA
+#define VIRTUALALLOC_HASH 0x91AFCA54
+#define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8
+
+#define IMAGE_REL_BASED_ARM_MOV32A 5
+#define IMAGE_REL_BASED_ARM_MOV32T 7
+
+#define ARM_MOV_MASK (DWORD)(0xFBF08000)
+#define ARM_MOV_MASK2 (DWORD)(0xFBF08F00)
+#define ARM_MOVW 0xF2400000
+#define ARM_MOVT 0xF2C00000
+
+#define HASH_KEY 13
+//===============================================================================================//
+#pragma intrinsic( _rotr )
+
+__forceinline DWORD ror( DWORD d )
+{
+ return _rotr( d, HASH_KEY );
+}
+
+__forceinline DWORD hash( char * c )
+{
+ register DWORD h = 0;
+ do
+ {
+ h = ror( h );
+ h += *c;
+ } while( *++c );
+
+ return h;
+}
+//===============================================================================================//
+typedef struct _UNICODE_STR
+{
+ USHORT Length;
+ USHORT MaximumLength;
+ PWSTR pBuffer;
+} UNICODE_STR, *PUNICODE_STR;
+
+// WinDbg> dt -v ntdll!_LDR_DATA_TABLE_ENTRY
+//__declspec( align(8) )
+typedef struct _LDR_DATA_TABLE_ENTRY
+{
+ //LIST_ENTRY InLoadOrderLinks; // As we search from PPEB_LDR_DATA->InMemoryOrderModuleList we dont use the first entry.
+ LIST_ENTRY InMemoryOrderModuleList;
+ LIST_ENTRY InInitializationOrderModuleList;
+ PVOID DllBase;
+ PVOID EntryPoint;
+ ULONG SizeOfImage;
+ UNICODE_STR FullDllName;
+ UNICODE_STR BaseDllName;
+ ULONG Flags;
+ SHORT LoadCount;
+ SHORT TlsIndex;
+ LIST_ENTRY HashTableEntry;
+ ULONG TimeDateStamp;
+} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
+
+// WinDbg> dt -v ntdll!_PEB_LDR_DATA
+typedef struct _PEB_LDR_DATA //, 7 elements, 0x28 bytes
+{
+ DWORD dwLength;
+ DWORD dwInitialized;
+ LPVOID lpSsHandle;
+ LIST_ENTRY InLoadOrderModuleList;
+ LIST_ENTRY InMemoryOrderModuleList;
+ LIST_ENTRY InInitializationOrderModuleList;
+ LPVOID lpEntryInProgress;
+} PEB_LDR_DATA, * PPEB_LDR_DATA;
+
+// WinDbg> dt -v ntdll!_PEB_FREE_BLOCK
+typedef struct _PEB_FREE_BLOCK // 2 elements, 0x8 bytes
+{
+ struct _PEB_FREE_BLOCK * pNext;
+ DWORD dwSize;
+} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;
+
+// struct _PEB is defined in Winternl.h but it is incomplete
+// WinDbg> dt -v ntdll!_PEB
+typedef struct __PEB // 65 elements, 0x210 bytes
+{
+ BYTE bInheritedAddressSpace;
+ BYTE bReadImageFileExecOptions;
+ BYTE bBeingDebugged;
+ BYTE bSpareBool;
+ LPVOID lpMutant;
+ LPVOID lpImageBaseAddress;
+ PPEB_LDR_DATA pLdr;
+ LPVOID lpProcessParameters;
+ LPVOID lpSubSystemData;
+ LPVOID lpProcessHeap;
+ PRTL_CRITICAL_SECTION pFastPebLock;
+ LPVOID lpFastPebLockRoutine;
+ LPVOID lpFastPebUnlockRoutine;
+ DWORD dwEnvironmentUpdateCount;
+ LPVOID lpKernelCallbackTable;
+ DWORD dwSystemReserved;
+ DWORD dwAtlThunkSListPtr32;
+ PPEB_FREE_BLOCK pFreeList;
+ DWORD dwTlsExpansionCounter;
+ LPVOID lpTlsBitmap;
+ DWORD dwTlsBitmapBits[2];
+ LPVOID lpReadOnlySharedMemoryBase;
+ LPVOID lpReadOnlySharedMemoryHeap;
+ LPVOID lpReadOnlyStaticServerData;
+ LPVOID lpAnsiCodePageData;
+ LPVOID lpOemCodePageData;
+ LPVOID lpUnicodeCaseTableData;
+ DWORD dwNumberOfProcessors;
+ DWORD dwNtGlobalFlag;
+ LARGE_INTEGER liCriticalSectionTimeout;
+ DWORD dwHeapSegmentReserve;
+ DWORD dwHeapSegmentCommit;
+ DWORD dwHeapDeCommitTotalFreeThreshold;
+ DWORD dwHeapDeCommitFreeBlockThreshold;
+ DWORD dwNumberOfHeaps;
+ DWORD dwMaximumNumberOfHeaps;
+ LPVOID lpProcessHeaps;
+ LPVOID lpGdiSharedHandleTable;
+ LPVOID lpProcessStarterHelper;
+ DWORD dwGdiDCAttributeList;
+ LPVOID lpLoaderLock;
+ DWORD dwOSMajorVersion;
+ DWORD dwOSMinorVersion;
+ WORD wOSBuildNumber;
+ WORD wOSCSDVersion;
+ DWORD dwOSPlatformId;
+ DWORD dwImageSubsystem;
+ DWORD dwImageSubsystemMajorVersion;
+ DWORD dwImageSubsystemMinorVersion;
+ DWORD dwImageProcessAffinityMask;
+ DWORD dwGdiHandleBuffer[34];
+ LPVOID lpPostProcessInitRoutine;
+ LPVOID lpTlsExpansionBitmap;
+ DWORD dwTlsExpansionBitmapBits[32];
+ DWORD dwSessionId;
+ ULARGE_INTEGER liAppCompatFlags;
+ ULARGE_INTEGER liAppCompatFlagsUser;
+ LPVOID lppShimData;
+ LPVOID lpAppCompatInfo;
+ UNICODE_STR usCSDVersion;
+ LPVOID lpActivationContextData;
+ LPVOID lpProcessAssemblyStorageMap;
+ LPVOID lpSystemDefaultActivationContextData;
+ LPVOID lpSystemAssemblyStorageMap;
+ DWORD dwMinimumStackCommit;
+} _PEB, * _PPEB;
+
+typedef struct
+{
+ WORD offset:12;
+ WORD type:4;
+} IMAGE_RELOC, *PIMAGE_RELOC;
+//===============================================================================================//
+#endif
+//===============================================================================================//
diff --git a/Inject/ReflectiveDLLInjection/inject/inject.sln b/Inject/ReflectiveDLLInjection/inject/inject.sln
new file mode 100644
index 0000000..6592be3
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/inject/inject.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inject", "inject.vcxproj", "{EEF3FD41-05D8-4A07-8434-EF5D34D76335}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|Win32.ActiveCfg = Release|Win32
+ {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Debug|Win32.Build.0 = Release|Win32
+ {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|Win32.ActiveCfg = Release|Win32
+ {EEF3FD41-05D8-4A07-8434-EF5D34D76335}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Inject/ReflectiveDLLInjection/inject/inject.vcxproj b/Inject/ReflectiveDLLInjection/inject/inject.vcxproj
new file mode 100644
index 0000000..742415d
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/inject/inject.vcxproj
@@ -0,0 +1,190 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {EEF3FD41-05D8-4A07-8434-EF5D34D76335}
+ inject
+ Win32Proj
+
+
+
+ Application
+ MultiByte
+ true
+
+
+ Application
+ Unicode
+
+
+ Application
+ MultiByte
+ true
+
+
+ Application
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ true
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ true
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ false
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ false
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+
+
+
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+ EditAndContinue
+
+
+ true
+ Console
+ MachineX86
+
+
+
+
+ X64
+
+
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+ ProgramDatabase
+
+
+ true
+ Console
+ MachineX64
+
+
+
+
+ MaxSpeed
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ MultiThreaded
+ true
+
+
+ Level3
+ ProgramDatabase
+
+
+ true
+ Console
+ true
+ true
+ MachineX86
+
+
+ copy ..\Release\inject.exe ..\bin\
+
+
+
+
+ X64
+
+
+ MaxSpeed
+ true
+ WIN64;NDEBUG;_CONSOLE;_WIN64;%(PreprocessorDefinitions)
+ MultiThreaded
+ true
+
+
+ Level3
+ ProgramDatabase
+
+
+ $(OutDir)inject.x64.exe
+ true
+ Console
+ true
+ true
+ MachineX64
+
+
+ copy ..\x64\Release\inject.x64.exe ..\bin\
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Inject/ReflectiveDLLInjection/inject/inject.vcxproj.filters b/Inject/ReflectiveDLLInjection/inject/inject.vcxproj.filters
new file mode 100644
index 0000000..418896d
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/inject/inject.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/Inject/ReflectiveDLLInjection/inject/src/GetProcAddressR.c b/Inject/ReflectiveDLLInjection/inject/src/GetProcAddressR.c
new file mode 100644
index 0000000..144ab6e
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/inject/src/GetProcAddressR.c
@@ -0,0 +1,116 @@
+//===============================================================================================//
+// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are permitted
+// provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// * Neither the name of Harmony Security nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//===============================================================================================//
+#include "GetProcAddressR.h"
+//===============================================================================================//
+// We implement a minimal GetProcAddress to avoid using the native kernel32!GetProcAddress which
+// wont be able to resolve exported addresses in reflectivly loaded librarys.
+FARPROC WINAPI GetProcAddressR( HANDLE hModule, LPCSTR lpProcName )
+{
+ UINT_PTR uiLibraryAddress = 0;
+ FARPROC fpResult = NULL;
+
+ if( hModule == NULL )
+ return NULL;
+
+ // a module handle is really its base address
+ uiLibraryAddress = (UINT_PTR)hModule;
+
+ __try
+ {
+ UINT_PTR uiAddressArray = 0;
+ UINT_PTR uiNameArray = 0;
+ UINT_PTR uiNameOrdinals = 0;
+ PIMAGE_NT_HEADERS pNtHeaders = NULL;
+ PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
+ PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
+
+ // get the VA of the modules NT Header
+ pNtHeaders = (PIMAGE_NT_HEADERS)(uiLibraryAddress + ((PIMAGE_DOS_HEADER)uiLibraryAddress)->e_lfanew);
+
+ pDataDirectory = (PIMAGE_DATA_DIRECTORY)&pNtHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
+
+ // get the VA of the export directory
+ pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)( uiLibraryAddress + pDataDirectory->VirtualAddress );
+
+ // get the VA for the array of addresses
+ uiAddressArray = ( uiLibraryAddress + pExportDirectory->AddressOfFunctions );
+
+ // get the VA for the array of name pointers
+ uiNameArray = ( uiLibraryAddress + pExportDirectory->AddressOfNames );
+
+ // get the VA for the array of name ordinals
+ uiNameOrdinals = ( uiLibraryAddress + pExportDirectory->AddressOfNameOrdinals );
+
+ // test if we are importing by name or by ordinal...
+ if( ((DWORD)lpProcName & 0xFFFF0000 ) == 0x00000000 )
+ {
+ // import by ordinal...
+
+ // use the import ordinal (- export ordinal base) as an index into the array of addresses
+ uiAddressArray += ( ( IMAGE_ORDINAL( (DWORD)lpProcName ) - pExportDirectory->Base ) * sizeof(DWORD) );
+
+ // resolve the address for this imported function
+ fpResult = (FARPROC)( uiLibraryAddress + DEREF_32(uiAddressArray) );
+ }
+ else
+ {
+ // import by name...
+ DWORD dwCounter = pExportDirectory->NumberOfNames;
+ while( dwCounter-- )
+ {
+ char * cpExportedFunctionName = (char *)(uiLibraryAddress + DEREF_32( uiNameArray ));
+
+ // test if we have a match...
+ if( strcmp( cpExportedFunctionName, lpProcName ) == 0 )
+ {
+ // use the functions name ordinal as an index into the array of name pointers
+ uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
+
+ // calculate the virtual address for the function
+ fpResult = (FARPROC)(uiLibraryAddress + DEREF_32( uiAddressArray ));
+
+ // finish...
+ break;
+ }
+
+ // get the next exported function name
+ uiNameArray += sizeof(DWORD);
+
+ // get the next exported function name ordinal
+ uiNameOrdinals += sizeof(WORD);
+ }
+ }
+ }
+ __except( EXCEPTION_EXECUTE_HANDLER )
+ {
+ fpResult = NULL;
+ }
+
+ return fpResult;
+}
+//===============================================================================================//
\ No newline at end of file
diff --git a/Inject/ReflectiveDLLInjection/inject/src/GetProcAddressR.h b/Inject/ReflectiveDLLInjection/inject/src/GetProcAddressR.h
new file mode 100644
index 0000000..ac15017
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/inject/src/GetProcAddressR.h
@@ -0,0 +1,36 @@
+//===============================================================================================//
+// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are permitted
+// provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// * Neither the name of Harmony Security nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//===============================================================================================//
+#ifndef _REFLECTIVEDLLINJECTION_GETPROCADDRESSR_H
+#define _REFLECTIVEDLLINJECTION_GETPROCADDRESSR_H
+//===============================================================================================//
+#include "ReflectiveDLLInjection.h"
+
+FARPROC WINAPI GetProcAddressR( HANDLE hModule, LPCSTR lpProcName );
+//===============================================================================================//
+#endif
+//===============================================================================================//
diff --git a/Inject/ReflectiveDLLInjection/inject/src/Inject.c b/Inject/ReflectiveDLLInjection/inject/src/Inject.c
new file mode 100644
index 0000000..479d04c
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/inject/src/Inject.c
@@ -0,0 +1,120 @@
+//===============================================================================================//
+// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are permitted
+// provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// * Neither the name of Harmony Security nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//===============================================================================================//
+#define WIN32_LEAN_AND_MEAN
+#include
+#include
+#include
+#include "LoadLibraryR.h"
+
+#pragma comment(lib,"Advapi32.lib")
+
+#define BREAK_WITH_ERROR( e ) { printf( "[-] %s. Error=%d", e, GetLastError() ); break; }
+
+// Simple app to inject a reflective DLL into a process vis its process ID.
+int main( int argc, char * argv[] )
+{
+ HANDLE hFile = NULL;
+ HANDLE hModule = NULL;
+ HANDLE hProcess = NULL;
+ HANDLE hToken = NULL;
+ LPVOID lpBuffer = NULL;
+ DWORD dwLength = 0;
+ DWORD dwBytesRead = 0;
+ DWORD dwProcessId = 0;
+ TOKEN_PRIVILEGES priv = {0};
+
+#ifdef WIN_X64
+ char * cpDllFile = "reflective_dll.x64.dll";
+#else
+#ifdef WIN_X86
+ char * cpDllFile = "reflective_dll.dll";
+#else WIN_ARM
+ char * cpDllFile = "reflective_dll.arm.dll";
+#endif
+#endif
+
+ do
+ {
+ // Usage: inject.exe [pid] [dll_file]
+
+ if( argc == 1 )
+ dwProcessId = GetCurrentProcessId();
+ else
+ dwProcessId = atoi( argv[1] );
+
+ if( argc >= 3 )
+ cpDllFile = argv[2];
+
+ hFile = CreateFileA( cpDllFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ if( hFile == INVALID_HANDLE_VALUE )
+ BREAK_WITH_ERROR( "Failed to open the DLL file" );
+
+ dwLength = GetFileSize( hFile, NULL );
+ if( dwLength == INVALID_FILE_SIZE || dwLength == 0 )
+ BREAK_WITH_ERROR( "Failed to get the DLL file size" );
+
+ lpBuffer = HeapAlloc( GetProcessHeap(), 0, dwLength );
+ if( !lpBuffer )
+ BREAK_WITH_ERROR( "Failed to get the DLL file size" );
+
+ if( ReadFile( hFile, lpBuffer, dwLength, &dwBytesRead, NULL ) == FALSE )
+ BREAK_WITH_ERROR( "Failed to alloc a buffer!" );
+
+ if( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
+ {
+ priv.PrivilegeCount = 1;
+ priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+ if( LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid ) )
+ AdjustTokenPrivileges( hToken, FALSE, &priv, 0, NULL, NULL );
+
+ CloseHandle( hToken );
+ }
+
+ hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwProcessId );
+ if( !hProcess )
+ BREAK_WITH_ERROR( "Failed to open the target process" );
+
+ hModule = LoadRemoteLibraryR( hProcess, lpBuffer, dwLength, NULL );
+ if( !hModule )
+ BREAK_WITH_ERROR( "Failed to inject the DLL" );
+
+ printf( "[+] Injected the '%s' DLL into process %d.", cpDllFile, dwProcessId );
+
+ WaitForSingleObject( hModule, -1 );
+
+ } while( 0 );
+
+ if( lpBuffer )
+ HeapFree( GetProcessHeap(), 0, lpBuffer );
+
+ if( hProcess )
+ CloseHandle( hProcess );
+
+ return 0;
+}
\ No newline at end of file
diff --git a/Inject/ReflectiveDLLInjection/inject/src/LoadLibraryR.c b/Inject/ReflectiveDLLInjection/inject/src/LoadLibraryR.c
new file mode 100644
index 0000000..030dd75
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/inject/src/LoadLibraryR.c
@@ -0,0 +1,234 @@
+//===============================================================================================//
+// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are permitted
+// provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// * Neither the name of Harmony Security nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//===============================================================================================//
+#include "LoadLibraryR.h"
+#include
+//===============================================================================================//
+DWORD Rva2Offset( DWORD dwRva, UINT_PTR uiBaseAddress )
+{
+ WORD wIndex = 0;
+ PIMAGE_SECTION_HEADER pSectionHeader = NULL;
+ PIMAGE_NT_HEADERS pNtHeaders = NULL;
+
+ pNtHeaders = (PIMAGE_NT_HEADERS)(uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew);
+
+ pSectionHeader = (PIMAGE_SECTION_HEADER)((UINT_PTR)(&pNtHeaders->OptionalHeader) + pNtHeaders->FileHeader.SizeOfOptionalHeader);
+
+ if( dwRva < pSectionHeader[0].PointerToRawData )
+ return dwRva;
+
+ for( wIndex=0 ; wIndex < pNtHeaders->FileHeader.NumberOfSections ; wIndex++ )
+ {
+ if( dwRva >= pSectionHeader[wIndex].VirtualAddress && dwRva < (pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].SizeOfRawData) )
+ return ( dwRva - pSectionHeader[wIndex].VirtualAddress + pSectionHeader[wIndex].PointerToRawData );
+ }
+
+ return 0;
+}
+//===============================================================================================//
+DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer )
+{
+ UINT_PTR uiBaseAddress = 0;
+ UINT_PTR uiExportDir = 0;
+ UINT_PTR uiNameArray = 0;
+ UINT_PTR uiAddressArray = 0;
+ UINT_PTR uiNameOrdinals = 0;
+ DWORD dwCounter = 0;
+#ifdef WIN_X64
+ DWORD dwCompiledArch = 2;
+#else
+ // This will catch Win32 and WinRT.
+ DWORD dwCompiledArch = 1;
+#endif
+
+ uiBaseAddress = (UINT_PTR)lpReflectiveDllBuffer;
+
+ // get the File Offset of the modules NT Header
+ uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew;
+
+ // currenlty we can only process a PE file which is the same type as the one this fuction has
+ // been compiled as, due to various offset in the PE structures being defined at compile time.
+ if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x010B ) // PE32
+ {
+ if( dwCompiledArch != 1 )
+ return 0;
+ }
+ else if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x020B ) // PE64
+ {
+ if( dwCompiledArch != 2 )
+ return 0;
+ }
+ else
+ {
+ return 0;
+ }
+
+ // uiNameArray = the address of the modules export directory entry
+ uiNameArray = (UINT_PTR)&((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
+
+ // get the File Offset of the export directory
+ uiExportDir = uiBaseAddress + Rva2Offset( ((PIMAGE_DATA_DIRECTORY)uiNameArray)->VirtualAddress, uiBaseAddress );
+
+ // get the File Offset for the array of name pointers
+ uiNameArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNames, uiBaseAddress );
+
+ // get the File Offset for the array of addresses
+ uiAddressArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress );
+
+ // get the File Offset for the array of name ordinals
+ uiNameOrdinals = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfNameOrdinals, uiBaseAddress );
+
+ // get a counter for the number of exported functions...
+ dwCounter = ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->NumberOfNames;
+
+ // loop through all the exported functions to find the ReflectiveLoader
+ while( dwCounter-- )
+ {
+ char * cpExportedFunctionName = (char *)(uiBaseAddress + Rva2Offset( DEREF_32( uiNameArray ), uiBaseAddress ));
+
+ if( strstr( cpExportedFunctionName, "ReflectiveLoader" ) != NULL )
+ {
+ // get the File Offset for the array of addresses
+ uiAddressArray = uiBaseAddress + Rva2Offset( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir)->AddressOfFunctions, uiBaseAddress );
+
+ // use the functions name ordinal as an index into the array of name pointers
+ uiAddressArray += ( DEREF_16( uiNameOrdinals ) * sizeof(DWORD) );
+
+ // return the File Offset to the ReflectiveLoader() functions code...
+ return Rva2Offset( DEREF_32( uiAddressArray ), uiBaseAddress );
+ }
+ // get the next exported function name
+ uiNameArray += sizeof(DWORD);
+
+ // get the next exported function name ordinal
+ uiNameOrdinals += sizeof(WORD);
+ }
+
+ return 0;
+}
+//===============================================================================================//
+// Loads a DLL image from memory via its exported ReflectiveLoader function
+HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength )
+{
+ HMODULE hResult = NULL;
+ DWORD dwReflectiveLoaderOffset = 0;
+ DWORD dwOldProtect1 = 0;
+ DWORD dwOldProtect2 = 0;
+ REFLECTIVELOADER pReflectiveLoader = NULL;
+ DLLMAIN pDllMain = NULL;
+
+ if( lpBuffer == NULL || dwLength == 0 )
+ return NULL;
+
+ __try
+ {
+ // check if the library has a ReflectiveLoader...
+ dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer );
+ if( dwReflectiveLoaderOffset != 0 )
+ {
+ pReflectiveLoader = (REFLECTIVELOADER)((UINT_PTR)lpBuffer + dwReflectiveLoaderOffset);
+
+ // we must VirtualProtect the buffer to RWX so we can execute the ReflectiveLoader...
+ // this assumes lpBuffer is the base address of the region of pages and dwLength the size of the region
+ if( VirtualProtect( lpBuffer, dwLength, PAGE_EXECUTE_READWRITE, &dwOldProtect1 ) )
+ {
+ // call the librarys ReflectiveLoader...
+ pDllMain = (DLLMAIN)pReflectiveLoader();
+ if( pDllMain != NULL )
+ {
+ // call the loaded librarys DllMain to get its HMODULE
+ if( !pDllMain( NULL, DLL_QUERY_HMODULE, &hResult ) )
+ hResult = NULL;
+ }
+ // revert to the previous protection flags...
+ VirtualProtect( lpBuffer, dwLength, dwOldProtect1, &dwOldProtect2 );
+ }
+ }
+ }
+ __except( EXCEPTION_EXECUTE_HANDLER )
+ {
+ hResult = NULL;
+ }
+
+ return hResult;
+}
+//===============================================================================================//
+// Loads a PE image from memory into the address space of a host process via the image's exported ReflectiveLoader function
+// Note: You must compile whatever you are injecting with REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
+// defined in order to use the correct RDI prototypes.
+// Note: The hProcess handle must have these access rights: PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
+// PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ
+// Note: If you are passing in an lpParameter value, if it is a pointer, remember it is for a different address space.
+// Note: This function currently cant inject accross architectures, but only to architectures which are the
+// same as the arch this function is compiled as, e.g. x86->x86 and x64->x64 but not x64->x86 or x86->x64.
+HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter )
+{
+ BOOL bSuccess = FALSE;
+ LPVOID lpRemoteLibraryBuffer = NULL;
+ LPTHREAD_START_ROUTINE lpReflectiveLoader = NULL;
+ HANDLE hThread = NULL;
+ DWORD dwReflectiveLoaderOffset = 0;
+ DWORD dwThreadId = 0;
+
+ __try
+ {
+ do
+ {
+ if( !hProcess || !lpBuffer || !dwLength )
+ break;
+
+ // check if the library has a ReflectiveLoader...
+ dwReflectiveLoaderOffset = GetReflectiveLoaderOffset( lpBuffer );
+ if( !dwReflectiveLoaderOffset )
+ break;
+
+ // alloc memory (RWX) in the host process for the image...
+ lpRemoteLibraryBuffer = VirtualAllocEx( hProcess, NULL, dwLength, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+ if( !lpRemoteLibraryBuffer )
+ break;
+
+ // write the image into the host process...
+ if( !WriteProcessMemory( hProcess, lpRemoteLibraryBuffer, lpBuffer, dwLength, NULL ) )
+ break;
+
+ // add the offset to ReflectiveLoader() to the remote library address...
+ lpReflectiveLoader = (LPTHREAD_START_ROUTINE)( (ULONG_PTR)lpRemoteLibraryBuffer + dwReflectiveLoaderOffset );
+
+ // create a remote thread in the host process to call the ReflectiveLoader!
+ hThread = CreateRemoteThread( hProcess, NULL, 1024*1024, lpReflectiveLoader, lpParameter, (DWORD)NULL, &dwThreadId );
+
+ } while( 0 );
+
+ }
+ __except( EXCEPTION_EXECUTE_HANDLER )
+ {
+ hThread = NULL;
+ }
+
+ return hThread;
+}
+//===============================================================================================//
diff --git a/Inject/ReflectiveDLLInjection/inject/src/LoadLibraryR.h b/Inject/ReflectiveDLLInjection/inject/src/LoadLibraryR.h
new file mode 100644
index 0000000..21154d3
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/inject/src/LoadLibraryR.h
@@ -0,0 +1,41 @@
+//===============================================================================================//
+// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are permitted
+// provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// * Neither the name of Harmony Security nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//===============================================================================================//
+#ifndef _REFLECTIVEDLLINJECTION_LOADLIBRARYR_H
+#define _REFLECTIVEDLLINJECTION_LOADLIBRARYR_H
+//===============================================================================================//
+#include "ReflectiveDLLInjection.h"
+
+DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer );
+
+HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength );
+
+HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLength, LPVOID lpParameter );
+
+//===============================================================================================//
+#endif
+//===============================================================================================//
diff --git a/Inject/ReflectiveDLLInjection/inject/src/ReflectiveDLLInjection.h b/Inject/ReflectiveDLLInjection/inject/src/ReflectiveDLLInjection.h
new file mode 100644
index 0000000..c804a91
--- /dev/null
+++ b/Inject/ReflectiveDLLInjection/inject/src/ReflectiveDLLInjection.h
@@ -0,0 +1,53 @@
+//===============================================================================================//
+// Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are permitted
+// provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice, this list of
+// conditions and the following disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// * Neither the name of Harmony Security nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//===============================================================================================//
+#ifndef _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
+#define _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H
+//===============================================================================================//
+#define WIN32_LEAN_AND_MEAN
+#include
+
+// we declare some common stuff in here...
+
+#define DLL_METASPLOIT_ATTACH 4
+#define DLL_METASPLOIT_DETACH 5
+#define DLL_QUERY_HMODULE 6
+
+#define DEREF( name )*(UINT_PTR *)(name)
+#define DEREF_64( name )*(DWORD64 *)(name)
+#define DEREF_32( name )*(DWORD *)(name)
+#define DEREF_16( name )*(WORD *)(name)
+#define DEREF_8( name )*(BYTE *)(name)
+
+typedef ULONG_PTR (WINAPI * REFLECTIVELOADER)( VOID );
+typedef BOOL (WINAPI * DLLMAIN)( HINSTANCE, DWORD, LPVOID );
+
+#define DLLEXPORT __declspec( dllexport )
+
+//===============================================================================================//
+#endif
+//===============================================================================================//