Example #1
0
TInt PEFile::Normalise()
//
// Remove the MSVC anomalies
//
	{

	// MSVC puts export data in with .rdata
	if (iExportDataDir && iSectionHeader[KExportSection]==NULL)
		{
		if (!PEFile::VirtualAddressInSection(iExportDataDir+iLinkedBase, iSectionHeader[KConstSection]))
			return Print(EError, "Can't find exports in this PE file.\n");
		else
			{
			iSectionHeader[KExportSection]=new IMAGE_SECTION_HEADER;
			iSectionHeader[KExportSection]->VirtualAddress=iExportDataDir;
			iSectionHeader[KExportSection]->Misc.VirtualSize=iExportDirSize;
			iSectionHeader[KExportSection]->SizeOfRawData=iExportDirSize;
			iSectionData[KExportSection]=new char [iExportDirSize];
			if (iSectionData[KExportSection]==NULL)
				return Print(EError, "Out of memory.\n");
			memcpy(iSectionData[KExportSection], iSectionData[KConstSection]+iExportDataDir-iSectionHeader[KConstSection]->VirtualAddress, iExportDirSize);
			// adjust .rdata so it does not include .edata
			iSectionHeader[KConstSection]->Misc.VirtualSize-=iExportDirSize;
			iSectionHeader[KConstSection]->SizeOfRawData-=iExportDirSize;
			char *c=new char [iSectionHeader[KConstSection]->SizeOfRawData];
			if (c==NULL)
				return Print(EError, "Out of memory.\n");
			memcpy(c, iSectionData[KConstSection], iSectionHeader[KConstSection]->SizeOfRawData);
			delete iSectionData[KConstSection];
			iSectionData[KConstSection]=c;
			}
		}
	// Stupid compilers generate .idata sections even when there are no imports
	if (iSectionHeader[KImportSection])
		{
		if (NumberOfImports()==0)
			{
			delete iSectionHeader[KImportSection];
			delete iSectionData[KImportSection];
			iSectionHeader[KImportSection]=NULL;
			iSectionData[KImportSection]=NULL;
			}
		}
	return KErrNone;
	}
Example #2
0
void E32ImageFile::RelocateSection(char* aPtr, char* aRelocs, TUint aCodeDelta, TUint aDataDelta, char* aImagePtr, TLinAddr** aIATRefs, TBool keepIAT)
//
// Relocates the section data at aPtr
//	
	{

	TUint codeStart=iHdr->iCodeBase;
	TUint codeFinish=codeStart+iHdr->iCodeSize;
	TUint iatStart = aIATRefs ? codeStart+iHdr->iTextSize : 0;
	TUint iatFinish = aIATRefs ? iatStart+NumberOfImports()*sizeof(TUint) : 0;
	char* relocs=aRelocs;
	TUint page=0;
	TInt size=0;
	TInt i=((E32RelocSection *)relocs)->iNumberOfRelocs;
	relocs+=sizeof(E32RelocSection);
	while (i>0)
		{
		if (size>0)
			{
			TUint offset=*(TUint16 *)relocs;
			relocs+=2;
			if (offset!=0)
				{ // its a reloc
				TUint va=page+(offset&0x0fff);
				TUint relocType=offset&0xf000;
				TUint *dataptr=(TUint *)(aPtr+va);
				assert((char *)dataptr < aRelocs);
				TUint data=*dataptr;
				if (relocType == KTextRelocType) 
					*dataptr=data+aCodeDelta; // points to text/rdata section
				else if (relocType == KDataRelocType)
					*dataptr=data+aDataDelta;
				else 
					{
					if (relocType != KInferredRelocType)
						Print(EError,"Unrecognized relocation type %x\n",relocType);

					if (data>=iatStart && data<iatFinish)
						{

						TUint iatNum = (data-iatStart)/sizeof(TLinAddr);

						// If "keepIAT" is used then the importing instruction must import through the IAT entry,
						// but otherwise we change the IAT entry to point to the bit of code doing the importing
						// and do the real fix-up later on in TRomBuilderEntry::FixupImports.
						// NB: We always want to do this for X86 or data exports dont work.
						if (keepIAT || (iHdr->iCpuIdentifier & 0x1000) /*denotes X86*/) 
							*dataptr=data+aCodeDelta; 
						else 
							{
							if ((TUint)aIATRefs[iatNum]>65535)
								Print(EWarning, "Multiple relocations for IAT entry %d (0x%x, 0x%x)\n",
										iatNum, aIATRefs[iatNum], dataptr);
							else
								aIATRefs[iatNum] = (TLinAddr*)(aImagePtr+va);	// ROM image address of importing pointer					
							}
						}
					else if (data>=codeStart && data<codeFinish)
						*dataptr=data+aCodeDelta; // points to text/rdata section
					else
						*dataptr=data+aDataDelta; // points to data section
					}
				--i;
				}
			size-=2;
			}
		else
			{ // next page of relocs
			page=*(TUint *)relocs;
			relocs+=4;
			size=*(TUint *)relocs;
			relocs+=4;
			size-=8;
			}
		}
	}