• R/O
  • SSH
  • HTTPS

pefrm-units: Commit


Commit MetaInfo

Revision25 (tree)
Time2017-08-03 01:00:40
Authorquiret

Log Message

- added injecting into imports of delay loaded DLLs
- code maintenance improvements

Change Summary

Incremental Difference

--- pefrmdllembed/src/main.cpp (revision 24)
+++ pefrmdllembed/src/main.cpp (revision 25)
@@ -298,6 +298,184 @@
298298 }
299299 };
300300
301+static void WriteVirtualAddress( PEFile& image, PEFile::PESection *targetSect, std::uint32_t sectOffset, std::uint64_t virtualAddress, std::uint32_t archPointerSize, bool requiresRelocations )
302+{
303+ std::uint32_t itemRVA = ( targetSect->GetVirtualAddress() + sectOffset );
304+
305+ targetSect->stream.Seek( sectOffset );
306+
307+ if ( archPointerSize == 4 )
308+ {
309+ targetSect->stream.WriteUInt32( (std::uint32_t)( virtualAddress ) );
310+ }
311+ else if ( archPointerSize == 8 )
312+ {
313+ targetSect->stream.WriteUInt64( virtualAddress );
314+ }
315+ else
316+ {
317+ throw peframework_exception( ePEExceptCode::RUNTIME_ERROR, "invalid arch pointer size in PE virtual address write" );
318+ }
319+
320+ // We could also need a base relocation entry.
321+ if ( requiresRelocations )
322+ {
323+ PEFile::PEBaseReloc::eRelocType relocType = PEFile::PEBaseReloc::GetRelocTypeForPointerSize( archPointerSize );
324+
325+ if ( relocType != PEFile::PEBaseReloc::eRelocType::ABSOLUTE )
326+ {
327+ image.AddRelocation( itemRVA, relocType );
328+ }
329+ }
330+}
331+
332+template <typename splitOperatorType>
333+static inline bool PutSplitIntoImports( PEFile& image, size_t& splitIndex, std::uint32_t thunkTableOffset, std::uint32_t archPointerSize, splitOperatorType& splitOperator )
334+{
335+ // Returns true if the import descriptor should be removed.
336+
337+ size_t numImpFuncs = splitOperator.GetImportFunctions().size();
338+
339+ if ( numImpFuncs <= splitIndex )
340+ {
341+ // Outside of range or imports empty.
342+ return false;
343+ }
344+
345+ // We first split the import directory into two.
346+ size_t first_part_count = ( splitIndex );
347+ size_t second_part_offset = ( first_part_count + 1 );
348+ size_t second_part_count = ( numImpFuncs - second_part_offset );
349+
350+ if ( first_part_count == 0 && second_part_count == 0 )
351+ {
352+ // Just remove this import entry.
353+ return true;
354+ }
355+ else if ( first_part_count > 0 && second_part_count > 0 )
356+ {
357+ // Simply take over the remainder of the first entry into a new second entry.
358+ splitOperator.MakeSecondDescriptor(
359+ image,
360+ second_part_offset, second_part_count,
361+ // Need to point to the new entry properly.
362+ ( thunkTableOffset + archPointerSize )
363+ );
364+
365+ // Trim the first entry.
366+ splitOperator.TrimFirstDescriptor( first_part_count );
367+
368+ splitIndex++;
369+ }
370+ else if ( first_part_count > 0 )
371+ {
372+ // We simply trim this import descriptor.
373+ splitOperator.TrimFirstDescriptor( first_part_count );
374+
375+ // Actually useless but here for mind-model completeness.
376+ splitIndex++;
377+ }
378+ else
379+ {
380+ // Move this import descriptor a little.
381+ splitOperator.RemoveFirstEntry();
382+
383+ splitOperator.MoveIATBy( image, archPointerSize );
384+ }
385+
386+ // We keep the import descriptor.
387+ return false;
388+}
389+
390+template <typename splitOperatorType, typename calcRedirRef_t>
391+static inline bool InjectImportsWithExports(
392+ PEFile& image,
393+ PEFile::PEExportDir& exportDir, splitOperatorType& splitOperator, const calcRedirRef_t& calcRedirRef,
394+ size_t& numOrdinalMatches, size_t& numNameMatches,
395+ std::uint32_t archPointerSize, bool requiresRelocations
396+)
397+{
398+ // Returns true if the import descriptor should be removed.
399+
400+ PEFile::PEImportDesc::functions_t& impFuncs = splitOperator.GetImportFunctions();
401+ PEFile::PESectionDataReference& firstThunkRef = splitOperator.GetFirstThunkRef();
402+
403+ // Check if any entry of this import directory is hosted by any export entry.
404+ size_t impFuncIter = 0;
405+
406+ while ( true )
407+ {
408+ size_t numImpFuncs = impFuncs.size();
409+
410+ if ( impFuncIter >= numImpFuncs )
411+ {
412+ break;
413+ }
414+
415+ // Check for any match.
416+ const PEFile::PEImportDesc::importFunc& impFunc = impFuncs[ impFuncIter ];
417+
418+ bool isOrdinalMatch = impFunc.isOrdinalImport;
419+ std::uint32_t ordinalOfImport = impFunc.ordinal_hint;
420+ const std::string& nameOfImport = impFunc.name;
421+
422+ const PEFile::PEExportDir::func *expFuncMatch = expFuncMatch = exportDir.ResolveExport( isOrdinalMatch, ordinalOfImport, nameOfImport );
423+
424+ if ( expFuncMatch != NULL )
425+ {
426+ // Keep track of change count.
427+ if ( isOrdinalMatch )
428+ {
429+ std::cout << "* by ordinal " << ordinalOfImport << std::endl;
430+
431+ numOrdinalMatches++;
432+ }
433+ else
434+ {
435+ std::cout << "* by name " << nameOfImport << std::endl;
436+
437+ numNameMatches++;
438+ }
439+
440+ // So if we did match, then we replace this entry.
441+ // Write the function address from the entry point.
442+ std::uint32_t thunkTableOffset = (std::uint32_t)( archPointerSize * impFuncIter );
443+ {
444+ PEFile::PESectionDataReference exeImageFuncRef = calcRedirRef( expFuncMatch->expRef );
445+
446+ std::uint64_t exeImageFuncVA = ( exeImageFuncRef.GetRVA() + image.GetImageBase() );
447+
448+ PEFile::PESection *thunkSect = firstThunkRef.GetSection();
449+
450+ // There should not be a case where import entries come without thunk RVAs.
451+ assert( thunkSect != NULL );
452+
453+ std::uint32_t thunkSectOffset = ( firstThunkRef.GetSectionOffset() + thunkTableOffset );
454+
455+ WriteVirtualAddress( image, thunkSect, thunkSectOffset, exeImageFuncVA, archPointerSize, requiresRelocations );
456+ }
457+
458+ // Perform the split operation.
459+ bool removeImpDesc = PutSplitIntoImports( image, impFuncIter, thunkTableOffset, archPointerSize, splitOperator );
460+
461+ // We could be done with this import descriptor entirely, in which case true is returned.
462+ // The runtime must remove it in that case.
463+ if ( removeImpDesc )
464+ {
465+ return true;
466+ }
467+ }
468+ else
469+ {
470+ // This import found no representation, so we simply skip it.
471+ impFuncIter++;
472+ }
473+ }
474+
475+ // Can keep the import descriptor.
476+ return false;
477+}
478+
301479 struct AssemblyEnvironment
302480 {
303481 struct MightyAssembler : public asmjit::X86Assembler
@@ -327,19 +505,35 @@
327505
328506 MightyAssembler x86_asm;
329507
330- inline AssemblyEnvironment( asmjit::CodeHolder *codeHolder )
331- : x86_asm( codeHolder )
508+ PEFile& embedImage;
509+ PEFile::PESection metaSect;
510+
511+ // List of allocations done by the runtime that should stay until the metaSect has been placed
512+ // into the image, finally.
513+ std::list <PEFile::PESectionAllocation> persistentAllocations;
514+
515+ inline AssemblyEnvironment( PEFile& embedImage, asmjit::CodeHolder *codeHolder )
516+ : x86_asm( codeHolder ), embedImage( embedImage )
332517 {
333- return;
518+ metaSect.shortName = ".meta";
519+ metaSect.chars.sect_mem_read = true;
520+ metaSect.chars.sect_mem_write = true;
334521 }
335522
336523 inline ~AssemblyEnvironment( void )
337524 {
338- return;
525+ if ( metaSect.IsEmpty() == false )
526+ {
527+ metaSect.Finalize();
528+
529+ embedImage.AddSection( std::move( this->metaSect ) );
530+ }
339531 }
340532
341- inline int EmbedModuleIntoExecutable( PEFile& exeImage, PEFile& moduleImage, bool requiresRelocations, const char *moduleImageName, bool injectMatchingImports, std::uint32_t archPointerSize )
533+ inline int EmbedModuleIntoExecutable( PEFile& moduleImage, bool requiresRelocations, const char *moduleImageName, bool injectMatchingImports, std::uint32_t archPointerSize )
342534 {
535+ PEFile& exeImage = this->embedImage;
536+
343537 // moduleImage cannot be const because we seek inside of its sections.
344538
345539 // Check that the module is a DLL.
@@ -889,7 +1083,7 @@
8891083 // We might want to inject exports into the imports of the executable module.
8901084 if ( injectMatchingImports )
8911085 {
892- std::cout << "injecting matched PE imports" << std::endl;
1086+ std::cout << "injecting matched PE imports..." << std::endl;
8931087
8941088 // Should keep track of how many items we matched of which type.
8951089 size_t numOrdinalMatches = 0;
@@ -899,207 +1093,229 @@
8991093 // that match it in the executable module. If we find a match we split the import
9001094 // directories in the thunk so that we can write into the loader address during
9011095 // entry point.
902- auto dstImpDescIter = exeImage.imports.begin();
903-
904- size_t numExportFuncs = moduleImage.exportDir.functions.size();
905-
906- while ( dstImpDescIter != exeImage.imports.end() )
9071096 {
908- PEFile::PEImportDesc& impDesc = *dstImpDescIter;
1097+ auto dstImpDescIter = exeImage.imports.begin();
9091098
910- bool removeImpDesc = false;
1099+ size_t numExportFuncs = moduleImage.exportDir.functions.size();
9111100
912- // Do things for matching import descriptors only.
913- if ( UniversalCompareStrings( impDesc.DLLName.c_str(), impDesc.DLLName.size(), moduleImageName, strlen(moduleImageName), false ) )
1101+ while ( dstImpDescIter != exeImage.imports.end() )
9141102 {
915- // Check if any entry of this import directory is hosted by any export entry.
916- size_t numImpFuncs = impDesc.funcs.size();
917- size_t impFuncIter = 0;
1103+ PEFile::PEImportDesc& impDesc = *dstImpDescIter;
9181104
919- while ( impFuncIter < numImpFuncs )
1105+ bool removeImpDesc = false;
1106+
1107+ // Do things for matching import descriptors only.
1108+ if ( UniversalCompareStrings(
1109+ impDesc.DLLName.c_str(), impDesc.DLLName.size(),
1110+ moduleImageName, strlen(moduleImageName),
1111+ false ) )
9201112 {
921- // Check for any match.
922- const PEFile::PEExportDir::func *expFuncMatch = NULL;
1113+ struct basicImpDescriptorHandler
9231114 {
924- const PEFile::PEImportDesc::importFunc& impFunc = impDesc.funcs[ impFuncIter ];
1115+ PEFile::PEImportDesc& impDesc;
1116+ size_t archPointerSize;
1117+ const decltype( PEFile::imports )::iterator& dstImpDescIter;
9251118
926- size_t impOrdinal;
927- bool hasImportOrdinal = false;
1119+ AINLINE basicImpDescriptorHandler( PEFile::PEImportDesc& impDesc, const decltype( PEFile::imports )::iterator& dstImpDescIter, size_t archPointerSize )
1120+ : impDesc( impDesc ), dstImpDescIter( dstImpDescIter )
1121+ {
1122+ this->archPointerSize = archPointerSize;
1123+ }
9281124
929- bool isOrdinalMatch = false;
930- bool isNameMatch = false;
931- const char *nameOfImport = NULL;
932-
933- if ( impFunc.isOrdinalImport )
1125+ AINLINE void MakeSecondDescriptor( PEFile& image, size_t functake_idx, size_t functake_count, std::uint32_t thunkRefStartOffset )
9341126 {
935- impOrdinal = impFunc.ordinal_hint;
936- hasImportOrdinal = true;
1127+ // Simply take over the remainder of the first entry into a new second entry.
1128+ PEFile::PEImportDesc newSecondDesc;
1129+ newSecondDesc.DLLName = impDesc.DLLName;
1130+ newSecondDesc.funcs.reserve( functake_count );
1131+ {
1132+ auto beginMoveIter = std::make_move_iterator( impDesc.funcs.begin() + functake_idx );
1133+ auto endMoveIter = ( beginMoveIter + functake_count );
9371134
938- isOrdinalMatch = true;
1135+ newSecondDesc.funcs.insert( newSecondDesc.funcs.begin(), beginMoveIter, endMoveIter );
1136+ }
1137+
1138+ // Need to point to the new entry properly.
1139+ newSecondDesc.firstThunkRef = image.ResolveRVAToRef( impDesc.firstThunkRef.GetRVA() + thunkRefStartOffset );
1140+
1141+ // Insert the new import descriptor after our.
1142+ image.imports.insert( this->dstImpDescIter + 1, std::move( newSecondDesc ) );
9391143 }
940- else
1144+
1145+ AINLINE PEFile::PEImportDesc::functions_t& GetImportFunctions( void )
9411146 {
942- auto findIter = moduleImage.exportDir.funcNameMap.find( impFunc.name );
1147+ return impDesc.funcs;
1148+ }
9431149
944- if ( findIter != moduleImage.exportDir.funcNameMap.end() )
945- {
946- impOrdinal = findIter->second;
947- hasImportOrdinal = true;
1150+ AINLINE PEFile::PESectionDataReference& GetFirstThunkRef( void )
1151+ {
1152+ return impDesc.firstThunkRef;
1153+ }
9481154
949- nameOfImport = (*findIter).first.name.c_str();
1155+ AINLINE void TrimFirstDescriptor( size_t trimTo )
1156+ {
1157+ impDesc.funcs.resize( trimTo );
1158+ }
9501159
951- isNameMatch = true;
952- }
1160+ AINLINE void MoveIATBy( PEFile& image, std::uint32_t moveBytes )
1161+ {
1162+ impDesc.firstThunkRef = image.ResolveRVAToRef( impDesc.firstThunkRef.GetRVA() + moveBytes );
9531163 }
9541164
955- if ( hasImportOrdinal )
1165+ AINLINE void RemoveFirstEntry( void )
9561166 {
957- // Need to subtract the ordinal base.
958- impOrdinal -= moduleImage.exportDir.ordinalBase;
1167+ impDesc.funcs.erase( impDesc.funcs.begin() );
1168+ }
1169+ };
1170+ basicImpDescriptorHandler splitOp( impDesc, dstImpDescIter, archPointerSize );
9591171
960- if ( impOrdinal < numExportFuncs )
961- {
962- const PEFile::PEExportDir::func& expFunc = moduleImage.exportDir.functions[ impOrdinal ];
1172+ removeImpDesc = InjectImportsWithExports(
1173+ exeImage,
1174+ moduleImage.exportDir, splitOp, calcRedirRef,
1175+ numOrdinalMatches, numNameMatches,
1176+ archPointerSize, requiresRelocations
1177+ );
1178+ }
9631179
964- if ( expFunc.isForwarder == false )
965- {
966- expFuncMatch = &expFunc;
1180+ if ( removeImpDesc )
1181+ {
1182+ dstImpDescIter = exeImage.imports.erase( dstImpDescIter );
1183+ }
1184+ else
1185+ {
1186+ dstImpDescIter++;
1187+ }
1188+ }
1189+ }
9671190
968- // Keep track of change count.
969- if ( isOrdinalMatch )
970- {
971- std::cout << "* by ordinal " << impOrdinal << std::endl;
1191+ // Also do the delayed import descriptors, which should be possible.
1192+ {
1193+ auto dstImpDescIter = exeImage.delayLoads.begin();
9721194
973- numOrdinalMatches++;
974- }
1195+ while ( dstImpDescIter != exeImage.delayLoads.end() )
1196+ {
1197+ bool removeImpDesc = false;
9751198
976- if ( isNameMatch )
977- {
978- std::cout << "* by name " << nameOfImport << std::endl;
1199+ // Process this import descriptor.
1200+ {
1201+ PEFile::PEDelayLoadDesc& impDesc = *dstImpDescIter;
9791202
980- numNameMatches++;
981- }
982- }
983- }
984- }
985- }
986-
987- if ( expFuncMatch != NULL )
1203+ if ( UniversalCompareStrings( impDesc.DLLName.c_str(), impDesc.DLLName.size(), moduleImageName, strlen(moduleImageName), false ) )
9881204 {
989- // So if we did match, then we replace this entry.
990- // Write the function address from the entry point.
991- std::uint32_t thunkTableOffset = (std::uint32_t)( archPointerSize * impFuncIter );
1205+ struct delayedImpDescriptorHandler
9921206 {
993- PEFile::PESectionDataReference exeImageFuncRef = calcRedirRef( expFuncMatch->expRef );
994-
995- std::uint64_t exeImageFuncVA = ( exeImageFuncRef.GetRVA() + exeModuleBase );
1207+ AssemblyEnvironment& env;
1208+ PEFile::PEDelayLoadDesc& impDesc;
1209+ std::uint32_t archPointerSize;
1210+ const decltype( PEFile::delayLoads )::iterator& dstImpDescIter;
9961211
997- PEFile::PESection *thunkSect = impDesc.firstThunkRef.GetSection();
1212+ AINLINE delayedImpDescriptorHandler( AssemblyEnvironment& env, PEFile::PEDelayLoadDesc& impDesc, std::uint32_t archPointerSize, const decltype( PEFile::delayLoads )::iterator& dstImpDescIter )
1213+ : impDesc( impDesc ), env( env ), dstImpDescIter( dstImpDescIter )
1214+ {
1215+ this->archPointerSize = archPointerSize;
1216+ }
9981217
999- // There should not be a case where import entries come without thunk RVAs.
1000- assert( thunkSect != NULL );
1218+ AINLINE PEFile::PEImportDesc::functions_t& GetImportFunctions( void )
1219+ {
1220+ return impDesc.importNames;
1221+ }
10011222
1002- std::uint32_t thunkSectOffset = ( impDesc.firstThunkRef.GetSectionOffset() + thunkTableOffset );
1223+ AINLINE PEFile::PESectionDataReference& GetFirstThunkRef( void )
1224+ {
1225+ return impDesc.IATRef;
1226+ }
10031227
1004- thunkSect->stream.Seek( thunkSectOffset );
1005-
1006- if ( archPointerSize == 4 )
1228+ AINLINE void TrimFirstDescriptor( size_t trimTo )
10071229 {
1008- thunkSect->stream.WriteUInt32( (std::uint32_t)exeImageFuncVA );
1230+ impDesc.importNames.resize( trimTo );
10091231 }
1010- else if ( archPointerSize == 8 )
1232+
1233+ AINLINE void RemoveFirstEntry( void )
10111234 {
1012- thunkSect->stream.WriteUInt64( exeImageFuncVA );
1235+ impDesc.importNames.erase( impDesc.importNames.begin() );
10131236 }
1014- else
1237+
1238+ AINLINE void MoveIATBy( PEFile& image, std::uint32_t moveBytes )
10151239 {
1016- std::cout << "invalid arch pointer size in PE import injection" << std::endl;
1240+ impDesc.IATRef = image.ResolveRVAToRef( impDesc.IATRef.GetRVA() + moveBytes );
1241+
1242+ // Move the other if it is available.
1243+ PEFile::PESectionDataReference& unloadIAT = impDesc.unloadInfoTableRef;
10171244
1018- return -20;
1245+ if ( unloadIAT.GetSection() != NULL )
1246+ {
1247+ unloadIAT = image.ResolveRVAToRef( unloadIAT.GetRVA() + moveBytes );
1248+ }
10191249 }
10201250
1021- // We could also need a base relocation entry.
1022- if ( requiresRelocations )
1251+ AINLINE void MakeSecondDescriptor( PEFile& image, size_t functake_idx, size_t functake_count, std::uint32_t thunkRefStartOffset )
10231252 {
1024- PEFile::PEBaseReloc::eRelocType relocType = PEFile::PEBaseReloc::GetRelocTypeForPointerSize( archPointerSize );
1025-
1026- if ( relocType != PEFile::PEBaseReloc::eRelocType::ABSOLUTE )
1253+ PEFile::PEDelayLoadDesc newSecondImp;
1254+ newSecondImp.attrib = impDesc.attrib;
1255+ newSecondImp.DLLName = impDesc.DLLName;
1256+
1257+ // Allocate a new DLL handle memory position for this descriptor.
10271258 {
1028- std::uint32_t thunkItemRVA = ( thunkSect->GetVirtualAddress() + thunkSectOffset );
1259+ PEFile::PESectionAllocation handleAlloc;
1260+ env.metaSect.Allocate( handleAlloc, this->archPointerSize, this->archPointerSize );
10291261
1030- exeImage.AddRelocation( thunkItemRVA, relocType );
1262+ env.persistentAllocations.push_back( std::move( handleAlloc ) );
1263+
1264+ newSecondImp.DLLHandleRef = env.persistentAllocations.back();
10311265 }
1032- }
1033- }
10341266
1035- // We first split the import directory into two.
1036- size_t first_part_count = ( impFuncIter );
1037- size_t second_part_offset = ( first_part_count + 1 );
1038- size_t second_part_count = ( numImpFuncs - second_part_offset );
1267+ // Create a special IAT out of the previous.
1268+ newSecondImp.IATRef = image.ResolveRVAToRef( impDesc.IATRef.GetRVA() + thunkRefStartOffset );
10391269
1040- // We remove one so we got less next time.
1041- numImpFuncs--;
1270+ // Copy over the import names aswell.
1271+ newSecondImp.importNames.reserve( functake_count );
1272+ {
1273+ auto beginMoveIter = std::make_move_iterator( impDesc.importNames.begin() + functake_idx );
1274+ auto endMoveIter = ( beginMoveIter + functake_count );
10421275
1043- if ( first_part_count == 0 && second_part_count == 0 )
1044- {
1045- // Just remove this import entry.
1046- removeImpDesc = true;
1047- break;
1048- }
1049- else if ( first_part_count > 0 && second_part_count > 0 )
1050- {
1051- // Simply take over the remainder of the first entry into a new second entry.
1052- PEFile::PEImportDesc newSecondDesc;
1053- newSecondDesc.DLLName = impDesc.DLLName;
1054- newSecondDesc.funcs.reserve( second_part_count );
1055- {
1056- auto beginMoveIter = std::make_move_iterator( impDesc.funcs.begin() + second_part_offset );
1057- auto endMoveIter = ( beginMoveIter + second_part_count );
1276+ newSecondImp.importNames.insert( newSecondImp.importNames.begin(), beginMoveIter, endMoveIter );
1277+ }
10581278
1059- newSecondDesc.funcs.insert( newSecondDesc.funcs.begin(), beginMoveIter, endMoveIter );
1060- }
1061-
1062- // Need to point to the new entry properly.
1063- newSecondDesc.firstThunkRef =
1064- exeImage.ResolveRVAToRef( impDesc.firstThunkRef.GetRVA() + ( thunkTableOffset + archPointerSize ) );
1279+ // If an unload info table existed previously, also handle that case.
1280+ {
1281+ PEFile::PESectionDataReference& unloadIAT = impDesc.unloadInfoTableRef;
10651282
1066- // Trim the first entry.
1067- impDesc.funcs.resize( first_part_count );
1283+ if ( unloadIAT.GetSection() != NULL )
1284+ {
1285+ newSecondImp.unloadInfoTableRef =
1286+ image.ResolveRVAToRef( unloadIAT.GetRVA() + thunkRefStartOffset );
1287+ }
1288+ }
10681289
1069- // Insert the new import descriptor after our.
1070- exeImage.imports.insert( dstImpDescIter + 1, std::move( newSecondDesc ) );
1290+ newSecondImp.timeDateStamp = impDesc.timeDateStamp;
10711291
1072- impFuncIter++;
1073- }
1074- else if ( first_part_count > 0 )
1075- {
1076- // We simply trim this import descriptor.
1077- impDesc.funcs.resize( first_part_count );
1292+ // Put in the new descriptor after the one we manage.
1293+ image.delayLoads.insert( this->dstImpDescIter + 1, std::move( newSecondImp ) );
10781294
1079- // Actually useless but here for mind-model completeness.
1080- impFuncIter++;
1081- }
1082- else
1083- {
1084- // Move this import descripter a little.
1085- impDesc.funcs.erase( impDesc.funcs.begin() );
1295+ // Done.
1296+ }
1297+ };
1298+ delayedImpDescriptorHandler splitOp( *this, impDesc, archPointerSize, dstImpDescIter );
10861299
1087- impDesc.firstThunkRef = exeImage.ResolveRVAToRef( impDesc.firstThunkRef.GetRVA() + archPointerSize );
1088- }
1089-
1090- // Nice.
1300+ removeImpDesc =
1301+ InjectImportsWithExports(
1302+ exeImage,
1303+ moduleImage.exportDir, splitOp, calcRedirRef,
1304+ numOrdinalMatches, numNameMatches,
1305+ archPointerSize, requiresRelocations
1306+ );
10911307 }
10921308 }
1093- }
10941309
1095- if ( removeImpDesc )
1096- {
1097- dstImpDescIter = exeImage.imports.erase( dstImpDescIter );
1310+ if ( removeImpDesc )
1311+ {
1312+ dstImpDescIter = exeImage.delayLoads.erase( dstImpDescIter );
1313+ }
1314+ else
1315+ {
1316+ dstImpDescIter++;
1317+ }
10981318 }
1099- else
1100- {
1101- dstImpDescIter++;
1102- }
11031319 }
11041320
11051321 // If any work was done then we should rewrite the imports table.
@@ -1594,7 +1810,7 @@
15941810 // We need to remember a label of the entry point.
15951811 asmjit::Label entryPointLabel;
15961812 {
1597- AssemblyEnvironment asmEnv( &asmCodeHolder );
1813+ AssemblyEnvironment asmEnv( exeImage, &asmCodeHolder );
15981814
15991815 asmjit::X86Assembler& x86_asm = asmEnv.x86_asm;
16001816
@@ -1797,7 +2013,7 @@
17972013 const char *moduleFileName = FetchFileName( inputModImageName );
17982014
17992015 // Perform the embedding.
1800- int statusEmbed = asmEnv.EmbedModuleIntoExecutable( exeImage, moduleImage, requiresRelocations, moduleFileName, doInjectMatchingImports, archPointerSize );
2016+ int statusEmbed = asmEnv.EmbedModuleIntoExecutable( moduleImage, requiresRelocations, moduleFileName, doInjectMatchingImports, archPointerSize );
18012017
18022018 if ( statusEmbed != 0 )
18032019 {
Show on old repository browser