diff -r 22486c9c7b15 -r 378360dbbdba bintools/petools/pe_dump/pe_dump.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bintools/petools/pe_dump/pe_dump.cpp Wed Jun 30 11:35:58 2010 +0800 @@ -0,0 +1,460 @@ +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include + +#include "h_ver.h" +#include "pe_defs.h" +#include + +#if defined(__MSVCDOTNET__) || defined (__TOOLS2__) + #include + #include + #include + #include + using namespace std; +#else //__MSVCDOTNET__ + #include + #include + #include + #include +#endif //__MSVCDOTNET__ + +#include + +const int KDiffIdentical=0; +const int KDiffDifferent=2; + +class PeFile + { +public: + PeFile(); + ~PeFile(); + int Open(char *aFileName); + void Close(); + PIMAGE_DOS_HEADER DosHeader(); + PIMAGE_NT_HEADERS Headers(); + PIMAGE_SECTION_HEADER SectionHeaders(); + char *LoadSection(PIMAGE_SECTION_HEADER aSectionHeader); + int NumberOfSections(); + char *LoadExtraData(int aOffsetToExtraData, TUint aFileSize); + + int Errno(); // Should be invoked only if previous call of PeFile's + // member function returns incorrectly + int Errno(int aErrno); // Assign error number for special purpose. +public: + fstream iFile; + PIMAGE_DOS_HEADER iDosHeader; + PIMAGE_NT_HEADERS iHeaders; + PIMAGE_SECTION_HEADER iSectionHeaders; +private: + int errnumber; + }; + +PeFile::PeFile() + //: iDosHeader(NULL), iHeaders(NULL), iSectionHeaders(NULL), errno(KErrNone) + //commented out as SBSv2 reports error: anachronistic old-style base class initializer +{ + iDosHeader = NULL ; + iHeaders = NULL ; + iSectionHeaders = NULL ; + errnumber = KErrNone; + + return; +} + +PeFile::~PeFile() + { + delete iDosHeader; + delete iHeaders; + delete [] iSectionHeaders; + } + +int PeFile::Open(char *aFileName) +{ +#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) + iFile.open(aFileName, ios::in | ios::binary); +#else //!__MSVCDOTNET__ + iFile.open(aFileName, ios::in | ios::binary | ios::nocreate); +#endif //__MSVCDOTNET__ + if (!iFile.is_open()) + { + errnumber = KErrNotFound; + return KErrNotFound; + } + return KErrNone; +} + +void PeFile::Close() + { + iFile.close(); + } + + +PIMAGE_DOS_HEADER PeFile::DosHeader() + { + if (iDosHeader) + return iDosHeader; + + iDosHeader=new IMAGE_DOS_HEADER; + if (!iDosHeader) { + errnumber = KErrNoMemory; + return NULL; + } + + memset(iDosHeader, 0, sizeof(IMAGE_DOS_HEADER)); + + iFile.seekg(0); + iFile.read((char *)iDosHeader, sizeof(IMAGE_DOS_HEADER)); + if (iDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) { + errnumber = KErrCorrupt; + return NULL; + } + return iDosHeader; + } + +PIMAGE_NT_HEADERS PeFile::Headers() + { + if (iHeaders) + return iHeaders; + PIMAGE_DOS_HEADER d=DosHeader(); + if (d==NULL) + return NULL; + + iHeaders=new IMAGE_NT_HEADERS; + if (!iHeaders) { + errnumber = KErrNoMemory; + return NULL; + } + + memset(iHeaders, 0, sizeof(IMAGE_NT_HEADERS)); + + iFile.seekg(d->e_lfanew); + if (iFile.eof()) { + errnumber = KErrCorrupt; // File size is too small. + return NULL; + } + + iFile.read((char *)iHeaders, sizeof(IMAGE_NT_HEADERS)); + return iHeaders; + } + +PIMAGE_SECTION_HEADER PeFile::SectionHeaders() + { + if (iSectionHeaders) + return iSectionHeaders; + PIMAGE_NT_HEADERS h=Headers(); + if (h==NULL) { + errnumber = KErrNoMemory; + return NULL; + } + + int numSec; + if ((numSec = NumberOfSections()) < 0) { + return NULL; + } + else { + iSectionHeaders=new IMAGE_SECTION_HEADER [numSec]; + if (!iSectionHeaders) { + errnumber = KErrNoMemory; + return NULL; + } + } + + iFile.seekg(DosHeader()->e_lfanew+sizeof(IMAGE_NT_HEADERS)); + int i=sizeof(IMAGE_SECTION_HEADER)*numSec; + iFile.read((char *)iSectionHeaders, i); + if (iFile.gcount() != i) { // The size of header is incorrect. + printf("Error: Cannot load section headers in offset: 0x%x \n", + (int) (DosHeader()->e_lfanew + sizeof(IMAGE_NT_HEADERS))); + errnumber = KErrCorrupt; + return NULL; + } + + return iSectionHeaders; + } + +int PeFile::NumberOfSections() + { + if (Headers()) + return iHeaders->FileHeader.NumberOfSections; + else + return -1; + } + +char *PeFile::LoadSection(PIMAGE_SECTION_HEADER h) + { + char *section=new char [h->SizeOfRawData]; + if (section==NULL){ + errnumber = KErrNoMemory; + return NULL; + } + + try + { + memset(section, 0, h->SizeOfRawData); + } + catch(...) + { + } + + iFile.seekg(h->PointerToRawData); + iFile.read(section, h->SizeOfRawData); + + // Guarantee we have loaded the section correctly. + unsigned int actNum = iFile.gcount(); + if (actNum != h->SizeOfRawData) { // The size of section is incorrect. + printf("Error: Cannot load section in offset: 0x%x \n", + (int)h->PointerToRawData); + errnumber = KErrCorrupt; + return NULL; + } + + return section; + } + +char* PeFile::LoadExtraData(int aOffset, TUint aFileSize) + { + TUint sizeOfExtraData = 0; + if(aFileSize >= (TUint)aOffset) + sizeOfExtraData=aFileSize-aOffset; + if(sizeOfExtraData>0){ + char* buffer=new char [sizeOfExtraData]; + if (!buffer) { + errnumber = KErrNoMemory; + return NULL; + } + + memset(buffer, 0, sizeOfExtraData); + iFile.seekg(aOffset); + iFile.read(buffer, sizeOfExtraData); // Should be OK if the file size is correct. + + // Guarantee we have loaded the data correctly. + unsigned int actNum = iFile.gcount(); + if (actNum != sizeOfExtraData){ // Shouldn't be here is the file size is correct. + printf("Error: Cannot load extra section in offset: 0x%x \n", aOffset); + errnumber = KErrCorrupt; + return NULL; + } + + return buffer; + } + else { + errnumber = KErrCorrupt; + return NULL; + } + +} + +int PeFile::Errno() { + return errnumber; +} + +int PeFile::Errno(int aErrno) { + return (errnumber = aErrno); +} + + +void dump(TUint *aData, TInt aLength) + { + TUint *p=aData; + TInt i=0; + char line[256]; + unsigned char *cp=(unsigned char*)aData; + TInt j=0; + memset(line,' ',sizeof(line)); + while (i127) + { + c = '.'; + } + *linep++ = c; + } + } + *linep='\0'; + printf("%s\n", line+(ccount*9)); + } + } + +int pecmp(char *aFileName) + { + + PeFile peFile; + if (peFile.Open(aFileName)!=KErrNone) + { + cout << "Cannot open file '"<FileHeader.TimeDateStamp=0; + headers->OptionalHeader.CheckSum = 0; // Fix for TOOLS2 + + printf("NT Headers:\n"); + dump((TUint*)headers, sizeof(IMAGE_NT_HEADERS)); + + int numberofsections=peFile.NumberOfSections(); + if (numberofsections==-1) + { + cout << "Not a valid PE file.\n"; + return KErrGeneral; + } + + PIMAGE_SECTION_HEADER sectionheaders=peFile.SectionHeaders(); + + printf("Section Headers:\n"); + dump((TUint*)sectionheaders, sizeof(IMAGE_SECTION_HEADER)*peFile.NumberOfSections()); + + TUint exportDirVa=headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + TUint debugDirVa=headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; + int SizeOfHeaders=headers->OptionalHeader.SizeOfHeaders; + int offsetToExtraData=0; + int i; + for (i=0; iSizeOfRawData == 0) + { + continue; + } + char *section=peFile.LoadSection(h); + if (section==NULL) + { + switch(peFile.Errno()){ + case KErrNoMemory: + cout << "Error: Out of memory\n"; + return KErrNoMemory; + default: + cout << "Not a valid PE file.\n"; + } + return KErrGeneral; + } + char name[9]; + for (int j=0; j<9; j++) + name[j]=h->Name[j]; + name[8]=0; + + if (debugDirVa>=h->VirtualAddress && debugDirVaVirtualAddress+h->SizeOfRawData) + { + // Debug data in this section + PIMAGE_DEBUG_DIRECTORY dd=(PIMAGE_DEBUG_DIRECTORY)(section+debugDirVa-h->VirtualAddress); + TInt debugDirSize=headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size; + while (debugDirSize>0) + { + dd->TimeDateStamp=0; + // size & location in file of debug data is not significant + // unless it's also mapped (AddressOfRawData != 0). If that's + // true, then the data will be visible in one of the sections + // anyway... + dd->SizeOfData=0; + dd->PointerToRawData=0; + dd++; + debugDirSize-=sizeof(IMAGE_DEBUG_DIRECTORY); + } + } + if (exportDirVa>=h->VirtualAddress && exportDirVaVirtualAddress+h->SizeOfRawData) + { + // Export directory in this section + PIMAGE_EXPORT_DIRECTORY ed=(PIMAGE_EXPORT_DIRECTORY)(section+exportDirVa-h->VirtualAddress); + ed->TimeDateStamp=0; + } + if (strcmp(".rsrc",name)==0) + { + int *t=(int *)(section+4); + *t=0; + } + + offsetToExtraData=offsetToExtraData+h->SizeOfRawData; + printf("Raw data:\n"); + dump((TUint*)section, h->SizeOfRawData); + + delete section; + } + struct stat buf; + stat (aFileName,&buf); + TUint fileSize=buf.st_size; + offsetToExtraData=offsetToExtraData+SizeOfHeaders; + TUint sizeOfExtraData = 0; + if(buf.st_size >= offsetToExtraData) + sizeOfExtraData=buf.st_size-offsetToExtraData; + char* extraData=peFile.LoadExtraData(offsetToExtraData, fileSize); + if(sizeOfExtraData>0){ + char* nsisSign; + nsisSign=extraData+8; + if(strncmp (nsisSign,"NullsoftInst",12) == 0){ + printf("\n\n Extra Data:\n"); + dump((TUint*)extraData, sizeOfExtraData); + } + } + peFile.Close(); + return KErrNone; + } + +int main(int argc, char *argv[]) + { + int r=KErrArgument; + if (argc==2) + { + r=pecmp(argv[1]); + } + if (r==KErrArgument) + { + cout << "\nPE_DUMP - PE file dumper V"; + cout << MajorVersion << '.' << setfill('0') << setw(2) << MinorVersion; + cout << '(' << setw(3) << Build << ")\n"; + cout << Copyright; + cout << "Syntax: "<