132 lines
6.0 KiB
C
132 lines
6.0 KiB
C
//===============================================================================================//
|
|
// Copyright (c) 2009, 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"
|
|
//===============================================================================================//
|
|
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 _WIN64
|
|
DWORD dwMeterpreterArch = 2;
|
|
#else
|
|
DWORD dwMeterpreterArch = 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( dwMeterpreterArch != 1 )
|
|
return 0;
|
|
}
|
|
else if( ((PIMAGE_NT_HEADERS)uiExportDir)->OptionalHeader.Magic == 0x020B ) // PE64
|
|
{
|
|
if( dwMeterpreterArch != 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;
|
|
}
|
|
//===============================================================================================//
|