From ca5bb76d2b8f65aa97e50b633f828c1deb241526 Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Fri, 11 Jul 2008 16:51:25 +0000 Subject: Delete the svn:executable property and set svn:eol-style to native for all those text files. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18012 a1c6a512-1295-4272-9138-f99709370657 --- .../libraries/pelib-0.9/pelib/ImportDirectory.h | 2278 ++++++++++---------- 1 file changed, 1139 insertions(+), 1139 deletions(-) mode change 100755 => 100644 utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h (limited to 'utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h') diff --git a/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h b/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h old mode 100755 new mode 100644 index 6578f0712a..42526f0c3c --- a/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h +++ b/utils/zenutils/libraries/pelib-0.9/pelib/ImportDirectory.h @@ -1,1139 +1,1139 @@ -/* -* ImportDirectory.h - Part of the PeLib library. -* -* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) -* All rights reserved. -* -* This software is licensed under the zlib/libpng License. -* For more details see http://www.opensource.org/licenses/zlib-license.php -* or the license information file (license.htm) in the root directory -* of PeLib. -*/ - -#ifndef IMPORTDIRECTORY_H -#define IMPORTDIRECTORY_H - -#include "PeLibAux.h" -#include "PeHeader.h" - -namespace PeLib -{ - /// Parameter for functions that can operate on the OLDDIR or new import directory. - enum currdir {OLDDIR = 1, NEWDIR}; - - class PeLibException; - - /// Class that handles import directories. - /** - * This class can read import directories from existing PE files or start completely from scratch. - * Modifying import directories and writing them to files is also possible. - * It's worthy to note that many functions require an extra parameter of type currdir - * because the structure of import directories make it necessary that the OLDDIR import directory - * must be preserved. That's why some functions (like adding and removing) imported functions - * only exist for the new import directory, not for the one which is already written to the file. - * \todo Adding functions by ordinal doesn't work yet (rebuild needs to be changed). - * \todo Somehow store the rvas of the chunks in the file. - **/ - template - class ImportDirectory - { - typedef typename std::vector >::iterator ImpDirFileIterator; - typedef typename std::vector >::const_iterator ConstImpDirFileIterator; - - private: - /// Stores information about already imported DLLs. - std::vector > m_vOldiid; - /// Stores information about imported DLLs which will be added. - std::vector > m_vNewiid; - - // I can't convince Borland C++ to compile the function outside of the class declaration. - // That's why the function definition is here. - /// Tests if a certain function is imported. - template bool hasFunction(std::string strFilename, T value, bool(PELIB_THUNK_DATA::* comp)(T) const) const - { - ConstImpDirFileIterator FileIter = m_vOldiid.begin(); - ConstImpDirFileIterator EndIter = m_vOldiid.end(); - - for (int i=0;i<=1;i++) // Loop once for m_vOldiid and once for m_vNewiid - { - do - { - FileIter = std::find_if(FileIter, EndIter, std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY::operator==), strFilename)); - - if (FileIter != EndIter) - { - typename std::vector >::const_iterator Iter = std::find_if(FileIter->originalfirstthunk.begin(), FileIter->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(comp), value)); - if (Iter != FileIter->originalfirstthunk.end()) - { - return true; - } - ++FileIter; - } - } - while (FileIter != EndIter); - - FileIter = m_vNewiid.begin(); - EndIter = m_vNewiid.end(); - } - - return false; - } - - - public: - - /// Add a function to the import directory. - int addFunction(const std::string& strFilename, word wHint); // EXPORT _byHint - /// Add a function to the import directory. - int addFunction(const std::string& strFilename, const std::string& strFuncname); // EXPORT _byName - - /// Get the ID of a file through it's name. - unsigned int getFileIndex(const std::string& strFilename, currdir cdDir) const; // EXPORT - /// Get the ID of a function through it's name. - unsigned int getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const; // EXPORT - - /// Get the name of an imported file. - std::string getFileName(dword dwFilenr, currdir cdDir) const; // EXPORT - - void setFileName(dword filenr, currdir dir, const std::string& name); // EXPORT - - /// Get the hint of an imported function. - word getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT - void setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value); // EXPORT - /// Get the name of an imported function. - std::string getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT - void setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName); // EXPORT - /// Get the number of files which are imported. - dword getNumberOfFiles(currdir cdDir) const; // EXPORT - /// Get the number of fucntions which are imported by a specific file. - dword getNumberOfFunctions(dword dwFilenr, currdir cdDir) const; // EXPORT - /// Read a file's import directory. - int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT& pehHeader); // EXPORT - /// Rebuild the import directory. - void rebuild(std::vector& vBuffer, dword dwRva, bool fixEntries = true) const; // EXPORT - /// Remove a file from the import directory. - int removeFile(const std::string& strFilename); // EXPORT - /// Remove a function from the import directory. - int removeFunction(const std::string& strFilename, const std::string& strFuncname); // EXPORT _byName - /// Remove a function from the import directory. - int removeFunction(const std::string& strFilename, word wHint); // EXPORT _byHint - /// Returns the size of the current import directory. - unsigned int size() const; // EXPORT - /// Writes the import directory to a file. - int write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva); // EXPORT - - /// Returns the FirstThunk value of a function. - dword getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT _byNumber - void setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); // EXPORT _byNumber - /// Returns the OriginalFirstThunk value of a function. - dword getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT _byNumber - void setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); // EXPORT - -// dword getFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); -// dword getOriginalFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); - - /// Returns the FirstThunk value of a file. - dword getFirstThunk(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName - /// Returns the OriginalFirstThunk value of a file. - dword getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName - /// Returns the ForwarderChain value of a file. - dword getForwarderChain(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName - dword getRvaOfName(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName - /// Returns the TimeDateStamp value of a file. - dword getTimeDateStamp(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName - - /// Returns the FirstThunk value of a file. - dword getFirstThunk(dword dwFilenr, currdir cdDir) const; // EXPORT - void setFirstThunk(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function - /// Returns the OriginalFirstThunk value of a file. - dword getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const; // EXPORT - void setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function - /// Returns the ForwarderChain value of a file. - dword getForwarderChain(dword dwFilenr, currdir cdDir) const; // EXPORT _byNumber - void setForwarderChain(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function - dword getRvaOfName(dword dwFilenr, currdir cdDir) const; // EXPORT _byNumber - void setRvaOfName(dword dwFilenr, currdir cdDir, dword value); // EXPORT - /// Returns the TimeDateStamp value of a file. - dword getTimeDateStamp(dword dwFilenr, currdir cdDir) const; // EXPORT - void setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber - -// word getFunctionHint(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); - }; - - /** - * Add another import (by Ordinal) to the current file. Note that the import table is not automatically updated. - * The new imported functions will be added when you recalculate the import table as it's necessary - * to specify the address the import table will have in the file. - * @param strFilename The name of a DLL. - * @param wHint The ordinal of the function in the DLL. - **/ - template - int ImportDirectory::addFunction(const std::string& strFilename, word wHint) - { - if (hasFunction(strFilename, wHint, &PELIB_THUNK_DATA::equalHint)) - { - return ERROR_DUPLICATE_ENTRY; - } - - // Find the imported file. - ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY::operator==), strFilename)); - - PELIB_IMAGE_IMPORT_DIRECTORY iid; - PELIB_THUNK_DATA td; - td.hint = wHint; - td.itd.Ordinal = wHint | PELIB_IMAGE_ORDINAL_FLAGS::IMAGE_ORDINAL_FLAG; - iid.name = strFilename; - if (FileIter == m_vNewiid.end()) - { - iid.originalfirstthunk.push_back(td); - iid.firstthunk.push_back(td); - m_vNewiid.push_back(iid); - } - else - { - FileIter->originalfirstthunk.push_back(td); - FileIter->firstthunk.push_back(td); - } - - return NO_ERROR; - } - - /** - * Add a function to the Import Directory. - * @param strFilename Name of the file which will be imported - * @param strFuncname Name of the function which will be imported. - **/ - template - int ImportDirectory::addFunction(const std::string& strFilename, const std::string& strFuncname) - { - if (hasFunction(strFilename, strFuncname, &PELIB_THUNK_DATA::equalFunctionName)) - { - return ERROR_DUPLICATE_ENTRY; - } - - // Find the imported file. - ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY::operator==), strFilename)); - - PELIB_IMAGE_IMPORT_DIRECTORY iid; - PELIB_THUNK_DATA td; - td.fname = strFuncname; - iid.name = strFilename; - if (FileIter == m_vNewiid.end()) - { - iid.originalfirstthunk.push_back(td); - iid.firstthunk.push_back(td); - m_vNewiid.push_back(iid); - } - else - { - FileIter->originalfirstthunk.push_back(td); - FileIter->firstthunk.push_back(td); - } - - return NO_ERROR; - } - - /** - * Searches through the import directory and returns the number of the import - * directory entry which belongs to the given filename. - * @param strFilename Name of the imported file. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return The ID of an imported file. - **/ - template - unsigned int ImportDirectory::getFileIndex(const std::string& strFilename, currdir cdDir) const - { - const std::vector >* currDir; - - if (cdDir == OLDDIR) - { - currDir = &m_vOldiid; - } - else - { - currDir = &m_vNewiid; - } - - ConstImpDirFileIterator FileIter = std::find_if(currDir->begin(), currDir->end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY::operator==), strFilename)); - - if (FileIter != currDir->end()) - { - return static_cast(std::distance(currDir->begin(), FileIter)); - } - else - { - return -1; - // throw Exceptions::InvalidName(ImportDirectoryId, __LINE__); - } - - return NO_ERROR; - } - - /** - * Searches through an imported file for a specific function. - * @param strFilename Name of the imported file. - * @param strFuncname Name of the imported function. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return ID of the imported function. - **/ - template - unsigned int ImportDirectory::getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const - { - unsigned int uiFile = getFileIndex(strFilename, cdDir); - - for (unsigned int i=0;i - std::string ImportDirectory::getFileName(dword dwFilenr, currdir cdDir) const - { - if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].name; - else return m_vNewiid[dwFilenr].name; - } - - template - void ImportDirectory::setFileName(dword filenr, currdir dir, const std::string& name) - { - if (dir == OLDDIR) m_vOldiid[filenr].name = name; - else m_vNewiid[filenr].name = name; - } - - /** - * Get the name of an imported function. - * @param dwFilenr Identifies which file should be checked. - * @param dwFuncnr Identifies which function should be checked. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return Name of an imported function. - * \todo Marked line is unsafe (function should be rewritten). - **/ - template - std::string ImportDirectory::getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - // Unsafe - if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) - { - return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname; - } - else - { - return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname; - } - } - else - { - if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk) - { - return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname; - } - else - { - return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname; - } - } - } - - template - void ImportDirectory::setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName) - { - if (cdDir == OLDDIR) - { - // Unsafe - if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) - { - m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName; - } - else - { - m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName; - } - } - else - { - if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk) - { - m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName; - } - else - { - m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName; - } - } - } - - /** - * Get the hint of an imported function. - * @param dwFilenr Identifies which file should be checked. - * @param dwFuncnr Identifies which function should be checked. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return Hint of an imported function. - **/ - template - word ImportDirectory::getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) - { - return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint; - } - else - { - return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint; - } - } - else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint; - } - - template - void ImportDirectory::setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value) - { - if (cdDir == OLDDIR) - { - if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) - { - m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value; - } - else - { - m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint = value; - } - } - else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value; - } - - /** - * Get the number of files which are currently being imported. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return Number of files which are currently being imported. - **/ - template - dword ImportDirectory::getNumberOfFiles(currdir cdDir) const - { - if (cdDir == OLDDIR) return static_cast(m_vOldiid.size()); - else return static_cast(m_vNewiid.size()); - } - - /** - * Get the number of functions which are currently being imported from a specific file. - * @param dwFilenr Identifies which file should be checked. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return Number of functions which are currently being imported from a specific file. - **/ - template - dword ImportDirectory::getNumberOfFunctions(dword dwFilenr, currdir cdDir) const - { - if (cdDir == OLDDIR) return static_cast(m_vOldiid[dwFilenr].firstthunk.size()); - else return static_cast(m_vNewiid[dwFilenr].firstthunk.size()); - } - - /** - * Read an import directory from a file. - * \todo Check if streams failed. - * @param strFilename Name of the file which will be read. - * @param uiOffset Offset of the import directory (see #PeLib::PeHeader::getIDImportRVA). - * @param uiSize Size of the import directory (see #PeLib::PeHeader::getIDImportSize). - * @param pehHeader A valid PE header. - **/ - template - int ImportDirectory::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT& pehHeader) - { - std::ifstream ifFile(strFilename.c_str(), std::ios_base::binary); - - if (!ifFile) - { - return ERROR_OPENING_FILE; - } - - unsigned int uiFileSize = fileSize(ifFile); - - if (uiFileSize < uiOffset + uiSize) - { - return ERROR_INVALID_FILE; - } - - ifFile.seekg(uiOffset, std::ios_base::beg); - - std::vector vImportdirectory(uiSize); - ifFile.read(reinterpret_cast(&vImportdirectory[0]), uiSize); - - PELIB_IMAGE_IMPORT_DIRECTORY iidCurr; - unsigned int uiDesccounter = 0; - - InputBuffer inpBuffer(vImportdirectory); - - std::vector > vOldIidCurr; - - do // Read and store all descriptors - { - inpBuffer >> iidCurr.impdesc.OriginalFirstThunk; - inpBuffer >> iidCurr.impdesc.TimeDateStamp; - inpBuffer >> iidCurr.impdesc.ForwarderChain; - inpBuffer >> iidCurr.impdesc.Name; - inpBuffer >> iidCurr.impdesc.FirstThunk; - - if (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 || - iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0) - { - vOldIidCurr.push_back(iidCurr); - } - - uiDesccounter++; - - if (uiSize < (uiDesccounter + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size()) break; - } while (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 || - iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0); - - char namebuffer[2] = {0}; - - // Name - for (unsigned int i=0;i(pehHeader.rvaToOffset(vOldIidCurr[i].impdesc.Name)), std::ios_base::beg); - - std::string dllname = ""; - - do - { - ifFile.read(namebuffer, 1); - if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte - dllname += namebuffer; - } while (true); - - vOldIidCurr[i].name = dllname; - - } - - // OriginalFirstThunk - for (unsigned int i=0;i tdCurr; - dword uiVaoft = vOldIidCurr[i].impdesc.OriginalFirstThunk; - - if (!uiVaoft) - { - continue; - } - - ifFile.seekg(static_cast(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg); - - do - { - if (uiFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal)) - { - return ERROR_INVALID_FILE; - } - uiVaoft += sizeof(tdCurr.itd.Ordinal); - - ifFile.read(reinterpret_cast(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal)); - if (tdCurr.itd.Ordinal) vOldIidCurr[i].originalfirstthunk.push_back(tdCurr); - } while (tdCurr.itd.Ordinal); - } - - // FirstThunk - for (unsigned int i=0;i tdCurr; - - ifFile.seekg(static_cast(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg); - - do - { - if (uiFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal)) - { - return ERROR_INVALID_FILE; - } - - uiVaoft += sizeof(tdCurr.itd.Ordinal); - - ifFile.read(reinterpret_cast(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal)); - if (tdCurr.itd.Ordinal) vOldIidCurr[i].firstthunk.push_back(tdCurr); - } while (tdCurr.itd.Ordinal); - } - - // Names - for (unsigned int i=0;i::IMAGE_ORDINAL_FLAG) - { - vOldIidCurr[i].originalfirstthunk[j].hint = 0; - continue; - } - - ifFile.seekg(static_cast(pehHeader.rvaToOffset(vOldIidCurr[i].originalfirstthunk[j].itd.Ordinal)), std::ios_base::beg); - - ifFile.read(reinterpret_cast(&vOldIidCurr[i].originalfirstthunk[j].hint), sizeof(vOldIidCurr[i].originalfirstthunk[j].hint)); - - if (!ifFile) - return ERROR_INVALID_FILE; - - std::string funcname = ""; - do - { - ifFile.read(namebuffer, 1); - if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte - funcname += namebuffer; - } while (true); - - vOldIidCurr[i].originalfirstthunk[j].fname = funcname; - } - } - else - { - for (unsigned int j=0;j::IMAGE_ORDINAL_FLAG) - { - continue; - } - - ifFile.seekg(static_cast(pehHeader.rvaToOffset(vOldIidCurr[i].firstthunk[j].itd.Ordinal)), std::ios_base::beg); - - ifFile.read(reinterpret_cast(&vOldIidCurr[i].firstthunk[j].hint), sizeof(vOldIidCurr[i].firstthunk[j].hint)); - - if (!ifFile) - return ERROR_INVALID_FILE; - - std::string funcname = ""; - do - { - ifFile.read(namebuffer, 1); - if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte - funcname += namebuffer; - } while (true); - - vOldIidCurr[i].firstthunk[j].fname = funcname; - } - } - } - std::swap(vOldIidCurr, m_vOldiid); - return NO_ERROR; - } - - /** - * Rebuilds the import directory. - * @param vBuffer Buffer the rebuilt import directory will be written to. - * @param dwRva The RVA of the ImportDirectory in the file. - * \todo uiSizeoffuncnames is not used. - **/ - template - void ImportDirectory::rebuild(std::vector& vBuffer, dword dwRva, bool fixEntries) const - { - unsigned int uiImprva = dwRva; - unsigned int uiSizeofdescriptors = (static_cast(m_vNewiid.size() + m_vOldiid.size()) + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size(); - - unsigned int uiSizeofdllnames = 0, uiSizeoffuncnames = 0; - unsigned int uiSizeofoft = 0; - - for (unsigned int i=0;i(m_vNewiid[i].name.size()) + 1; - uiSizeofoft += (static_cast(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA::size(); - - for(unsigned int j=0;j(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3); - } - } - -// for (unsigned int i=0;i(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA::size(); -// } - - OutputBuffer obBuffer(vBuffer); - - // Rebuild IMAGE_IMPORT_DESCRIPTORS - for (unsigned int i=0;i(m_vNewiid[j-1].originalfirstthunk.size()) + 1) * PELIB_IMAGE_THUNK_DATA::size(); - } - - obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.OriginalFirstThunk); - obBuffer << m_vNewiid[i].impdesc.TimeDateStamp; - obBuffer << m_vNewiid[i].impdesc.ForwarderChain; - dword dwPdll = uiSizeofdescriptors + uiSizeofoft + uiImprva + dllsize; - obBuffer << (fixEntries ? dwPdll : m_vNewiid[i].impdesc.Name); - obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.FirstThunk); - - dllsize += static_cast(m_vNewiid[i].name.size()) + 1; - } - - obBuffer << (dword)0; - obBuffer << (dword)0; - obBuffer << (dword)0; - obBuffer << (dword)0; - obBuffer << (dword)0; - - unsigned int uiPfunc = uiSizeofdescriptors + uiSizeofoft + uiSizeofdllnames + uiImprva; - - // Rebuild original first thunk - for (unsigned int i=0;i::IMAGE_ORDINAL_FLAG - || fixEntries == false) - { - obBuffer << m_vNewiid[i].originalfirstthunk[j].itd.Ordinal; - } - else - { - obBuffer << uiPfunc; - } - uiPfunc += static_cast(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3; - } - obBuffer << (dword)0; - } - - // Write dllnames into import directory - for (unsigned int i=0;i(m_vNewiid[i].name.size())+1); - } - - // Write function names into directory - for (unsigned int i=0;i(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 1); - } - } - } - - /** - * Removes a specific file and all functions of it from the import directory. - * @param strFilename Name of the file which will be removed. - **/ - template - int ImportDirectory::removeFile(const std::string& strFilename) - { - unsigned int oldSize = static_cast(m_vNewiid.size()); - - m_vNewiid.erase(std::remove_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY::operator==), strFilename)), m_vNewiid.end()); - - return oldSize == m_vNewiid.size() ? 1 : 0; - } - - /** - * Removes a specific function from the import directory. - * @param strFilename Name of the file which exports the function. - * @param strFuncname Name of the imported function. - **/ - template - int ImportDirectory::removeFunction(const std::string& strFilename, const std::string& strFuncname) - { - ImpDirFileIterator viPos = m_vNewiid.begin(); - - int notFound = 1; - - while (viPos != m_vNewiid.end()) - { - if (isEqualNc(viPos->name, strFilename)) - { - unsigned int oldSize = static_cast(viPos->originalfirstthunk.size()); - viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA::equalFunctionName), strFuncname)), viPos->originalfirstthunk.end()); - //viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(CompPolicy(), strFuncname))); - if (viPos->originalfirstthunk.size() != oldSize) notFound = 0; - } - ++viPos; - } - - return notFound; - } - - /** - * Removes a specific function from the import directory. - * @param strFilename Name of the file which exports the function. - * @param wHint The hint of the function. - **/ - template - int ImportDirectory::removeFunction(const std::string& strFilename, word wHint) - { - ImpDirFileIterator viPos = m_vNewiid.begin(); - int notFound = 1; - - while (viPos != m_vNewiid.end()) - { - if (isEqualNc(viPos->name, strFilename)) - { - unsigned int oldSize = static_cast(viPos->originalfirstthunk.size()); - viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA::equalHint), wHint)), viPos->originalfirstthunk.end()); - unsigned int newPos = static_cast(viPos->originalfirstthunk.size()); - if (viPos->originalfirstthunk.size() != oldSize) notFound = 0; - } - ++viPos; - } - - return notFound; - } - - /** - * Writes the current import directory to a file. - * @param strFilename Name of the file. - * @param uiOffset File Offset of the new import directory. - * @param uiRva RVA which belongs to that file offset. - **/ - template - int ImportDirectory::write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) - { - std::fstream ofFile(strFilename.c_str(), std::ios_base::in); - - if (!ofFile) - { - ofFile.clear(); - ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); - } - else - { - ofFile.close(); - ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); - } - - if (!ofFile) - { - return ERROR_OPENING_FILE; - } - - ofFile.seekp(uiOffset, std::ios_base::beg); - - std::vector vBuffer; - - rebuild(vBuffer, uiRva); - - ofFile.write(reinterpret_cast(&vBuffer[0]), vBuffer.size()); - ofFile.close(); - - std::copy(m_vNewiid.begin(), m_vNewiid.end(), std::back_inserter(m_vOldiid)); - m_vNewiid.clear(); - - return NO_ERROR; - } - - /** - * Returns the size of the import directory. - * @return Size of the import directory. - **/ - template - unsigned int ImportDirectory::size() const - { - // Only the descriptors of m_vOldiid must be rebuilt, not the data they point to. - return std::accumulate(m_vNewiid.begin(), m_vNewiid.end(), 0, accumulate >) - + (m_vOldiid.size() + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size(); - } - - /** - * @param strFilename Name of the imported file. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return FirstThunk value of an imported file. - **/ - template - dword ImportDirectory::getFirstThunk(const std::string& strFilename, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk; - } - else - { - return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk; - } - } - - /** - * @param strFilename Name of the imported file. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return OriginalFirstThunk value of an imported file. - **/ - template - dword ImportDirectory::getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk; - } - else - { - return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk; - } - } - - /** - * @param strFilename Name of the imported file. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return ForwarderChain value of an imported file. - **/ - template - dword ImportDirectory::getForwarderChain(const std::string& strFilename, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain; - } - else - { - return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain; - } - } - - /** - * @param strFilename Name of the imported file. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return TimeDateStamp value of an imported file. - **/ - template - dword ImportDirectory::getTimeDateStamp(const std::string& strFilename, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp; - } - else - { - return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp; - } - } - - template - dword ImportDirectory::getRvaOfName(const std::string& strFilename, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.Name; - } - else - { - return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.Name; - } - } - - /** - * @param strFilename Name of the imported file. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return FirstThunk value of an imported file. - **/ - template - dword ImportDirectory::getFirstThunk(dword dwFilenr, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - return m_vOldiid[dwFilenr].impdesc.FirstThunk; - } - else - { - return m_vNewiid[dwFilenr].impdesc.FirstThunk; - } - } - - template - void ImportDirectory::setFirstThunk(dword dwFilenr, currdir cdDir, dword value) - { - if (cdDir == OLDDIR) - { - m_vOldiid[dwFilenr].impdesc.FirstThunk = value; - } - else - { - m_vNewiid[dwFilenr].impdesc.FirstThunk = value; - } - } - - /** - * @param strFilename Name of the imported file. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return OriginalFirstThunk value of an imported file. - **/ - template - dword ImportDirectory::getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - return m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk; - } - else - { - return m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk; - } - } - - template - void ImportDirectory::setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value) - { - if (cdDir == OLDDIR) - { - m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk = value; - } - else - { - m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk = value; - } - } - - /** - * @param strFilename Name of the imported file. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return ForwarderChain value of an imported file. - **/ - template - dword ImportDirectory::getForwarderChain(dword dwFilenr, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - return m_vOldiid[dwFilenr].impdesc.ForwarderChain; - } - else - { - return m_vNewiid[dwFilenr].impdesc.ForwarderChain; - } - } - - template - void ImportDirectory::setForwarderChain(dword dwFilenr, currdir cdDir, dword value) - { - if (cdDir == OLDDIR) - { - m_vOldiid[dwFilenr].impdesc.ForwarderChain = value; - } - else - { - m_vNewiid[dwFilenr].impdesc.ForwarderChain = value; - } - } - - /** - * @param strFilename Name of the imported file. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return TimeDateStamp value of an imported file. - **/ - template - dword ImportDirectory::getTimeDateStamp(dword dwFilenr, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - return m_vOldiid[dwFilenr].impdesc.TimeDateStamp; - } - else - { - return m_vNewiid[dwFilenr].impdesc.TimeDateStamp; - } - } - - template - void ImportDirectory::setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value) - { - if (cdDir == OLDDIR) - { - m_vOldiid[dwFilenr].impdesc.TimeDateStamp = value; - } - else - { - m_vNewiid[dwFilenr].impdesc.TimeDateStamp = value; - } - } - - template - dword ImportDirectory::getRvaOfName(dword dwFilenr, currdir cdDir) const - { - if (cdDir == OLDDIR) - { - return m_vOldiid[dwFilenr].impdesc.Name; - } - else - { - return m_vNewiid[dwFilenr].impdesc.Name; - } - } - - template - void ImportDirectory::setRvaOfName(dword dwFilenr, currdir cdDir, dword value) - { - if (cdDir == OLDDIR) - { - m_vOldiid[dwFilenr].impdesc.Name = value; - } - else - { - m_vNewiid[dwFilenr].impdesc.Name = value; - } - } - - /** - * @param dwFilenr ID of the imported file. - * @param dwFuncnr ID of the imported function. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return FirstThunk value of an imported function. - **/ - template - dword ImportDirectory::getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const - { - if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal; - else return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal; - } - - template - void ImportDirectory::setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value) - { - if (cdDir == OLDDIR) m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value; - else m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value; - } - - /** - * @param dwFilenr ID of the imported file. - * @param dwFuncnr ID of the imported function. - * @param cdDir Flag to decide if the OLDDIR or new import directory is used. - * @return OriginalFirstThunk value of an imported function. - **/ - template - dword ImportDirectory::getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const - { - if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal; - else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal; - } - - template - void ImportDirectory::setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value) - { - if (cdDir == OLDDIR) m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value; - else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value; - } - - typedef ImportDirectory<32> ImportDirectory32; - typedef ImportDirectory<64> ImportDirectory64; -} - -#endif +/* +* ImportDirectory.h - Part of the PeLib library. +* +* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com) +* All rights reserved. +* +* This software is licensed under the zlib/libpng License. +* For more details see http://www.opensource.org/licenses/zlib-license.php +* or the license information file (license.htm) in the root directory +* of PeLib. +*/ + +#ifndef IMPORTDIRECTORY_H +#define IMPORTDIRECTORY_H + +#include "PeLibAux.h" +#include "PeHeader.h" + +namespace PeLib +{ + /// Parameter for functions that can operate on the OLDDIR or new import directory. + enum currdir {OLDDIR = 1, NEWDIR}; + + class PeLibException; + + /// Class that handles import directories. + /** + * This class can read import directories from existing PE files or start completely from scratch. + * Modifying import directories and writing them to files is also possible. + * It's worthy to note that many functions require an extra parameter of type currdir + * because the structure of import directories make it necessary that the OLDDIR import directory + * must be preserved. That's why some functions (like adding and removing) imported functions + * only exist for the new import directory, not for the one which is already written to the file. + * \todo Adding functions by ordinal doesn't work yet (rebuild needs to be changed). + * \todo Somehow store the rvas of the chunks in the file. + **/ + template + class ImportDirectory + { + typedef typename std::vector >::iterator ImpDirFileIterator; + typedef typename std::vector >::const_iterator ConstImpDirFileIterator; + + private: + /// Stores information about already imported DLLs. + std::vector > m_vOldiid; + /// Stores information about imported DLLs which will be added. + std::vector > m_vNewiid; + + // I can't convince Borland C++ to compile the function outside of the class declaration. + // That's why the function definition is here. + /// Tests if a certain function is imported. + template bool hasFunction(std::string strFilename, T value, bool(PELIB_THUNK_DATA::* comp)(T) const) const + { + ConstImpDirFileIterator FileIter = m_vOldiid.begin(); + ConstImpDirFileIterator EndIter = m_vOldiid.end(); + + for (int i=0;i<=1;i++) // Loop once for m_vOldiid and once for m_vNewiid + { + do + { + FileIter = std::find_if(FileIter, EndIter, std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY::operator==), strFilename)); + + if (FileIter != EndIter) + { + typename std::vector >::const_iterator Iter = std::find_if(FileIter->originalfirstthunk.begin(), FileIter->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(comp), value)); + if (Iter != FileIter->originalfirstthunk.end()) + { + return true; + } + ++FileIter; + } + } + while (FileIter != EndIter); + + FileIter = m_vNewiid.begin(); + EndIter = m_vNewiid.end(); + } + + return false; + } + + + public: + + /// Add a function to the import directory. + int addFunction(const std::string& strFilename, word wHint); // EXPORT _byHint + /// Add a function to the import directory. + int addFunction(const std::string& strFilename, const std::string& strFuncname); // EXPORT _byName + + /// Get the ID of a file through it's name. + unsigned int getFileIndex(const std::string& strFilename, currdir cdDir) const; // EXPORT + /// Get the ID of a function through it's name. + unsigned int getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const; // EXPORT + + /// Get the name of an imported file. + std::string getFileName(dword dwFilenr, currdir cdDir) const; // EXPORT + + void setFileName(dword filenr, currdir dir, const std::string& name); // EXPORT + + /// Get the hint of an imported function. + word getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT + void setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value); // EXPORT + /// Get the name of an imported function. + std::string getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT + void setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName); // EXPORT + /// Get the number of files which are imported. + dword getNumberOfFiles(currdir cdDir) const; // EXPORT + /// Get the number of fucntions which are imported by a specific file. + dword getNumberOfFunctions(dword dwFilenr, currdir cdDir) const; // EXPORT + /// Read a file's import directory. + int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT& pehHeader); // EXPORT + /// Rebuild the import directory. + void rebuild(std::vector& vBuffer, dword dwRva, bool fixEntries = true) const; // EXPORT + /// Remove a file from the import directory. + int removeFile(const std::string& strFilename); // EXPORT + /// Remove a function from the import directory. + int removeFunction(const std::string& strFilename, const std::string& strFuncname); // EXPORT _byName + /// Remove a function from the import directory. + int removeFunction(const std::string& strFilename, word wHint); // EXPORT _byHint + /// Returns the size of the current import directory. + unsigned int size() const; // EXPORT + /// Writes the import directory to a file. + int write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva); // EXPORT + + /// Returns the FirstThunk value of a function. + dword getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT _byNumber + void setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); // EXPORT _byNumber + /// Returns the OriginalFirstThunk value of a function. + dword getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; // EXPORT _byNumber + void setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); // EXPORT + +// dword getFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); +// dword getOriginalFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); + + /// Returns the FirstThunk value of a file. + dword getFirstThunk(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName + /// Returns the OriginalFirstThunk value of a file. + dword getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName + /// Returns the ForwarderChain value of a file. + dword getForwarderChain(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName + dword getRvaOfName(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName + /// Returns the TimeDateStamp value of a file. + dword getTimeDateStamp(const std::string& strFilename, currdir cdDir) const; // EXPORT _byName + + /// Returns the FirstThunk value of a file. + dword getFirstThunk(dword dwFilenr, currdir cdDir) const; // EXPORT + void setFirstThunk(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function + /// Returns the OriginalFirstThunk value of a file. + dword getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const; // EXPORT + void setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function + /// Returns the ForwarderChain value of a file. + dword getForwarderChain(dword dwFilenr, currdir cdDir) const; // EXPORT _byNumber + void setForwarderChain(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber_function + dword getRvaOfName(dword dwFilenr, currdir cdDir) const; // EXPORT _byNumber + void setRvaOfName(dword dwFilenr, currdir cdDir, dword value); // EXPORT + /// Returns the TimeDateStamp value of a file. + dword getTimeDateStamp(dword dwFilenr, currdir cdDir) const; // EXPORT + void setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value); // EXPORT _byNumber + +// word getFunctionHint(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); + }; + + /** + * Add another import (by Ordinal) to the current file. Note that the import table is not automatically updated. + * The new imported functions will be added when you recalculate the import table as it's necessary + * to specify the address the import table will have in the file. + * @param strFilename The name of a DLL. + * @param wHint The ordinal of the function in the DLL. + **/ + template + int ImportDirectory::addFunction(const std::string& strFilename, word wHint) + { + if (hasFunction(strFilename, wHint, &PELIB_THUNK_DATA::equalHint)) + { + return ERROR_DUPLICATE_ENTRY; + } + + // Find the imported file. + ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY::operator==), strFilename)); + + PELIB_IMAGE_IMPORT_DIRECTORY iid; + PELIB_THUNK_DATA td; + td.hint = wHint; + td.itd.Ordinal = wHint | PELIB_IMAGE_ORDINAL_FLAGS::IMAGE_ORDINAL_FLAG; + iid.name = strFilename; + if (FileIter == m_vNewiid.end()) + { + iid.originalfirstthunk.push_back(td); + iid.firstthunk.push_back(td); + m_vNewiid.push_back(iid); + } + else + { + FileIter->originalfirstthunk.push_back(td); + FileIter->firstthunk.push_back(td); + } + + return NO_ERROR; + } + + /** + * Add a function to the Import Directory. + * @param strFilename Name of the file which will be imported + * @param strFuncname Name of the function which will be imported. + **/ + template + int ImportDirectory::addFunction(const std::string& strFilename, const std::string& strFuncname) + { + if (hasFunction(strFilename, strFuncname, &PELIB_THUNK_DATA::equalFunctionName)) + { + return ERROR_DUPLICATE_ENTRY; + } + + // Find the imported file. + ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY::operator==), strFilename)); + + PELIB_IMAGE_IMPORT_DIRECTORY iid; + PELIB_THUNK_DATA td; + td.fname = strFuncname; + iid.name = strFilename; + if (FileIter == m_vNewiid.end()) + { + iid.originalfirstthunk.push_back(td); + iid.firstthunk.push_back(td); + m_vNewiid.push_back(iid); + } + else + { + FileIter->originalfirstthunk.push_back(td); + FileIter->firstthunk.push_back(td); + } + + return NO_ERROR; + } + + /** + * Searches through the import directory and returns the number of the import + * directory entry which belongs to the given filename. + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return The ID of an imported file. + **/ + template + unsigned int ImportDirectory::getFileIndex(const std::string& strFilename, currdir cdDir) const + { + const std::vector >* currDir; + + if (cdDir == OLDDIR) + { + currDir = &m_vOldiid; + } + else + { + currDir = &m_vNewiid; + } + + ConstImpDirFileIterator FileIter = std::find_if(currDir->begin(), currDir->end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY::operator==), strFilename)); + + if (FileIter != currDir->end()) + { + return static_cast(std::distance(currDir->begin(), FileIter)); + } + else + { + return -1; + // throw Exceptions::InvalidName(ImportDirectoryId, __LINE__); + } + + return NO_ERROR; + } + + /** + * Searches through an imported file for a specific function. + * @param strFilename Name of the imported file. + * @param strFuncname Name of the imported function. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return ID of the imported function. + **/ + template + unsigned int ImportDirectory::getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const + { + unsigned int uiFile = getFileIndex(strFilename, cdDir); + + for (unsigned int i=0;i + std::string ImportDirectory::getFileName(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].name; + else return m_vNewiid[dwFilenr].name; + } + + template + void ImportDirectory::setFileName(dword filenr, currdir dir, const std::string& name) + { + if (dir == OLDDIR) m_vOldiid[filenr].name = name; + else m_vNewiid[filenr].name = name; + } + + /** + * Get the name of an imported function. + * @param dwFilenr Identifies which file should be checked. + * @param dwFuncnr Identifies which function should be checked. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return Name of an imported function. + * \todo Marked line is unsafe (function should be rewritten). + **/ + template + std::string ImportDirectory::getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + // Unsafe + if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) + { + return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname; + } + else + { + return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname; + } + } + else + { + if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk) + { + return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname; + } + else + { + return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname; + } + } + } + + template + void ImportDirectory::setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName) + { + if (cdDir == OLDDIR) + { + // Unsafe + if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) + { + m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName; + } + else + { + m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName; + } + } + else + { + if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk) + { + m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName; + } + else + { + m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName; + } + } + } + + /** + * Get the hint of an imported function. + * @param dwFilenr Identifies which file should be checked. + * @param dwFuncnr Identifies which function should be checked. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return Hint of an imported function. + **/ + template + word ImportDirectory::getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) + { + return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint; + } + else + { + return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint; + } + } + else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint; + } + + template + void ImportDirectory::setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value) + { + if (cdDir == OLDDIR) + { + if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) + { + m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value; + } + else + { + m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint = value; + } + } + else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value; + } + + /** + * Get the number of files which are currently being imported. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return Number of files which are currently being imported. + **/ + template + dword ImportDirectory::getNumberOfFiles(currdir cdDir) const + { + if (cdDir == OLDDIR) return static_cast(m_vOldiid.size()); + else return static_cast(m_vNewiid.size()); + } + + /** + * Get the number of functions which are currently being imported from a specific file. + * @param dwFilenr Identifies which file should be checked. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return Number of functions which are currently being imported from a specific file. + **/ + template + dword ImportDirectory::getNumberOfFunctions(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) return static_cast(m_vOldiid[dwFilenr].firstthunk.size()); + else return static_cast(m_vNewiid[dwFilenr].firstthunk.size()); + } + + /** + * Read an import directory from a file. + * \todo Check if streams failed. + * @param strFilename Name of the file which will be read. + * @param uiOffset Offset of the import directory (see #PeLib::PeHeader::getIDImportRVA). + * @param uiSize Size of the import directory (see #PeLib::PeHeader::getIDImportSize). + * @param pehHeader A valid PE header. + **/ + template + int ImportDirectory::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT& pehHeader) + { + std::ifstream ifFile(strFilename.c_str(), std::ios_base::binary); + + if (!ifFile) + { + return ERROR_OPENING_FILE; + } + + unsigned int uiFileSize = fileSize(ifFile); + + if (uiFileSize < uiOffset + uiSize) + { + return ERROR_INVALID_FILE; + } + + ifFile.seekg(uiOffset, std::ios_base::beg); + + std::vector vImportdirectory(uiSize); + ifFile.read(reinterpret_cast(&vImportdirectory[0]), uiSize); + + PELIB_IMAGE_IMPORT_DIRECTORY iidCurr; + unsigned int uiDesccounter = 0; + + InputBuffer inpBuffer(vImportdirectory); + + std::vector > vOldIidCurr; + + do // Read and store all descriptors + { + inpBuffer >> iidCurr.impdesc.OriginalFirstThunk; + inpBuffer >> iidCurr.impdesc.TimeDateStamp; + inpBuffer >> iidCurr.impdesc.ForwarderChain; + inpBuffer >> iidCurr.impdesc.Name; + inpBuffer >> iidCurr.impdesc.FirstThunk; + + if (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 || + iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0) + { + vOldIidCurr.push_back(iidCurr); + } + + uiDesccounter++; + + if (uiSize < (uiDesccounter + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size()) break; + } while (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 || + iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0); + + char namebuffer[2] = {0}; + + // Name + for (unsigned int i=0;i(pehHeader.rvaToOffset(vOldIidCurr[i].impdesc.Name)), std::ios_base::beg); + + std::string dllname = ""; + + do + { + ifFile.read(namebuffer, 1); + if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte + dllname += namebuffer; + } while (true); + + vOldIidCurr[i].name = dllname; + + } + + // OriginalFirstThunk + for (unsigned int i=0;i tdCurr; + dword uiVaoft = vOldIidCurr[i].impdesc.OriginalFirstThunk; + + if (!uiVaoft) + { + continue; + } + + ifFile.seekg(static_cast(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg); + + do + { + if (uiFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal)) + { + return ERROR_INVALID_FILE; + } + uiVaoft += sizeof(tdCurr.itd.Ordinal); + + ifFile.read(reinterpret_cast(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal)); + if (tdCurr.itd.Ordinal) vOldIidCurr[i].originalfirstthunk.push_back(tdCurr); + } while (tdCurr.itd.Ordinal); + } + + // FirstThunk + for (unsigned int i=0;i tdCurr; + + ifFile.seekg(static_cast(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg); + + do + { + if (uiFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal)) + { + return ERROR_INVALID_FILE; + } + + uiVaoft += sizeof(tdCurr.itd.Ordinal); + + ifFile.read(reinterpret_cast(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal)); + if (tdCurr.itd.Ordinal) vOldIidCurr[i].firstthunk.push_back(tdCurr); + } while (tdCurr.itd.Ordinal); + } + + // Names + for (unsigned int i=0;i::IMAGE_ORDINAL_FLAG) + { + vOldIidCurr[i].originalfirstthunk[j].hint = 0; + continue; + } + + ifFile.seekg(static_cast(pehHeader.rvaToOffset(vOldIidCurr[i].originalfirstthunk[j].itd.Ordinal)), std::ios_base::beg); + + ifFile.read(reinterpret_cast(&vOldIidCurr[i].originalfirstthunk[j].hint), sizeof(vOldIidCurr[i].originalfirstthunk[j].hint)); + + if (!ifFile) + return ERROR_INVALID_FILE; + + std::string funcname = ""; + do + { + ifFile.read(namebuffer, 1); + if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte + funcname += namebuffer; + } while (true); + + vOldIidCurr[i].originalfirstthunk[j].fname = funcname; + } + } + else + { + for (unsigned int j=0;j::IMAGE_ORDINAL_FLAG) + { + continue; + } + + ifFile.seekg(static_cast(pehHeader.rvaToOffset(vOldIidCurr[i].firstthunk[j].itd.Ordinal)), std::ios_base::beg); + + ifFile.read(reinterpret_cast(&vOldIidCurr[i].firstthunk[j].hint), sizeof(vOldIidCurr[i].firstthunk[j].hint)); + + if (!ifFile) + return ERROR_INVALID_FILE; + + std::string funcname = ""; + do + { + ifFile.read(namebuffer, 1); + if (!ifFile || !namebuffer[0]) break; // reached end of file or 0-byte + funcname += namebuffer; + } while (true); + + vOldIidCurr[i].firstthunk[j].fname = funcname; + } + } + } + std::swap(vOldIidCurr, m_vOldiid); + return NO_ERROR; + } + + /** + * Rebuilds the import directory. + * @param vBuffer Buffer the rebuilt import directory will be written to. + * @param dwRva The RVA of the ImportDirectory in the file. + * \todo uiSizeoffuncnames is not used. + **/ + template + void ImportDirectory::rebuild(std::vector& vBuffer, dword dwRva, bool fixEntries) const + { + unsigned int uiImprva = dwRva; + unsigned int uiSizeofdescriptors = (static_cast(m_vNewiid.size() + m_vOldiid.size()) + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size(); + + unsigned int uiSizeofdllnames = 0, uiSizeoffuncnames = 0; + unsigned int uiSizeofoft = 0; + + for (unsigned int i=0;i(m_vNewiid[i].name.size()) + 1; + uiSizeofoft += (static_cast(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA::size(); + + for(unsigned int j=0;j(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3); + } + } + +// for (unsigned int i=0;i(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA::size(); +// } + + OutputBuffer obBuffer(vBuffer); + + // Rebuild IMAGE_IMPORT_DESCRIPTORS + for (unsigned int i=0;i(m_vNewiid[j-1].originalfirstthunk.size()) + 1) * PELIB_IMAGE_THUNK_DATA::size(); + } + + obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.OriginalFirstThunk); + obBuffer << m_vNewiid[i].impdesc.TimeDateStamp; + obBuffer << m_vNewiid[i].impdesc.ForwarderChain; + dword dwPdll = uiSizeofdescriptors + uiSizeofoft + uiImprva + dllsize; + obBuffer << (fixEntries ? dwPdll : m_vNewiid[i].impdesc.Name); + obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.FirstThunk); + + dllsize += static_cast(m_vNewiid[i].name.size()) + 1; + } + + obBuffer << (dword)0; + obBuffer << (dword)0; + obBuffer << (dword)0; + obBuffer << (dword)0; + obBuffer << (dword)0; + + unsigned int uiPfunc = uiSizeofdescriptors + uiSizeofoft + uiSizeofdllnames + uiImprva; + + // Rebuild original first thunk + for (unsigned int i=0;i::IMAGE_ORDINAL_FLAG + || fixEntries == false) + { + obBuffer << m_vNewiid[i].originalfirstthunk[j].itd.Ordinal; + } + else + { + obBuffer << uiPfunc; + } + uiPfunc += static_cast(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3; + } + obBuffer << (dword)0; + } + + // Write dllnames into import directory + for (unsigned int i=0;i(m_vNewiid[i].name.size())+1); + } + + // Write function names into directory + for (unsigned int i=0;i(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 1); + } + } + } + + /** + * Removes a specific file and all functions of it from the import directory. + * @param strFilename Name of the file which will be removed. + **/ + template + int ImportDirectory::removeFile(const std::string& strFilename) + { + unsigned int oldSize = static_cast(m_vNewiid.size()); + + m_vNewiid.erase(std::remove_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY::operator==), strFilename)), m_vNewiid.end()); + + return oldSize == m_vNewiid.size() ? 1 : 0; + } + + /** + * Removes a specific function from the import directory. + * @param strFilename Name of the file which exports the function. + * @param strFuncname Name of the imported function. + **/ + template + int ImportDirectory::removeFunction(const std::string& strFilename, const std::string& strFuncname) + { + ImpDirFileIterator viPos = m_vNewiid.begin(); + + int notFound = 1; + + while (viPos != m_vNewiid.end()) + { + if (isEqualNc(viPos->name, strFilename)) + { + unsigned int oldSize = static_cast(viPos->originalfirstthunk.size()); + viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA::equalFunctionName), strFuncname)), viPos->originalfirstthunk.end()); + //viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(CompPolicy(), strFuncname))); + if (viPos->originalfirstthunk.size() != oldSize) notFound = 0; + } + ++viPos; + } + + return notFound; + } + + /** + * Removes a specific function from the import directory. + * @param strFilename Name of the file which exports the function. + * @param wHint The hint of the function. + **/ + template + int ImportDirectory::removeFunction(const std::string& strFilename, word wHint) + { + ImpDirFileIterator viPos = m_vNewiid.begin(); + int notFound = 1; + + while (viPos != m_vNewiid.end()) + { + if (isEqualNc(viPos->name, strFilename)) + { + unsigned int oldSize = static_cast(viPos->originalfirstthunk.size()); + viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA::equalHint), wHint)), viPos->originalfirstthunk.end()); + unsigned int newPos = static_cast(viPos->originalfirstthunk.size()); + if (viPos->originalfirstthunk.size() != oldSize) notFound = 0; + } + ++viPos; + } + + return notFound; + } + + /** + * Writes the current import directory to a file. + * @param strFilename Name of the file. + * @param uiOffset File Offset of the new import directory. + * @param uiRva RVA which belongs to that file offset. + **/ + template + int ImportDirectory::write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) + { + std::fstream ofFile(strFilename.c_str(), std::ios_base::in); + + if (!ofFile) + { + ofFile.clear(); + ofFile.open(strFilename.c_str(), std::ios_base::out | std::ios_base::binary); + } + else + { + ofFile.close(); + ofFile.open(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); + } + + if (!ofFile) + { + return ERROR_OPENING_FILE; + } + + ofFile.seekp(uiOffset, std::ios_base::beg); + + std::vector vBuffer; + + rebuild(vBuffer, uiRva); + + ofFile.write(reinterpret_cast(&vBuffer[0]), vBuffer.size()); + ofFile.close(); + + std::copy(m_vNewiid.begin(), m_vNewiid.end(), std::back_inserter(m_vOldiid)); + m_vNewiid.clear(); + + return NO_ERROR; + } + + /** + * Returns the size of the import directory. + * @return Size of the import directory. + **/ + template + unsigned int ImportDirectory::size() const + { + // Only the descriptors of m_vOldiid must be rebuilt, not the data they point to. + return std::accumulate(m_vNewiid.begin(), m_vNewiid.end(), 0, accumulate >) + + (m_vOldiid.size() + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size(); + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return FirstThunk value of an imported file. + **/ + template + dword ImportDirectory::getFirstThunk(const std::string& strFilename, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk; + } + else + { + return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return OriginalFirstThunk value of an imported file. + **/ + template + dword ImportDirectory::getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk; + } + else + { + return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return ForwarderChain value of an imported file. + **/ + template + dword ImportDirectory::getForwarderChain(const std::string& strFilename, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain; + } + else + { + return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return TimeDateStamp value of an imported file. + **/ + template + dword ImportDirectory::getTimeDateStamp(const std::string& strFilename, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp; + } + else + { + return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp; + } + } + + template + dword ImportDirectory::getRvaOfName(const std::string& strFilename, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.Name; + } + else + { + return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.Name; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return FirstThunk value of an imported file. + **/ + template + dword ImportDirectory::getFirstThunk(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[dwFilenr].impdesc.FirstThunk; + } + else + { + return m_vNewiid[dwFilenr].impdesc.FirstThunk; + } + } + + template + void ImportDirectory::setFirstThunk(dword dwFilenr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) + { + m_vOldiid[dwFilenr].impdesc.FirstThunk = value; + } + else + { + m_vNewiid[dwFilenr].impdesc.FirstThunk = value; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return OriginalFirstThunk value of an imported file. + **/ + template + dword ImportDirectory::getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk; + } + else + { + return m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk; + } + } + + template + void ImportDirectory::setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) + { + m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk = value; + } + else + { + m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk = value; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return ForwarderChain value of an imported file. + **/ + template + dword ImportDirectory::getForwarderChain(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[dwFilenr].impdesc.ForwarderChain; + } + else + { + return m_vNewiid[dwFilenr].impdesc.ForwarderChain; + } + } + + template + void ImportDirectory::setForwarderChain(dword dwFilenr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) + { + m_vOldiid[dwFilenr].impdesc.ForwarderChain = value; + } + else + { + m_vNewiid[dwFilenr].impdesc.ForwarderChain = value; + } + } + + /** + * @param strFilename Name of the imported file. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return TimeDateStamp value of an imported file. + **/ + template + dword ImportDirectory::getTimeDateStamp(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[dwFilenr].impdesc.TimeDateStamp; + } + else + { + return m_vNewiid[dwFilenr].impdesc.TimeDateStamp; + } + } + + template + void ImportDirectory::setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) + { + m_vOldiid[dwFilenr].impdesc.TimeDateStamp = value; + } + else + { + m_vNewiid[dwFilenr].impdesc.TimeDateStamp = value; + } + } + + template + dword ImportDirectory::getRvaOfName(dword dwFilenr, currdir cdDir) const + { + if (cdDir == OLDDIR) + { + return m_vOldiid[dwFilenr].impdesc.Name; + } + else + { + return m_vNewiid[dwFilenr].impdesc.Name; + } + } + + template + void ImportDirectory::setRvaOfName(dword dwFilenr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) + { + m_vOldiid[dwFilenr].impdesc.Name = value; + } + else + { + m_vNewiid[dwFilenr].impdesc.Name = value; + } + } + + /** + * @param dwFilenr ID of the imported file. + * @param dwFuncnr ID of the imported function. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return FirstThunk value of an imported function. + **/ + template + dword ImportDirectory::getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const + { + if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal; + else return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal; + } + + template + void ImportDirectory::setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value; + else m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value; + } + + /** + * @param dwFilenr ID of the imported file. + * @param dwFuncnr ID of the imported function. + * @param cdDir Flag to decide if the OLDDIR or new import directory is used. + * @return OriginalFirstThunk value of an imported function. + **/ + template + dword ImportDirectory::getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const + { + if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal; + else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal; + } + + template + void ImportDirectory::setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value) + { + if (cdDir == OLDDIR) m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value; + else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value; + } + + typedef ImportDirectory<32> ImportDirectory32; + typedef ImportDirectory<64> ImportDirectory64; +} + +#endif -- cgit v1.2.3