11//===============================================================================================//
22// Copyright (c) 2013, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
33// All rights reserved.
4- //
5- // Redistribution and use in source and binary forms, with or without modification, are permitted
4+ //
5+ // Redistribution and use in source and binary forms, with or without modification, are permitted
66// provided that the following conditions are met:
7- //
8- // * Redistributions of source code must retain the above copyright notice, this list of
7+ //
8+ // * Redistributions of source code must retain the above copyright notice, this list of
99// conditions and the following disclaimer.
10- //
11- // * Redistributions in binary form must reproduce the above copyright notice, this list of
12- // conditions and the following disclaimer in the documentation and/or other materials provided
10+ //
11+ // * Redistributions in binary form must reproduce the above copyright notice, this list of
12+ // conditions and the following disclaimer in the documentation and/or other materials provided
1313// with the distribution.
14- //
14+ //
1515// * Neither the name of Harmony Security nor the names of its contributors may be used to
1616// endorse or promote products derived from this software without specific prior written permission.
17- //
18- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
17+ //
18+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
1919// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20- // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21- // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22- // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23- // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25- // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
20+ // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21+ // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22+ // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23+ // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25+ // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2626// POSSIBILITY OF SUCH DAMAGE.
2727//===============================================================================================//
2828#include "LoadLibraryR.h"
2929//===============================================================================================//
30- DWORD Rva2Offset ( DWORD dwRva , UINT_PTR uiBaseAddress )
31- {
30+ DWORD Rva2Offset ( DWORD dwRva , UINT_PTR uiBaseAddress , BOOL is64 )
31+ {
3232 WORD wIndex = 0 ;
3333 PIMAGE_SECTION_HEADER pSectionHeader = NULL ;
34- PIMAGE_NT_HEADERS pNtHeaders = NULL ;
35-
36- pNtHeaders = (PIMAGE_NT_HEADERS )(uiBaseAddress + ((PIMAGE_DOS_HEADER )uiBaseAddress )-> e_lfanew );
37-
38- pSectionHeader = (PIMAGE_SECTION_HEADER )((UINT_PTR )(& pNtHeaders -> OptionalHeader ) + pNtHeaders -> FileHeader .SizeOfOptionalHeader );
39-
40- if ( dwRva < pSectionHeader [0 ].PointerToRawData )
41- return dwRva ;
42-
43- for ( wIndex = 0 ; wIndex < pNtHeaders -> FileHeader .NumberOfSections ; wIndex ++ )
44- {
45- if ( dwRva >= pSectionHeader [wIndex ].VirtualAddress && dwRva < (pSectionHeader [wIndex ].VirtualAddress + pSectionHeader [wIndex ].SizeOfRawData ) )
46- return ( dwRva - pSectionHeader [wIndex ].VirtualAddress + pSectionHeader [wIndex ].PointerToRawData );
47- }
48-
49- return 0 ;
34+ PIMAGE_NT_HEADERS32 pNtHeaders32 = NULL ;
35+ PIMAGE_NT_HEADERS64 pNtHeaders64 = NULL ;
36+
37+ if (is64 ) {
38+ pNtHeaders64 = (PIMAGE_NT_HEADERS64 )(uiBaseAddress + ((PIMAGE_DOS_HEADER )uiBaseAddress )-> e_lfanew );
39+
40+ pSectionHeader = (PIMAGE_SECTION_HEADER )((UINT_PTR )(& pNtHeaders64 -> OptionalHeader ) + pNtHeaders64 -> FileHeader .SizeOfOptionalHeader );
41+
42+ if ( dwRva < pSectionHeader [0 ].PointerToRawData )
43+ return dwRva ;
44+
45+ for ( wIndex = 0 ; wIndex < pNtHeaders64 -> FileHeader .NumberOfSections ; wIndex ++ )
46+ {
47+ if ( dwRva >= pSectionHeader [wIndex ].VirtualAddress && dwRva < (pSectionHeader [wIndex ].VirtualAddress + pSectionHeader [wIndex ].SizeOfRawData ) )
48+ return ( dwRva - pSectionHeader [wIndex ].VirtualAddress + pSectionHeader [wIndex ].PointerToRawData );
49+ }
50+ }
51+ else {
52+ pNtHeaders32 = (PIMAGE_NT_HEADERS32 )(uiBaseAddress + ((PIMAGE_DOS_HEADER )uiBaseAddress )-> e_lfanew );
53+
54+ pSectionHeader = (PIMAGE_SECTION_HEADER )((UINT_PTR )(& pNtHeaders32 -> OptionalHeader ) + pNtHeaders32 -> FileHeader .SizeOfOptionalHeader );
55+
56+ if ( dwRva < pSectionHeader [0 ].PointerToRawData )
57+ return dwRva ;
58+
59+ for ( wIndex = 0 ; wIndex < pNtHeaders32 -> FileHeader .NumberOfSections ; wIndex ++ )
60+ {
61+ if ( dwRva >= pSectionHeader [wIndex ].VirtualAddress && dwRva < (pSectionHeader [wIndex ].VirtualAddress + pSectionHeader [wIndex ].SizeOfRawData ) )
62+ return ( dwRva - pSectionHeader [wIndex ].VirtualAddress + pSectionHeader [wIndex ].PointerToRawData );
63+ }
64+ }
65+
66+ return 0 ;
5067}
5168//===============================================================================================//
5269DWORD GetReflectiveLoaderOffset ( VOID * lpReflectiveDllBuffer )
@@ -57,68 +74,63 @@ DWORD GetReflectiveLoaderOffset( VOID * lpReflectiveDllBuffer )
5774 UINT_PTR uiAddressArray = 0 ;
5875 UINT_PTR uiNameOrdinals = 0 ;
5976 DWORD dwCounter = 0 ;
60- #ifdef _WIN64
61- DWORD dwMeterpreterArch = 2 ;
62- #else
63- // This will catch Win32 and WinRT.
64- DWORD dwMeterpreterArch = 1 ;
65- #endif
77+ BOOL is64 = 0 ;
6678
6779 uiBaseAddress = (UINT_PTR )lpReflectiveDllBuffer ;
6880
6981 // get the File Offset of the modules NT Header
7082 uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER )uiBaseAddress )-> e_lfanew ;
7183
72- // currenlty we can only process a PE file which is the same type as the one this fuction has
73- // been compiled as, due to various offset in the PE structures being defined at compile time.
84+ // process a PE file based on its architecture
7485 if ( ((PIMAGE_NT_HEADERS )uiExportDir )-> OptionalHeader .Magic == 0x010B ) // PE32
7586 {
76- if ( dwMeterpreterArch != 1 )
77- return 0 ;
87+ is64 = FALSE;
88+ // uiNameArray = the address of the modules export directory entry
89+ uiNameArray = (UINT_PTR )& ((PIMAGE_NT_HEADERS32 )uiExportDir )-> OptionalHeader .DataDirectory [ IMAGE_DIRECTORY_ENTRY_EXPORT ];
90+
7891 }
7992 else if ( ((PIMAGE_NT_HEADERS )uiExportDir )-> OptionalHeader .Magic == 0x020B ) // PE64
8093 {
81- if ( dwMeterpreterArch != 2 )
82- return 0 ;
94+ is64 = TRUE;
95+ // uiNameArray = the address of the modules export directory entry
96+ uiNameArray = (UINT_PTR )& ((PIMAGE_NT_HEADERS64 )uiExportDir )-> OptionalHeader .DataDirectory [ IMAGE_DIRECTORY_ENTRY_EXPORT ];
97+
8398 }
8499 else
85100 {
86101 return 0 ;
87102 }
88103
89- // uiNameArray = the address of the modules export directory entry
90- uiNameArray = (UINT_PTR )& ((PIMAGE_NT_HEADERS )uiExportDir )-> OptionalHeader .DataDirectory [ IMAGE_DIRECTORY_ENTRY_EXPORT ];
91-
92104 // get the File Offset of the export directory
93- uiExportDir = uiBaseAddress + Rva2Offset ( ((PIMAGE_DATA_DIRECTORY )uiNameArray )-> VirtualAddress , uiBaseAddress );
105+ uiExportDir = uiBaseAddress + Rva2Offset ( ((PIMAGE_DATA_DIRECTORY )uiNameArray )-> VirtualAddress , uiBaseAddress , is64 );
94106
95107 // get the File Offset for the array of name pointers
96- uiNameArray = uiBaseAddress + Rva2Offset ( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir )-> AddressOfNames , uiBaseAddress );
108+ uiNameArray = uiBaseAddress + Rva2Offset ( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir )-> AddressOfNames , uiBaseAddress , is64 );
97109
98110 // get the File Offset for the array of addresses
99- uiAddressArray = uiBaseAddress + Rva2Offset ( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir )-> AddressOfFunctions , uiBaseAddress );
111+ uiAddressArray = uiBaseAddress + Rva2Offset ( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir )-> AddressOfFunctions , uiBaseAddress , is64 );
100112
101113 // get the File Offset for the array of name ordinals
102- uiNameOrdinals = uiBaseAddress + Rva2Offset ( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir )-> AddressOfNameOrdinals , uiBaseAddress );
114+ uiNameOrdinals = uiBaseAddress + Rva2Offset ( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir )-> AddressOfNameOrdinals , uiBaseAddress , is64 );
103115
104116 // get a counter for the number of exported functions...
105117 dwCounter = ((PIMAGE_EXPORT_DIRECTORY )uiExportDir )-> NumberOfNames ;
106118
107119 // loop through all the exported functions to find the ReflectiveLoader
108120 while ( dwCounter -- )
109121 {
110- char * cpExportedFunctionName = (char * )(uiBaseAddress + Rva2Offset ( DEREF_32 ( uiNameArray ), uiBaseAddress ));
122+ char * cpExportedFunctionName = (char * )(uiBaseAddress + Rva2Offset ( DEREF_32 ( uiNameArray ), uiBaseAddress , is64 ));
111123
112124 if ( strstr ( cpExportedFunctionName , "ReflectiveLoader" ) != NULL )
113125 {
114126 // get the File Offset for the array of addresses
115- uiAddressArray = uiBaseAddress + Rva2Offset ( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir )-> AddressOfFunctions , uiBaseAddress );
116-
127+ uiAddressArray = uiBaseAddress + Rva2Offset ( ((PIMAGE_EXPORT_DIRECTORY )uiExportDir )-> AddressOfFunctions , uiBaseAddress , is64 );
128+
117129 // use the functions name ordinal as an index into the array of name pointers
118130 uiAddressArray += ( DEREF_16 ( uiNameOrdinals ) * sizeof (DWORD ) );
119131
120132 // return the File Offset to the ReflectiveLoader() functions code...
121- return Rva2Offset ( DEREF_32 ( uiAddressArray ), uiBaseAddress );
133+ return Rva2Offset ( DEREF_32 ( uiAddressArray ), uiBaseAddress , is64 );
122134 }
123135 // get the next exported function name
124136 uiNameArray += sizeof (DWORD );
@@ -161,7 +173,7 @@ HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength )
161173 {
162174 // call the loaded librarys DllMain to get its HMODULE
163175 // Dont call DLL_METASPLOIT_ATTACH/DLL_METASPLOIT_DETACH as that is for payloads only.
164- if ( !pDllMain ( NULL , DLL_QUERY_HMODULE , & hResult ) )
176+ if ( !pDllMain ( NULL , DLL_QUERY_HMODULE , & hResult ) )
165177 hResult = NULL ;
166178 }
167179 // revert to the previous protection flags...
@@ -178,12 +190,12 @@ HMODULE WINAPI LoadLibraryR( LPVOID lpBuffer, DWORD dwLength )
178190}
179191//===============================================================================================//
180192// Loads a PE image from memory into the address space of a host process via the image's exported ReflectiveLoader function
181- // Note: You must compile whatever you are injecting with REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
193+ // Note: You must compile whatever you are injecting with REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
182194// defined in order to use the correct RDI prototypes.
183- // Note: The hProcess handle must have these access rights: PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
195+ // Note: The hProcess handle must have these access rights: PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
184196// PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ
185197// Note: If you are passing in an lpParameter value, if it is a pointer, remember it is for a different address space.
186- // Note: This function currently cant inject accross architectures, but only to architectures which are the
198+ // Note: This function currently cant inject accross architectures, but only to architectures which are the
187199// same as the arch this function is compiled as, e.g. x86->x86 and x64->x64 but not x64->x86 or x86->x64.
188200HANDLE WINAPI LoadRemoteLibraryR ( HANDLE hProcess , LPVOID lpBuffer , DWORD dwLength , LPVOID lpParameter )
189201{
@@ -206,7 +218,7 @@ HANDLE WINAPI LoadRemoteLibraryR( HANDLE hProcess, LPVOID lpBuffer, DWORD dwLeng
206218 break ;
207219
208220 // alloc memory (RWX) in the host process for the image...
209- lpRemoteLibraryBuffer = VirtualAllocEx ( hProcess , NULL , dwLength , MEM_RESERVE |MEM_COMMIT , PAGE_EXECUTE_READWRITE );
221+ lpRemoteLibraryBuffer = VirtualAllocEx ( hProcess , NULL , dwLength , MEM_RESERVE |MEM_COMMIT , PAGE_EXECUTE_READWRITE );
210222 if ( !lpRemoteLibraryBuffer )
211223 break ;
212224
0 commit comments