Skip to content

Commit aca0fda

Browse files
committed
2 parents 88e8e5f + 2d0f3f5 commit aca0fda

1 file changed

Lines changed: 74 additions & 62 deletions

File tree

inject/src/LoadLibraryR.c

Lines changed: 74 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,69 @@
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
//===============================================================================================//
5269
DWORD 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.
188200
HANDLE 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

Comments
 (0)