//===============================================================================================// 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; uiBaseAddress = (UINT_PTR)lpReflectiveDllBuffer; // get the File Offset of the modules NT Header uiExportDir = uiBaseAddress + ((PIMAGE_DOS_HEADER)uiBaseAddress)->e_lfanew; // 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; }
//===============================================================================================// 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 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; }
BOOL PasteOrgIT(CHAR* szOrgITPE,CHAR* szTargetPE) { VOID *pOrgMem,*pTargetMem; PIMAGE_DOS_HEADER pDosh; PIMAGE_NT_HEADERS pPeh; PIMAGE_SECTION_HEADER pSech; PIMAGE_IMPORT_DESCRIPTOR pOrgIID,pTarIID; DWORD *pdwOrg,*pdwTar; // map the files and fill some PE structs pOrgMem = MapFileR(szOrgITPE); if (!pOrgMem) return FALSE; pTargetMem = MapFileRW(szTargetPE); if (!pTargetMem) { UnmapViewOfFile(pOrgMem); return FALSE; } __try { if (!IsPE(pTargetMem)) { UnmapViewOfFile(pOrgMem); UnmapViewOfFile(pTargetMem); return FALSE; } pDosh = (PIMAGE_DOS_HEADER)(pOrgMem); pPeh = (PIMAGE_NT_HEADERS)((DWORD)pDosh + pDosh->e_lfanew); pSech = (PIMAGE_SECTION_HEADER)((DWORD)pPeh + 0xF8); pOrgIID = (PIMAGE_IMPORT_DESCRIPTOR)( (DWORD)pOrgMem + Rva2Offset( pPeh, pDosh, pPeh->OptionalHeader.DataDirectory[1].VirtualAddress)); pTarIID = (PIMAGE_IMPORT_DESCRIPTOR)( (DWORD)pTargetMem + pPeh->OptionalHeader.DataDirectory[1].VirtualAddress); // START THE FIX while(pOrgIID->FirstThunk) { pdwOrg = (DWORD*)((DWORD)pOrgMem + Rva2Offset(pPeh,pDosh,pOrgIID->FirstThunk)); pdwTar = (DWORD*)((DWORD)pTargetMem + pTarIID->FirstThunk); pTarIID->ForwarderChain = 0; // This is need for W9X ! The PE loader wouldn't pTarIID->TimeDateStamp = 0; // initialize the Import Table without it. while(*pdwTar) { *pdwTar = *pdwOrg; ++pdwTar; ++pdwOrg; } ++pOrgIID; ++pTarIID; } } __except(EXCEPTION_EXECUTE_HANDLER) { UnmapViewOfFile(pOrgMem); UnmapViewOfFile(pTargetMem); return FALSE; } // clean up UnmapViewOfFile(pOrgMem); UnmapViewOfFile(pTargetMem); return TRUE; }