• R/O
  • SSH
  • HTTPS

peframework: Commit


Commit MetaInfo

Revision19 (tree)
Time2018-01-12 03:20:11
Authorquiret

Log Message

- added Code::Blocks project
- minor adjustments to please GCC
- fixed a bug where if the e_lfanew member was negative or in the MSDOS header an assert would be triggered

Change Summary

Incremental Difference

--- src/peloader.cpp (revision 18)
+++ src/peloader.cpp (revision 19)
@@ -4,7 +4,7 @@
44
55 #include "peloader.internal.hxx"
66
7-PEFile::PEFile( void ) : resourceRoot( false, std::u16string(), 0 ), sections( 0x1000, 0x10000 )
7+PEFile::PEFile( void ) : sections( 0x1000, 0x10000 ), resourceRoot( false, std::u16string(), 0 )
88 {
99 // By default we generate plain PE32+ files.
1010 // If true then PE32+ files are generated.
@@ -214,7 +214,7 @@
214214 // * all active section data references
215215 {
216216 LIST_FOREACH_BEGIN( PESectionReference, this->dataRefList.root, sectionNode )
217-
217+
218218 // Reset data fields to unlinked status
219219 // without clearing ties itself.
220220 item->clearLink();
@@ -365,7 +365,7 @@
365365 typedef sliceOfData <std::uint32_t> streamSlice_t;
366366
367367 streamSlice_t sectionSlice( 0, this->virtualSize );
368-
368+
369369 streamSlice_t reqSlice( allocOff, std::max( allocSize, 1u ) );
370370
371371 streamSlice_t::eIntersectionResult intResult = reqSlice.intersectWith( sectionSlice );
@@ -423,7 +423,7 @@
423423 {
424424 // Calculate the absolute VA.
425425 std::uint32_t targetVA = 0;
426-
426+
427427 if ( targetSect )
428428 {
429429 targetVA = ( (std::uint32_t)imageBase + targetSect->ResolveRVA( targetOff ) );
@@ -481,7 +481,7 @@
481481 chars.sect_mem_16bit = ( schars & PEL_IMAGE_SCN_MEM_16BIT ) != 0;
482482 chars.sect_mem_locked = ( schars & PEL_IMAGE_SCN_MEM_LOCKED ) != 0;
483483 chars.sect_mem_preload = ( schars & PEL_IMAGE_SCN_MEM_PRELOAD ) != 0;
484-
484+
485485 // Parse the alignment information out of the chars.
486486 PESection::eAlignment alignNum = (PESection::eAlignment)( ( schars & 0x00F00000 ) >> 20 );
487487 chars.sect_alignment = alignNum;
@@ -675,7 +675,7 @@
675675
676676 // The image does not have a virtualSize parameter yet.
677677 assert( this->virtualSize == 0 );
678-
678+
679679 // It is created by taking the rawdata size.
680680 // The image will later round it to section alignment.
681681 this->virtualSize = ( (decltype(virtualSize))stream.Size() );
@@ -694,7 +694,7 @@
694694
695695 // The image does not have a virtualSize parameter yet.
696696 assert( this->virtualSize == 0 );
697-
697+
698698 // Ensure that the guy set a proper virtual size.
699699 // If not then we are in trouble.
700700 std::uint32_t atLeastVirtSize = ( (std::uint32_t)stream.Size() );
@@ -706,7 +706,7 @@
706706 "invalid virtual size in profound section finalization"
707707 );
708708 }
709-
709+
710710 // Store the user-given value.
711711 // We assume that it is aligned properly.
712712 this->virtualSize = virtSize;
@@ -881,7 +881,7 @@
881881 sectAllocSemantics::allocInfo allocInfo;
882882
883883 bool foundSpace = sectAllocSemantics::FindSpace( sectVirtualAllocMan, alignedSectionSize, allocInfo, sectionAlignment, imageBase );
884-
884+
885885 if ( !foundSpace )
886886 {
887887 return false;
@@ -905,7 +905,7 @@
905905 {
906906 assert( this->storageType == eStorageType::NONE );
907907 }
908-
908+
909909 this->storageType = eStorageType::NONE;
910910 }
911911
@@ -1019,7 +1019,7 @@
10191019
10201020 if ( item->shortName == name )
10211021 return item;
1022-
1022+
10231023 LIST_FOREACH_END
10241024
10251025 return NULL;
@@ -1028,10 +1028,10 @@
10281028 PEFile::PESection* PEFile::FindFirstAllocatableSection( void )
10291029 {
10301030 LIST_FOREACH_BEGIN( PESection, this->sections.sectionList.root, sectionNode )
1031-
1031+
10321032 if ( item->IsFinal() == false )
10331033 return item;
1034-
1034+
10351035 LIST_FOREACH_END
10361036
10371037 return NULL;
@@ -1087,10 +1087,10 @@
10871087 {
10881088 // Check any sections.
10891089 LIST_FOREACH_BEGIN( PESection, this->sections.sectionList.root, sectionNode )
1090-
1090+
10911091 if ( item->relocations.size() != 0 )
10921092 return true;
1093-
1093+
10941094 LIST_FOREACH_END
10951095
10961096 // Check the base relocation data.
@@ -1105,10 +1105,10 @@
11051105 {
11061106 // Check sections.
11071107 LIST_FOREACH_BEGIN( PESection, this->sections.sectionList.root, sectionNode )
1108-
1108+
11091109 if ( item->linenumbers.size() != 0 )
11101110 return true;
1111-
1111+
11121112 LIST_FOREACH_END
11131113
11141114 // Has no embedded line number info.
@@ -1129,4 +1129,4 @@
11291129 bool PEFile::IsDynamicLinkLibrary( void ) const
11301130 {
11311131 return ( this->pe_finfo.isDLL );
1132-}
\ No newline at end of file
1132+}
--- src/peloader.read.cpp (revision 18)
+++ src/peloader.read.cpp (revision 19)
@@ -95,7 +95,7 @@
9595 );
9696 }
9797 }
98-
98+
9999 importNameArraySect->SetPlacedMemory( allocEntry, rva );
100100
101101 // The array goes on until a terminating NULL.
@@ -173,7 +173,7 @@
173173 ReadPEString( importNameStream, funcInfo.name );
174174 }
175175 funcInfo.isOrdinalImport = isOrdinalImport;
176-
176+
177177 funcs.push_back( std::move( funcInfo ) );
178178 }
179179
@@ -234,27 +234,39 @@
234234
235235 // We need the program data aswell.
236236 // Assumption is that the data directly follows the header and ends in the new data ptr.
237- {
238- std::int32_t newDataOffset = dosHeader.e_lfanew;
237+ {
238+ std::int32_t lfa_offset_data = dosHeader.e_lfanew;
239+
240+ if ( lfa_offset_data < 0 )
241+ {
242+ throw peframework_exception(
243+ ePEExceptCode::CORRUPT_PE_STRUCTURE,
244+ "invalid MSDOS e_lfanew offset (negative)"
245+ );
246+ }
239247
240- std::int32_t sizeOfStubData = ( newDataOffset - sizeof( dosHeader ) );
241-
242- assert( sizeOfStubData >= 0 );
243-
244- std::vector <unsigned char> progData( sizeOfStubData );
248+ std::uint32_t newDataOffset = (std::uint32_t)dosHeader.e_lfanew;
249+
250+ // Only copy a possible stub if it exists.
251+ if ( newDataOffset >= sizeof( dosHeader ) )
245252 {
246- size_t progReadCount = peStream->Read( progData.data(), sizeOfStubData );
253+ std::uint32_t sizeOfStubData = ( newDataOffset - sizeof( dosHeader ) );
247254
248- if ( progReadCount != sizeOfStubData )
255+ std::vector <unsigned char> progData( sizeOfStubData );
249256 {
250- throw peframework_exception(
251- ePEExceptCode::CORRUPT_PE_STRUCTURE,
252- "invalid MSDOS stub"
253- );
257+ size_t progReadCount = peStream->Read( progData.data(), sizeOfStubData );
258+
259+ if ( progReadCount != sizeOfStubData )
260+ {
261+ throw peframework_exception(
262+ ePEExceptCode::CORRUPT_PE_STRUCTURE,
263+ "invalid MSDOS stub"
264+ );
265+ }
254266 }
267+
268+ dos.progData = std::move( progData );
255269 }
256-
257- dos.progData = std::move( progData );
258270 }
259271
260272 peFileStartOffset = dosHeader.e_lfanew;
@@ -302,7 +314,7 @@
302314 // Store stuff.
303315 peInfo.machine_id = machineType;
304316 peInfo.timeDateStamp = peHeader.FileHeader.TimeDateStamp;
305-
317+
306318 // Flags that matter.
307319 std::uint16_t chars = peHeader.FileHeader.Characteristics;
308320
@@ -320,10 +332,10 @@
320332 peInfo.bytesReversedHI = ( chars & PEL_IMAGE_FILE_BYTES_REVERSED_HI ) != 0;
321333
322334 // Other properties should be respected during parsing.
323- bool hasRelocsStripped = ( chars & PEL_IMAGE_FILE_RELOCS_STRIPPED ) != 0;
324- bool hasLineNumsStripped = ( chars & PEL_IMAGE_FILE_LINE_NUMS_STRIPPED ) != 0;
325- bool hasLocalSymsStripped = ( chars & PEL_IMAGE_FILE_LOCAL_SYMS_STRIPPED ) != 0;
326- bool hasDebugStripped = ( chars & PEL_IMAGE_FILE_DEBUG_STRIPPED ) != 0;
335+ //bool hasRelocsStripped = ( chars & PEL_IMAGE_FILE_RELOCS_STRIPPED ) != 0;
336+ //bool hasLineNumsStripped = ( chars & PEL_IMAGE_FILE_LINE_NUMS_STRIPPED ) != 0;
337+ //bool hasLocalSymsStripped = ( chars & PEL_IMAGE_FILE_LOCAL_SYMS_STRIPPED ) != 0;
338+ //bool hasDebugStripped = ( chars & PEL_IMAGE_FILE_DEBUG_STRIPPED ) != 0;
327339
328340 // Remember that we were here.
329341 pe_file_ptr_t optionalHeaderOffset = peStream->Tell();
@@ -456,7 +468,7 @@
456468
457469 // Extract the data directory information.
458470 numberOfDataDirs = optHeader.NumberOfRvaAndSizes;
459-
471+
460472 // Decrease remaining size.
461473 optHeaderSizeRemain -= sizeof(optHeaderType);
462474 }
@@ -632,7 +644,7 @@
632644 PESection section;
633645 section.shortName = std::string( (const char*)sectHeader.Name, strnlen( (const char*)sectHeader.Name, countof(sectHeader.Name) ) );
634646 section.SetPlacementInfo( sectHeader.VirtualAddress, sectHeader.Misc.VirtualSize );
635-
647+
636648 // Save characteristics flags.
637649 std::uint32_t schars = sectHeader.Characteristics;
638650
@@ -812,9 +824,6 @@
812824 std::vector <PEExportDir::func> funcs;
813825 funcs.reserve( expEntry.NumberOfFunctions );
814826
815- std::uint32_t archPointerSize = GetPEPointerSize( isExtendedFormat );
816- std::uint64_t tabSize = ( archPointerSize * expEntry.NumberOfFunctions );
817-
818827 PESection *addrPtrSect;
819828 PEDataStream addrPtrStream;
820829 {
@@ -926,7 +935,7 @@
926935 PEDataStream addrNameOrdStream;
927936 {
928937 bool gotStream = sections.GetPEDataStream( expEntry.AddressOfNameOrdinals, addrNameOrdStream, &addrNameOrdSect );
929-
938+
930939 if ( !gotStream )
931940 {
932941 throw peframework_exception(
@@ -989,7 +998,7 @@
989998 // Store this link.
990999 PEExportDir::mappedName nameMap;
9911000 nameMap.name = std::move( realName );
992-
1001+
9931002 realNamePtrSect->SetPlacedMemory( nameMap.nameAllocEntry, namePtrRVA );
9941003
9951004 expInfo.funcNameMap.insert( std::make_pair( std::move( nameMap ), std::move( mapIndex ) ) );
@@ -1046,7 +1055,7 @@
10461055 if ( importInfo.Characteristics == 0 &&
10471056 importInfo.TimeDateStamp == 0 &&
10481057 importInfo.ForwarderChain == 0 &&
1049- importInfo.Name == 0 &&
1058+ importInfo.Name == 0 &&
10501059 importInfo.FirstThunk == 0 )
10511060 {
10521061 break;
@@ -1201,7 +1210,7 @@
12011210 rootStream.Read( &nameCharCount, sizeof(nameCharCount) );
12021211
12031212 nameOfItem.resize( nameCharCount );
1204-
1213+
12051214 rootStream.Read( (char16_t*)nameOfItem.c_str(), nameCharCount );
12061215 }
12071216
@@ -1224,7 +1233,7 @@
12241233 for ( std::uint32_t n = 0; n < numIDEntries; n++ )
12251234 {
12261235 rootStream.Seek( subDirStartOff + ( n + numNamedEntries ) * sizeof(PEStructures::IMAGE_RESOURCE_DIRECTORY_ENTRY) );
1227-
1236+
12281237 PEStructures::IMAGE_RESOURCE_DIRECTORY_ENTRY idEntry;
12291238 rootStream.Read( &idEntry, sizeof(idEntry) );
12301239
@@ -1579,7 +1588,7 @@
15791588
15801589 if ( !gotStream )
15811590 {
1582- throw peframework_exception(
1591+ throw peframework_exception(
15831592 ePEExceptCode::CORRUPT_PE_STRUCTURE,
15841593 "invalid PE thread-local-storage directory"
15851594 );
@@ -1764,7 +1773,6 @@
17641773 // PE sections so we need to read it custom.
17651774
17661775 std::uint32_t boundImpFileOff = boundDataDir.VirtualAddress;
1767- std::uint32_t boundImpStoreSize = boundDataDir.Size;
17681776
17691777 struct helpers
17701778 {
@@ -1785,7 +1793,7 @@
17851793 while ( true )
17861794 {
17871795 char c;
1788-
1796+
17891797 bool gotChar = peStream->ReadStruct( c );
17901798
17911799 if ( !gotChar )
@@ -1812,7 +1820,7 @@
18121820 PEBoundImport desc;
18131821 desc.timeDateStamp = boundDesc.TimeDateStamp;
18141822 desc.DLLName = std::move( DLLName );
1815-
1823+
18161824 // Read child structures.
18171825 const std::uint32_t numChildren = boundDesc.NumberOfModuleForwarderRefs;
18181826
@@ -1843,7 +1851,7 @@
18431851 // Read all bound import descriptors.
18441852 // They are not fixed-size, so we need to read till end.
18451853 peStream->Seek( boundImpFileOff );
1846-
1854+
18471855 while ( true )
18481856 {
18491857 // Are we past the descriptors?
@@ -1947,7 +1955,7 @@
19471955
19481956 PEDelayLoadDesc desc;
19491957 desc.attrib = delayLoad.Attributes.AllAttributes;
1950-
1958+
19511959 // Read DLL name.
19521960 if ( std::uint32_t DllNameRVA = delayLoad.DllNameRVA )
19531961 {
@@ -1989,7 +1997,7 @@
19891997 }
19901998
19911999 desc.IATRef = sections.ResolveRVAToRef( delayLoad.ImportAddressTableRVA );
1992-
2000+
19932001 if ( std::uint32_t importNamesRVA = delayLoad.ImportNameTableRVA )
19942002 {
19952003 desc.importNames =
@@ -2021,7 +2029,7 @@
20212029 }
20222030
20232031 // TODO: maybe validate all structures more explicitly in context now.
2024-
2032+
20252033 // Successfully loaded!
20262034 // Store everything inside ourselves.
20272035 this->dos_data = std::move( dos );
@@ -2028,7 +2036,7 @@
20282036 this->pe_finfo = std::move( peInfo );
20292037 this->peOptHeader = std::move( peOpt );
20302038 this->sections = std::move( sections );
2031-
2039+
20322040 // Data directories.
20332041 this->exportDir = std::move( expInfo );
20342042 this->imports = std::move( impDescs );
@@ -2049,4 +2057,4 @@
20492057 this->isExtendedFormat = isExtendedFormat; // important for casting certain offsets.
20502058
20512059 // Next thing we would need is writing support.
2052-}
\ No newline at end of file
2060+}
--- include/peloader.h (revision 18)
+++ include/peloader.h (revision 19)
@@ -138,10 +138,11 @@
138138 : shortName( std::move( right.shortName ) ), virtualSize( std::move( right.virtualSize ) ),
139139 virtualAddr( std::move( right.virtualAddr ) ), relocations( std::move( right.relocations ) ),
140140 linenumbers( std::move( right.linenumbers ) ), chars( std::move( right.chars ) ),
141- isFinal( std::move( right.isFinal ) ), dataAlloc( std::move( right.dataAlloc ) ),
141+ isFinal( std::move( right.isFinal ) ),
142+ placedOffsets( std::move( right.placedOffsets ) ), RVAreferalList( std::move( right.RVAreferalList ) ),
143+ dataAlloc( std::move( right.dataAlloc ) ),
142144 dataRefList( std::move( right.dataRefList ) ), dataAllocList( std::move( right.dataAllocList ) ),
143- streamAllocMan( std::move( right.streamAllocMan ) ), stream( std::move( right.stream ) ),
144- placedOffsets( std::move( right.placedOffsets ) ), RVAreferalList( std::move( right.RVAreferalList ) )
145+ streamAllocMan( std::move( right.streamAllocMan ) ), stream( std::move( right.stream ) )
145146 {
146147 // Since I have been writing this, how about a move constructor that allows
147148 // default-construction of all members but on top of that executes its own constructor body?
@@ -171,7 +172,7 @@
171172
172173 inline void unregisterOwnerImage( void )
173174 {
174- if ( PESectionMan *ownerImage = this->ownerImage )
175+ if ( this->ownerImage )
175176 {
176177 LIST_REMOVE( this->sectionNode );
177178
@@ -285,7 +286,7 @@
285286 bool sect_mem_16bit;
286287 bool sect_mem_locked;
287288 bool sect_mem_preload;
288-
289+
289290 eAlignment sect_alignment;
290291
291292 bool sect_link_nreloc_ovfl;
@@ -343,7 +344,7 @@
343344
344345 inline ~PESectionReference( void )
345346 {
346- if ( PESection *theSect = this->theSect )
347+ if ( this->theSect )
347348 {
348349 LIST_REMOVE( this->sectionNode );
349350
@@ -602,7 +603,7 @@
602603
603604 // Data-access methods for this allocation
604605 void WriteToSection( const void *dataPtr, std::uint32_t dataSize, std::int32_t dataOff = 0 );
605-
606+
606607 // For allocating placed RVAs into allocated structs.
607608 void RegisterTargetRVA(
608609 std::uint32_t patchOffset, PESection *targetSect, std::uint32_t targetOff,
@@ -902,7 +903,7 @@
902903 typedef sliceOfData <std::uint32_t> sectionSlice_t;
903904
904905 // Get the slice of the present data.
905- const std::uint32_t sectVirtualAddr = theSection->virtualAddr;
906+ //const std::uint32_t sectVirtualAddr = theSection->virtualAddr;
906907 const std::uint32_t sectVirtualSize = theSection->virtualSize;
907908
908909 sectionSlice_t dataSlice( 0, theSection->stream.Size() );
@@ -1026,7 +1027,7 @@
10261027 std::uint32_t sectIndex = 0;
10271028
10281029 LIST_FOREACH_BEGIN( PESection, this->sectionList.root, sectionNode )
1029-
1030+
10301031 // We only support that for sections whose data is figured out already.
10311032 if ( item->isFinal )
10321033 {
@@ -1065,7 +1066,7 @@
10651066 }
10661067
10671068 sectIndex++;
1068-
1069+
10691070 LIST_FOREACH_END
10701071
10711072 // Not found.
@@ -1402,7 +1403,7 @@
14021403
14031404 PESectionAllocation allocEntry;
14041405 writeSect.Allocate( allocEntry, writeSize, sizeof(charType) );
1405-
1406+
14061407 allocEntry.WriteToSection( string.c_str(), writeSize );
14071408
14081409 return allocEntry;
@@ -1542,7 +1543,7 @@
15421543
15431544 PESectionAllocation impNameArrayAllocEntry;
15441545 PESectionAllocation DLLName_allocEntry;
1545-
1546+
15461547 // Meta-information we must keep because it is baked
15471548 // by compilers.
15481549 PESectionDataReference firstThunkRef;
@@ -1561,8 +1562,8 @@
15611562 };
15621563
15631564 inline PEResourceItem( eType typeDesc, bool isIdentifierName, std::u16string name, std::uint16_t identifier )
1564- : itemType( std::move( typeDesc ) ),
1565- hasIdentifierName( std::move( isIdentifierName ) ), name( std::move( name ) ), identifier( std::move( identifier ) )
1565+ : itemType( std::move( typeDesc ) ), name( std::move( name ) ),
1566+ identifier( std::move( identifier ) ), hasIdentifierName( std::move( isIdentifierName ) )
15661567 {
15671568 return;
15681569 }
@@ -1597,7 +1598,7 @@
15971598 std::uint32_t codePage;
15981599 std::uint32_t reserved;
15991600 };
1600-
1601+
16011602 struct PEResourceDir : public PEResourceItem
16021603 {
16031604 inline PEResourceDir( bool isIdentifierName, std::u16string name, std::uint16_t identifier )
@@ -1662,7 +1663,7 @@
16621663 std::uint32_t timeDateStamp;
16631664 std::uint16_t majorVersion;
16641665 std::uint16_t minorVersion;
1665-
1666+
16661667 private:
16671668 struct _compareNamedEntry
16681669 {
@@ -1710,7 +1711,7 @@
17101711 std::set <PEResourceItem*, _compareIDEntry> idChildren;
17111712 };
17121713 PEResourceDir resourceRoot;
1713-
1714+
17141715 PESectionAllocation resAllocEntry;
17151716
17161717 struct PERuntimeFunction
@@ -1914,7 +1915,7 @@
19141915 inline PEBoundImport( void ) = default;
19151916 inline PEBoundImport( const PEBoundImport& right ) = delete;
19161917 inline PEBoundImport( PEBoundImport&& right ) = default;
1917-
1918+
19181919 inline PEBoundImport& operator = ( const PEBoundImport& right ) = delete;
19191920 inline PEBoundImport& operator = ( PEBoundImport&& right ) = default;
19201921
@@ -2001,4 +2002,4 @@
20012002 void CommitDataDirectories( void );
20022003 };
20032004
2004-#endif //_PELOADER_CORE_
\ No newline at end of file
2005+#endif //_PELOADER_CORE_
Show on old repository browser