Main Page | Class Hierarchy | Class List | File List | Class Members | Related Pages

ImportDirectory.h

00001 /* 00002 * ImportDirectory.h - Part of the PeLib library. 00003 * 00004 * Copyright (c) 2004 Sebastian Porst (webmaster@the-interweb.com) 00005 * All rights reserved. 00006 * 00007 * This software is licensed under the zlib/libpng License. 00008 * For more details see http://www.opensource.org/licenses/zlib-license.php 00009 * or the license information file (license.htm) in the root directory 00010 * of PeLib. 00011 */ 00012 00013 #ifndef IMPORTDIRECTORY_H 00014 #define IMPORTDIRECTORY_H 00015 00016 #include "PeLibAux.h" 00017 #include "PeHeader.h" 00018 00019 namespace PeLib 00020 { 00022 enum currdir {OLDDIR = 1, NEWDIR}; 00023 00024 class PeLibException; 00025 00027 00037 template<int bits> 00038 class ImportDirectory 00039 { 00040 typedef typename std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >::iterator ImpDirFileIterator; 00041 typedef typename std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >::const_iterator ConstImpDirFileIterator; 00042 00043 private: 00045 std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > m_vOldiid; 00047 std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > m_vNewiid; 00048 00049 // I can't convince Borland C++ to compile the function outside of the class declaration. 00050 // That's why the function definition is here. 00052 template<typename T> bool hasFunction(std::string strFilename, T value, bool(PELIB_THUNK_DATA<bits>::* comp)(T) const) const 00053 { 00054 ConstImpDirFileIterator FileIter = m_vOldiid.begin(); 00055 ConstImpDirFileIterator EndIter = m_vOldiid.end(); 00056 00057 for (int i=0;i<=1;i++) // Loop once for m_vOldiid and once for m_vNewiid 00058 { 00059 do 00060 { 00061 FileIter = std::find_if(FileIter, EndIter, std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)); 00062 00063 if (FileIter != EndIter) 00064 { 00065 typename std::vector<PELIB_THUNK_DATA<bits> >::const_iterator Iter = std::find_if(FileIter->originalfirstthunk.begin(), FileIter->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(comp), value)); 00066 if (Iter != FileIter->originalfirstthunk.end()) 00067 { 00068 return true; 00069 } 00070 ++FileIter; 00071 } 00072 } 00073 while (FileIter != EndIter); 00074 00075 FileIter = m_vNewiid.begin(); 00076 EndIter = m_vNewiid.end(); 00077 } 00078 00079 return false; 00080 } 00081 00082 00083 public: 00084 00086 int addFunction(const std::string& strFilename, word wHint); 00088 int addFunction(const std::string& strFilename, const std::string& strFuncname); 00089 00091 unsigned int getFileIndex(const std::string& strFilename, currdir cdDir) const; 00093 unsigned int getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const; 00094 00096 std::string getFileName(dword dwFilenr, currdir cdDir) const; 00097 00098 void setFileName(dword filenr, currdir dir, const std::string& name); 00099 00101 word getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; 00102 void setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value); 00104 std::string getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; 00105 void setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName); 00107 dword getNumberOfFiles(currdir cdDir) const; 00109 dword getNumberOfFunctions(dword dwFilenr, currdir cdDir) const; 00111 int read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT<bits>& pehHeader); 00113 void rebuild(std::vector<byte>& vBuffer, dword dwRva, bool fixEntries = true) const; 00115 int removeFile(const std::string& strFilename); 00117 int removeFunction(const std::string& strFilename, const std::string& strFuncname); 00119 int removeFunction(const std::string& strFilename, word wHint); 00121 unsigned int size() const; 00123 int write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva); 00124 00126 dword getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; 00127 void setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); 00129 dword getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const; 00130 void setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value); 00131 00132 // dword getFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); 00133 // dword getOriginalFirstThunk(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); 00134 00136 dword getFirstThunk(const std::string& strFilename, currdir cdDir) const; 00138 dword getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const; 00140 dword getForwarderChain(const std::string& strFilename, currdir cdDir) const; 00141 dword getRvaOfName(const std::string& strFilename, currdir cdDir) const; 00143 dword getTimeDateStamp(const std::string& strFilename, currdir cdDir) const; 00144 00146 dword getFirstThunk(dword dwFilenr, currdir cdDir) const; 00147 void setFirstThunk(dword dwFilenr, currdir cdDir, dword value); 00149 dword getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const; 00150 void setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value); 00152 dword getForwarderChain(dword dwFilenr, currdir cdDir) const; 00153 void setForwarderChain(dword dwFilenr, currdir cdDir, dword value); 00154 dword getRvaOfName(dword dwFilenr, currdir cdDir) const; 00155 void setRvaOfName(dword dwFilenr, currdir cdDir, dword value); 00157 dword getTimeDateStamp(dword dwFilenr, currdir cdDir) const; 00158 void setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value); 00159 00160 // word getFunctionHint(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const throw (PeLibException); 00161 }; 00162 00170 template<int bits> 00171 int ImportDirectory<bits>::addFunction(const std::string& strFilename, word wHint) 00172 { 00173 if (hasFunction(strFilename, wHint, &PELIB_THUNK_DATA<bits>::equalHint)) 00174 { 00175 return 1; 00176 // throw Exceptions::EntryAlreadyExists(ImportDirectoryId, __LINE__); 00177 } 00178 00179 // Find the imported file. 00180 ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)); 00181 00182 PELIB_IMAGE_IMPORT_DIRECTORY<bits> iid; 00183 PELIB_THUNK_DATA<bits> td; 00184 td.hint = wHint; 00185 td.itd.Ordinal = wHint | IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG; 00186 iid.name = strFilename; 00187 if (FileIter == m_vNewiid.end()) 00188 { 00189 iid.originalfirstthunk.push_back(td); 00190 iid.firstthunk.push_back(td); 00191 m_vNewiid.push_back(iid); 00192 } 00193 else 00194 { 00195 FileIter->originalfirstthunk.push_back(td); 00196 FileIter->firstthunk.push_back(td); 00197 } 00198 00199 return 0; 00200 } 00201 00207 template<int bits> 00208 int ImportDirectory<bits>::addFunction(const std::string& strFilename, const std::string& strFuncname) 00209 { 00210 if (hasFunction(strFilename, strFuncname, &PELIB_THUNK_DATA<bits>::equalFunctionName)) 00211 { 00212 return 1; 00213 // throw Exceptions::EntryAlreadyExists(ImportDirectoryId, __LINE__); 00214 } 00215 00216 // Find the imported file. 00217 ImpDirFileIterator FileIter = std::find_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)); 00218 00219 PELIB_IMAGE_IMPORT_DIRECTORY<bits> iid; 00220 PELIB_THUNK_DATA<bits> td; 00221 td.fname = strFuncname; 00222 iid.name = strFilename; 00223 if (FileIter == m_vNewiid.end()) 00224 { 00225 iid.originalfirstthunk.push_back(td); 00226 iid.firstthunk.push_back(td); 00227 m_vNewiid.push_back(iid); 00228 } 00229 else 00230 { 00231 FileIter->originalfirstthunk.push_back(td); 00232 FileIter->firstthunk.push_back(td); 00233 } 00234 00235 return 0; 00236 } 00237 00245 template<int bits> 00246 unsigned int ImportDirectory<bits>::getFileIndex(const std::string& strFilename, currdir cdDir) const 00247 { 00248 const std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >* currDir; 00249 00250 if (cdDir == OLDDIR) 00251 { 00252 currDir = &m_vOldiid; 00253 } 00254 else 00255 { 00256 currDir = &m_vNewiid; 00257 } 00258 00259 ConstImpDirFileIterator FileIter = std::find_if(currDir->begin(), currDir->end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)); 00260 00261 if (FileIter != currDir->end()) 00262 { 00263 return static_cast<unsigned int>(std::distance(currDir->begin(), FileIter)); 00264 } 00265 else 00266 { 00267 return -1; 00268 // throw Exceptions::InvalidName(ImportDirectoryId, __LINE__); 00269 } 00270 00271 return 0; 00272 } 00273 00281 template<int bits> 00282 unsigned int ImportDirectory<bits>::getFunctionIndex(const std::string& strFilename, const std::string& strFuncname, currdir cdDir) const 00283 { 00284 unsigned int uiFile = getFileIndex(strFilename, cdDir); 00285 00286 for (unsigned int i=0;i<getNumberOfFunctions(uiFile, cdDir);i++) 00287 { 00288 if (getFunctionName(uiFile, i, cdDir) == strFuncname) return i; 00289 } 00290 00291 return -1; 00292 } 00293 00300 template<int bits> 00301 std::string ImportDirectory<bits>::getFileName(dword dwFilenr, currdir cdDir) const 00302 { 00303 if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].name; 00304 else return m_vNewiid[dwFilenr].name; 00305 } 00306 00307 template<int bits> 00308 void ImportDirectory<bits>::setFileName(dword filenr, currdir dir, const std::string& name) 00309 { 00310 if (dir == OLDDIR) m_vOldiid[filenr].name = name; 00311 else m_vNewiid[filenr].name = name; 00312 } 00313 00322 template<int bits> 00323 std::string ImportDirectory<bits>::getFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir) const 00324 { 00325 if (cdDir == OLDDIR) 00326 { 00327 // Unsafe 00328 if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) 00329 { 00330 return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname; 00331 } 00332 else 00333 { 00334 return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname; 00335 } 00336 } 00337 else 00338 { 00339 if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk) 00340 { 00341 return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname; 00342 } 00343 else 00344 { 00345 return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname; 00346 } 00347 } 00348 } 00349 00350 template<int bits> 00351 void ImportDirectory<bits>::setFunctionName(dword dwFilenr, dword dwFuncnr, currdir cdDir, const std::string& functionName) 00352 { 00353 if (cdDir == OLDDIR) 00354 { 00355 // Unsafe 00356 if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) 00357 { 00358 m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName; 00359 } 00360 else 00361 { 00362 m_vOldiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName; 00363 } 00364 } 00365 else 00366 { 00367 if (m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk) 00368 { 00369 m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].fname = functionName; 00370 } 00371 else 00372 { 00373 m_vNewiid[dwFilenr].firstthunk[dwFuncnr].fname = functionName; 00374 } 00375 } 00376 } 00377 00385 template<int bits> 00386 word ImportDirectory<bits>::getFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir) const 00387 { 00388 if (cdDir == OLDDIR) 00389 { 00390 if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) 00391 { 00392 return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint; 00393 } 00394 else 00395 { 00396 return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint; 00397 } 00398 } 00399 else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint; 00400 } 00401 00402 template<int bits> 00403 void ImportDirectory<bits>::setFunctionHint(dword dwFilenr, dword dwFuncnr, currdir cdDir, word value) 00404 { 00405 if (cdDir == OLDDIR) 00406 { 00407 if (m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk) 00408 { 00409 m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value; 00410 } 00411 else 00412 { 00413 m_vOldiid[dwFilenr].firstthunk[dwFuncnr].hint = value; 00414 } 00415 } 00416 else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].hint = value; 00417 } 00418 00424 template<int bits> 00425 dword ImportDirectory<bits>::getNumberOfFiles(currdir cdDir) const 00426 { 00427 if (cdDir == OLDDIR) return static_cast<dword>(m_vOldiid.size()); 00428 else return static_cast<dword>(m_vNewiid.size()); 00429 } 00430 00437 template<int bits> 00438 dword ImportDirectory<bits>::getNumberOfFunctions(dword dwFilenr, currdir cdDir) const 00439 { 00440 if (cdDir == OLDDIR) return static_cast<unsigned int>(m_vOldiid[dwFilenr].firstthunk.size()); 00441 else return static_cast<unsigned int>(m_vNewiid[dwFilenr].firstthunk.size()); 00442 } 00443 00452 template<int bits> 00453 int ImportDirectory<bits>::read(const std::string& strFilename, unsigned int uiOffset, unsigned int uiSize, const PeHeaderT<bits>& pehHeader) 00454 { 00455 if (uiSize < PELIB_IMAGE_IMPORT_DESCRIPTOR::size()) 00456 { 00457 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00458 return 1; 00459 } 00460 00461 std::ifstream ifFile(strFilename.c_str(), std::ios_base::binary); 00462 unsigned long ulFileSize = fileSize(ifFile); 00463 00464 if (!ifFile) 00465 { 00466 // throw Exceptions::CannotOpenFile(ImportDirectoryId, __LINE__); 00467 return 1; 00468 } 00469 00470 if (ulFileSize < uiOffset + uiSize) 00471 { 00472 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00473 return 1; 00474 } 00475 00476 ifFile.seekg(uiOffset, std::ios_base::beg); 00477 00478 std::vector<unsigned char> vImportdirectory(uiSize); 00479 ifFile.read(reinterpret_cast<char*>(&vImportdirectory[0]), uiSize); 00480 00481 PELIB_IMAGE_IMPORT_DIRECTORY<bits> iidCurr; 00482 unsigned int uiDesccounter = 0; 00483 00484 InputBuffer inpBuffer(vImportdirectory); 00485 00486 std::vector<PELIB_IMAGE_IMPORT_DIRECTORY<bits> > vOldIidCurr; 00487 00488 do // Read and store all descriptors 00489 { 00490 inpBuffer >> iidCurr.impdesc.OriginalFirstThunk; 00491 inpBuffer >> iidCurr.impdesc.TimeDateStamp; 00492 inpBuffer >> iidCurr.impdesc.ForwarderChain; 00493 inpBuffer >> iidCurr.impdesc.Name; 00494 inpBuffer >> iidCurr.impdesc.FirstThunk; 00495 00496 if (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 || 00497 iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0) 00498 { 00499 vOldIidCurr.push_back(iidCurr); 00500 } 00501 00502 uiDesccounter++; 00503 00504 if (uiSize < (uiDesccounter + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size()) break; 00505 } while (iidCurr.impdesc.OriginalFirstThunk != 0 || iidCurr.impdesc.TimeDateStamp != 0 || iidCurr.impdesc.ForwarderChain != 0 || 00506 iidCurr.impdesc.Name != 0 || iidCurr.impdesc.FirstThunk != 0); 00507 00508 const unsigned int MAXNAMESIZE = 100; 00509 char namebuffer[MAXNAMESIZE + 1] = {0}; 00510 00511 // Name 00512 for (unsigned int i=0;i<vOldIidCurr.size();i++) 00513 { 00514 try 00515 { 00516 ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].impdesc.Name)), std::ios_base::beg); 00517 } 00518 catch (...) 00519 { 00520 // Invalid offset 00521 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00522 return 1; 00523 } 00524 00525 std::string dllname = ""; 00526 00527 do 00528 { 00529 ifFile.read(namebuffer, MAXNAMESIZE); 00530 dllname += namebuffer; 00531 } while (strlen(namebuffer) == MAXNAMESIZE && !ifFile.fail()); 00532 00533 vOldIidCurr[i].name = dllname; 00534 00535 } 00536 00537 // OriginalFirstThunk 00538 for (unsigned int i=0;i<vOldIidCurr.size();i++) 00539 { 00540 PELIB_THUNK_DATA<bits> tdCurr; 00541 dword uiVaoft = vOldIidCurr[i].impdesc.OriginalFirstThunk; 00542 00543 if (!uiVaoft) 00544 { 00545 continue; 00546 } 00547 00548 try 00549 { 00550 ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg); 00551 } 00552 catch (...) 00553 { 00554 // Invalid offset 00555 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00556 return 1; 00557 } 00558 00559 do 00560 { 00561 if (ulFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal)) 00562 { 00563 return 1; 00564 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00565 } 00566 uiVaoft += sizeof(tdCurr.itd.Ordinal); 00567 00568 ifFile.read(reinterpret_cast<char*>(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal)); 00569 if (tdCurr.itd.Ordinal) vOldIidCurr[i].originalfirstthunk.push_back(tdCurr); 00570 } while (tdCurr.itd.Ordinal); 00571 } 00572 00573 // FirstThunk 00574 for (unsigned int i=0;i<vOldIidCurr.size();i++) 00575 { 00576 dword uiVaoft = vOldIidCurr[i].impdesc.FirstThunk; 00577 PELIB_THUNK_DATA<bits> tdCurr; 00578 00579 try 00580 { 00581 ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(uiVaoft)), std::ios_base::beg); 00582 } 00583 catch (...) 00584 { 00585 // Invalid offset 00586 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00587 return 1; 00588 } 00589 00590 do 00591 { 00592 if (ulFileSize < pehHeader.rvaToOffset(uiVaoft) + sizeof(tdCurr.itd.Ordinal)) 00593 { 00594 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00595 return 1; 00596 } 00597 uiVaoft += sizeof(tdCurr.itd.Ordinal); 00598 00599 ifFile.read(reinterpret_cast<char*>(&tdCurr.itd.Ordinal), sizeof(tdCurr.itd.Ordinal)); 00600 if (tdCurr.itd.Ordinal) vOldIidCurr[i].firstthunk.push_back(tdCurr); 00601 } while (tdCurr.itd.Ordinal); 00602 } 00603 00604 // Names 00605 for (unsigned int i=0;i<vOldIidCurr.size();i++) 00606 { 00607 if (vOldIidCurr[i].impdesc.OriginalFirstThunk) 00608 { 00609 for (unsigned int j=0;j<vOldIidCurr[i].originalfirstthunk.size();j++) 00610 { 00611 if (vOldIidCurr[i].originalfirstthunk[j].itd.Ordinal & IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG) 00612 { 00613 vOldIidCurr[i].originalfirstthunk[j].hint = 0; 00614 continue; 00615 } 00616 00617 try 00618 { 00619 ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].originalfirstthunk[j].itd.Ordinal)), std::ios_base::beg); 00620 } 00621 catch (...) 00622 { 00623 // Invalid offset 00624 //throw PeLibException(PeLibException::INVALID_IMPORT_DIRECTORY, __FILE__, __LINE__); 00625 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00626 return 1; 00627 } 00628 00629 try 00630 { 00631 ifFile.read(reinterpret_cast<char*>(&vOldIidCurr[i].originalfirstthunk[j].hint), sizeof(vOldIidCurr[i].originalfirstthunk[j].hint)); 00632 } 00633 catch(...) 00634 { 00635 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00636 return 1; 00637 } 00638 00639 std::string funcname = ""; 00640 do 00641 { 00642 ifFile.read(namebuffer, MAXNAMESIZE); 00643 funcname += namebuffer; 00644 } while (strlen(namebuffer) == MAXNAMESIZE && !ifFile.fail()); 00645 00646 vOldIidCurr[i].originalfirstthunk[j].fname = funcname; 00647 } 00648 } 00649 else 00650 { 00651 for (unsigned int j=0;j<vOldIidCurr[i].firstthunk.size();j++) 00652 { 00653 if (vOldIidCurr[i].firstthunk[j].itd.Ordinal & IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG) 00654 { 00655 continue; 00656 } 00657 00658 try 00659 { 00660 ifFile.seekg(static_cast<unsigned int>(pehHeader.rvaToOffset(vOldIidCurr[i].firstthunk[j].itd.Ordinal)), std::ios_base::beg); 00661 } 00662 catch (...) 00663 { 00664 // Invalid offset 00665 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00666 return 1; 00667 } 00668 00669 try 00670 { 00671 ifFile.read(reinterpret_cast<char*>(&vOldIidCurr[i].firstthunk[j].hint), sizeof(vOldIidCurr[i].firstthunk[j].hint)); 00672 } 00673 catch(...) 00674 { 00675 // throw Exceptions::InvalidFormat(ImportDirectoryId, __LINE__); 00676 return 1; 00677 } 00678 00679 std::string funcname = ""; 00680 do 00681 { 00682 ifFile.read(namebuffer, MAXNAMESIZE); 00683 funcname += namebuffer; 00684 } while (strlen(namebuffer) == MAXNAMESIZE && !ifFile.fail()); 00685 00686 vOldIidCurr[i].firstthunk[j].fname = funcname; 00687 } 00688 } 00689 } 00690 std::swap(vOldIidCurr, m_vOldiid); 00691 return 0; 00692 } 00693 00700 template<int bits> 00701 void ImportDirectory<bits>::rebuild(std::vector<byte>& vBuffer, dword dwRva, bool fixEntries) const 00702 { 00703 unsigned int uiImprva = dwRva; 00704 unsigned int uiSizeofdescriptors = (static_cast<unsigned int>(m_vNewiid.size() + m_vOldiid.size()) + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size(); 00705 00706 unsigned int uiSizeofdllnames = 0, uiSizeoffuncnames = 0; 00707 unsigned int uiSizeofoft = 0; 00708 00709 for (unsigned int i=0;i<m_vNewiid.size();i++) 00710 { 00711 uiSizeofdllnames += static_cast<unsigned int>(m_vNewiid[i].name.size()) + 1; 00712 uiSizeofoft += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA<bits>::size(); 00713 00714 for(unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++) 00715 { 00716 // +3 for hint (word) and 00-byte 00717 uiSizeoffuncnames += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3); 00718 } 00719 } 00720 00721 // for (unsigned int i=0;i<m_vNewiid.size();i++) 00722 // { 00723 // uiSizeofoft += (static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk.size())+1) * PELIB_IMAGE_THUNK_DATA<bits>::size(); 00724 // } 00725 00726 OutputBuffer obBuffer(vBuffer); 00727 00728 // Rebuild IMAGE_IMPORT_DESCRIPTORS 00729 for (unsigned int i=0;i<m_vOldiid.size();i++) 00730 { 00731 obBuffer << m_vOldiid[i].impdesc.OriginalFirstThunk; 00732 obBuffer << m_vOldiid[i].impdesc.TimeDateStamp; 00733 obBuffer << m_vOldiid[i].impdesc.ForwarderChain; 00734 obBuffer << m_vOldiid[i].impdesc.Name; 00735 obBuffer << m_vOldiid[i].impdesc.FirstThunk; 00736 } 00737 00738 unsigned int dllsize = 0; 00739 00740 for (unsigned int i=0;i<m_vNewiid.size();i++) 00741 { 00742 dword dwPoft = uiSizeofdescriptors + uiImprva; 00743 00744 for (unsigned int j=1;j<=i;j++) 00745 { 00746 dwPoft += (static_cast<unsigned int>(m_vNewiid[j-1].originalfirstthunk.size()) + 1) * PELIB_IMAGE_THUNK_DATA<bits>::size(); 00747 } 00748 00749 obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.OriginalFirstThunk); 00750 obBuffer << m_vNewiid[i].impdesc.TimeDateStamp; 00751 obBuffer << m_vNewiid[i].impdesc.ForwarderChain; 00752 dword dwPdll = uiSizeofdescriptors + uiSizeofoft + uiImprva + dllsize; 00753 obBuffer << (fixEntries ? dwPdll : m_vNewiid[i].impdesc.Name); 00754 obBuffer << (fixEntries ? dwPoft : m_vNewiid[i].impdesc.FirstThunk); 00755 00756 dllsize += static_cast<unsigned int>(m_vNewiid[i].name.size()) + 1; 00757 } 00758 00759 obBuffer << (dword)0; 00760 obBuffer << (dword)0; 00761 obBuffer << (dword)0; 00762 obBuffer << (dword)0; 00763 obBuffer << (dword)0; 00764 00765 unsigned int uiPfunc = uiSizeofdescriptors + uiSizeofoft + uiSizeofdllnames + uiImprva; 00766 00767 // Rebuild original first thunk 00768 for (unsigned int i=0;i<m_vNewiid.size();i++) 00769 { 00770 for (unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++) 00771 { 00772 if (m_vNewiid[i].originalfirstthunk[j].itd.Ordinal & IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG 00773 || fixEntries == false) 00774 { 00775 obBuffer << m_vNewiid[i].originalfirstthunk[j].itd.Ordinal; 00776 } 00777 else 00778 { 00779 obBuffer << uiPfunc; 00780 } 00781 uiPfunc += static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 3; 00782 } 00783 obBuffer << (dword)0; 00784 } 00785 00786 // Write dllnames into import directory 00787 for (unsigned int i=0;i<m_vNewiid.size();i++) 00788 { 00789 obBuffer.add(m_vNewiid[i].name.c_str(), static_cast<unsigned int>(m_vNewiid[i].name.size())+1); 00790 } 00791 00792 // Write function names into directory 00793 for (unsigned int i=0;i<m_vNewiid.size();i++) 00794 { 00795 for (unsigned int j=0;j<m_vNewiid[i].originalfirstthunk.size();j++) 00796 { 00797 obBuffer << m_vNewiid[i].originalfirstthunk[j].hint; 00798 obBuffer.add(m_vNewiid[i].originalfirstthunk[j].fname.c_str(), static_cast<unsigned int>(m_vNewiid[i].originalfirstthunk[j].fname.size()) + 1); 00799 } 00800 } 00801 } 00802 00807 template<int bits> 00808 int ImportDirectory<bits>::removeFile(const std::string& strFilename) 00809 { 00810 unsigned int oldSize = static_cast<unsigned int>(m_vNewiid.size()); 00811 00812 m_vNewiid.erase(std::remove_if(m_vNewiid.begin(), m_vNewiid.end(), std::bind2nd(std::mem_fun_ref(&PELIB_IMAGE_IMPORT_DIRECTORY<bits>::operator==), strFilename)), m_vNewiid.end()); 00813 00814 return oldSize == m_vNewiid.size() ? 1 : 0; 00815 } 00816 00822 template<int bits> 00823 int ImportDirectory<bits>::removeFunction(const std::string& strFilename, const std::string& strFuncname) 00824 { 00825 ImpDirFileIterator viPos = m_vNewiid.begin(); 00826 00827 int notFound = 1; 00828 00829 while (viPos != m_vNewiid.end()) 00830 { 00831 if (isEqualNc(viPos->name, strFilename)) 00832 { 00833 unsigned int oldSize = static_cast<unsigned int>(viPos->originalfirstthunk.size()); 00834 viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA<bits>::equalFunctionName), strFuncname)), viPos->originalfirstthunk.end()); 00835 //viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(CompPolicy<PELIB_THUNK_DATA, std::string>(), strFuncname))); 00836 if (viPos->originalfirstthunk.size() != oldSize) notFound = 0; 00837 } 00838 ++viPos; 00839 } 00840 00841 return notFound; 00842 } 00843 00849 template<int bits> 00850 int ImportDirectory<bits>::removeFunction(const std::string& strFilename, word wHint) 00851 { 00852 ImpDirFileIterator viPos = m_vNewiid.begin(); 00853 int notFound = 1; 00854 00855 while (viPos != m_vNewiid.end()) 00856 { 00857 if (isEqualNc(viPos->name, strFilename)) 00858 { 00859 unsigned int oldSize = static_cast<unsigned int>(viPos->originalfirstthunk.size()); 00860 viPos->originalfirstthunk.erase(std::remove_if(viPos->originalfirstthunk.begin(), viPos->originalfirstthunk.end(), std::bind2nd(std::mem_fun_ref(&PELIB_THUNK_DATA<bits>::equalHint), wHint)), viPos->originalfirstthunk.end()); 00861 unsigned int newPos = static_cast<unsigned int>(viPos->originalfirstthunk.size()); 00862 if (viPos->originalfirstthunk.size() != oldSize) notFound = 0; 00863 } 00864 ++viPos; 00865 } 00866 00867 return notFound; 00868 } 00869 00876 template<int bits> 00877 int ImportDirectory<bits>::write(const std::string& strFilename, unsigned int uiOffset, unsigned int uiRva) 00878 { 00879 std::fstream ofFile(strFilename.c_str(), std::ios_base::in | std::ios_base::out | std::ios_base::binary); 00880 00881 if (!ofFile) 00882 { 00883 ofFile.clear(); 00884 return 1; 00885 } 00886 00887 ofFile.seekp(uiOffset, std::ios_base::beg); 00888 00889 std::vector<byte> vBuffer; 00890 00891 rebuild(vBuffer, uiRva); 00892 00893 ofFile.write(reinterpret_cast<const char*>(&vBuffer[0]), vBuffer.size()); 00894 ofFile.close(); 00895 00896 std::copy(m_vNewiid.begin(), m_vNewiid.end(), std::back_inserter(m_vOldiid)); 00897 m_vNewiid.clear(); 00898 00899 return 0; 00900 } 00901 00906 template<int bits> 00907 unsigned int ImportDirectory<bits>::size() const 00908 { 00909 // Only the descriptors of m_vOldiid must be rebuilt, not the data they point to. 00910 return std::accumulate(m_vNewiid.begin(), m_vNewiid.end(), 0, accumulate<PELIB_IMAGE_IMPORT_DIRECTORY<bits> >) 00911 + (m_vOldiid.size() + 1) * PELIB_IMAGE_IMPORT_DESCRIPTOR::size(); 00912 } 00913 00919 template<int bits> 00920 dword ImportDirectory<bits>::getFirstThunk(const std::string& strFilename, currdir cdDir) const 00921 { 00922 if (cdDir == OLDDIR) 00923 { 00924 return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk; 00925 } 00926 else 00927 { 00928 return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.FirstThunk; 00929 } 00930 } 00931 00937 template<int bits> 00938 dword ImportDirectory<bits>::getOriginalFirstThunk(const std::string& strFilename, currdir cdDir) const 00939 { 00940 if (cdDir == OLDDIR) 00941 { 00942 return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk; 00943 } 00944 else 00945 { 00946 return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.OriginalFirstThunk; 00947 } 00948 } 00949 00955 template<int bits> 00956 dword ImportDirectory<bits>::getForwarderChain(const std::string& strFilename, currdir cdDir) const 00957 { 00958 if (cdDir == OLDDIR) 00959 { 00960 return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain; 00961 } 00962 else 00963 { 00964 return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.ForwarderChain; 00965 } 00966 } 00967 00973 template<int bits> 00974 dword ImportDirectory<bits>::getTimeDateStamp(const std::string& strFilename, currdir cdDir) const 00975 { 00976 if (cdDir == OLDDIR) 00977 { 00978 return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp; 00979 } 00980 else 00981 { 00982 return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.TimeDateStamp; 00983 } 00984 } 00985 00986 template<int bits> 00987 dword ImportDirectory<bits>::getRvaOfName(const std::string& strFilename, currdir cdDir) const 00988 { 00989 if (cdDir == OLDDIR) 00990 { 00991 return m_vOldiid[getFileIndex(strFilename, cdDir)].impdesc.Name; 00992 } 00993 else 00994 { 00995 return m_vNewiid[getFileIndex(strFilename, cdDir)].impdesc.Name; 00996 } 00997 } 00998 01004 template<int bits> 01005 dword ImportDirectory<bits>::getFirstThunk(dword dwFilenr, currdir cdDir) const 01006 { 01007 if (cdDir == OLDDIR) 01008 { 01009 return m_vOldiid[dwFilenr].impdesc.FirstThunk; 01010 } 01011 else 01012 { 01013 return m_vNewiid[dwFilenr].impdesc.FirstThunk; 01014 } 01015 } 01016 01017 template<int bits> 01018 void ImportDirectory<bits>::setFirstThunk(dword dwFilenr, currdir cdDir, dword value) 01019 { 01020 if (cdDir == OLDDIR) 01021 { 01022 m_vOldiid[dwFilenr].impdesc.FirstThunk = value; 01023 } 01024 else 01025 { 01026 m_vNewiid[dwFilenr].impdesc.FirstThunk = value; 01027 } 01028 } 01029 01035 template<int bits> 01036 dword ImportDirectory<bits>::getOriginalFirstThunk(dword dwFilenr, currdir cdDir) const 01037 { 01038 if (cdDir == OLDDIR) 01039 { 01040 return m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk; 01041 } 01042 else 01043 { 01044 return m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk; 01045 } 01046 } 01047 01048 template<int bits> 01049 void ImportDirectory<bits>::setOriginalFirstThunk(dword dwFilenr, currdir cdDir, dword value) 01050 { 01051 if (cdDir == OLDDIR) 01052 { 01053 m_vOldiid[dwFilenr].impdesc.OriginalFirstThunk = value; 01054 } 01055 else 01056 { 01057 m_vNewiid[dwFilenr].impdesc.OriginalFirstThunk = value; 01058 } 01059 } 01060 01066 template<int bits> 01067 dword ImportDirectory<bits>::getForwarderChain(dword dwFilenr, currdir cdDir) const 01068 { 01069 if (cdDir == OLDDIR) 01070 { 01071 return m_vOldiid[dwFilenr].impdesc.ForwarderChain; 01072 } 01073 else 01074 { 01075 return m_vNewiid[dwFilenr].impdesc.ForwarderChain; 01076 } 01077 } 01078 01079 template<int bits> 01080 void ImportDirectory<bits>::setForwarderChain(dword dwFilenr, currdir cdDir, dword value) 01081 { 01082 if (cdDir == OLDDIR) 01083 { 01084 m_vOldiid[dwFilenr].impdesc.ForwarderChain = value; 01085 } 01086 else 01087 { 01088 m_vNewiid[dwFilenr].impdesc.ForwarderChain = value; 01089 } 01090 } 01091 01097 template<int bits> 01098 dword ImportDirectory<bits>::getTimeDateStamp(dword dwFilenr, currdir cdDir) const 01099 { 01100 if (cdDir == OLDDIR) 01101 { 01102 return m_vOldiid[dwFilenr].impdesc.TimeDateStamp; 01103 } 01104 else 01105 { 01106 return m_vNewiid[dwFilenr].impdesc.TimeDateStamp; 01107 } 01108 } 01109 01110 template<int bits> 01111 void ImportDirectory<bits>::setTimeDateStamp(dword dwFilenr, currdir cdDir, dword value) 01112 { 01113 if (cdDir == OLDDIR) 01114 { 01115 m_vOldiid[dwFilenr].impdesc.TimeDateStamp = value; 01116 } 01117 else 01118 { 01119 m_vNewiid[dwFilenr].impdesc.TimeDateStamp = value; 01120 } 01121 } 01122 01123 template<int bits> 01124 dword ImportDirectory<bits>::getRvaOfName(dword dwFilenr, currdir cdDir) const 01125 { 01126 if (cdDir == OLDDIR) 01127 { 01128 return m_vOldiid[dwFilenr].impdesc.Name; 01129 } 01130 else 01131 { 01132 return m_vNewiid[dwFilenr].impdesc.Name; 01133 } 01134 } 01135 01136 template<int bits> 01137 void ImportDirectory<bits>::setRvaOfName(dword dwFilenr, currdir cdDir, dword value) 01138 { 01139 if (cdDir == OLDDIR) 01140 { 01141 m_vOldiid[dwFilenr].impdesc.Name = value; 01142 } 01143 else 01144 { 01145 m_vNewiid[dwFilenr].impdesc.Name = value; 01146 } 01147 } 01148 01155 template<int bits> 01156 dword ImportDirectory<bits>::getFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const 01157 { 01158 if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal; 01159 else return m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal; 01160 } 01161 01162 template<int bits> 01163 void ImportDirectory<bits>::setFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value) 01164 { 01165 if (cdDir == OLDDIR) m_vOldiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value; 01166 else m_vNewiid[dwFilenr].firstthunk[dwFuncnr].itd.Ordinal = value; 01167 } 01168 01175 template<int bits> 01176 dword ImportDirectory<bits>::getOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir) const 01177 { 01178 if (cdDir == OLDDIR) return m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal; 01179 else return m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal; 01180 } 01181 01182 template<int bits> 01183 void ImportDirectory<bits>::setOriginalFirstThunk(dword dwFilenr, dword dwFuncnr, currdir cdDir, dword value) 01184 { 01185 if (cdDir == OLDDIR) m_vOldiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value; 01186 else m_vNewiid[dwFilenr].originalfirstthunk[dwFuncnr].itd.Ordinal = value; 01187 } 01188 01189 typedef ImportDirectory<32> ImportDirectory32; 01190 typedef ImportDirectory<64> ImportDirectory64; 01191 } 01192 01193 #endif

Generated on Mon Jan 17 20:50:08 2005 for PeLib by doxygen 1.3.7