#include "pe/ImportBaseDirWrapper.h" //--------------------------------- bufsize_t ImportBaseEntryWrapper::NameLenLimit = 0xFF; bool imports_util::isNameValid(Executable *pe, char* myName) { if (!myName) return false; // do not parse, invalid entry bufsize_t upperLimit = pe->getMaxSizeFromPtr((BYTE*) myName); if (upperLimit == 0) return false; bool isInvalid = pe_util::hasNonPrintable(myName, upperLimit); if (isInvalid) return false; if (pe_util::noWhiteCount(myName) == 0) return false; return true; } //--------------------------------- using namespace imports_util; bufsize_t ImportBaseDirWrapper::thunkSize(Executable::exe_bits bits) { if (bits == Executable::BITS_32) return sizeof (uint32_t); else if (bits == Executable::BITS_64) return sizeof (uint64_t); return 0; } void ImportBaseDirWrapper::addMapping(ExeNodeWrapper *funcNode) { ImportBaseFuncWrapper* func = dynamic_cast (funcNode); if (func == NULL) return; offset_t via = func->callVia(); if (via == INVALID_ADDR) return; /* if (m_Exe->isValidVA(via)) { via = m_Exe->VaToRva(via); }*/ ImportBaseEntryWrapper* lib = dynamic_cast(func->getParentNode()); if (!lib) return; this->thunksList.push_back(via); size_t num = lib->getEntryId(); thunkToLibMap[via] = num; num = func->getEntryId(); lib->thunkToFuncMap[via] = num; } void ImportBaseDirWrapper::clearMapping() { thunksList.clear(); thunkToLibMap.clear(); } void ImportBaseDirWrapper::reloadMapping() { clearMapping(); size_t entriesCount = this->entries.size(); for (size_t i = 0; i < entriesCount; i++) { ImportBaseEntryWrapper* lib = dynamic_cast (this->getEntryAt(i)); if (!lib) continue; size_t funcCount = lib->getEntriesCount(); for (size_t fI = 0; fI < funcCount; fI++) { addMapping(lib->getEntryAt(fI)); } } } ImportBaseEntryWrapper* ImportBaseDirWrapper::thunkToLib(offset_t thunk) { std::map::iterator libItr = thunkToLibMap.find(thunk); if (libItr == thunkToLibMap.end()) return NULL; size_t libId = libItr->second; ImportBaseEntryWrapper* lib = dynamic_cast(this->getEntryAt(libId)); return lib; } ImportBaseFuncWrapper* ImportBaseDirWrapper::thunkToFunction(offset_t thunk) { ImportBaseEntryWrapper* lib = thunkToLib(thunk); if (!lib) return NULL; std::map::iterator funcItr = lib->thunkToFuncMap.find(thunk); if (funcItr == lib->thunkToFuncMap.end()) return NULL; ImportBaseFuncWrapper* func = dynamic_cast(lib->getEntryAt(funcItr->second)); return func; } QString ImportBaseDirWrapper::thunkToFuncName(offset_t thunk, bool shortName) { ImportBaseFuncWrapper* func = thunkToFunction(thunk); if (func == NULL) return ""; if (shortName) { return func->getShortName(); } return func->getName(); } QString ImportBaseDirWrapper::thunkToLibName(offset_t thunk) { ImportBaseEntryWrapper* lib = thunkToLib(thunk); if (!lib) return ""; return lib->getName(); } bool ImportBaseDirWrapper::wrap() { clearMapping(); clear(); size_t oldCount = this->importsCount; this->importsCount = 0; this->invalidEntries = 0; if (!getDataDirectory()) { return (oldCount != this->importsCount); //has count changed } const size_t LIMIT = (-1); const size_t INVALID_LIMIT = 100; size_t cntr = 0; size_t invalidSeries = 0; for (cntr = 0; cntr < LIMIT; cntr++) { if (loadNextEntry(cntr) == false) break; ExeNodeWrapper* entry = this->entries.at(cntr); if (!entry) break; if (entry->isValid()) { invalidSeries = 0; } else { invalidSeries++; this->invalidEntries++; if (invalidSeries >= INVALID_LIMIT) break; } } this->importsCount = cntr; return (oldCount != this->importsCount); //has count changed } bool ImportBaseDirWrapper::isValid() { if (this->invalidEntries > 0) return false; const QList thunks = getThunksList(); if (!thunks.size()) return false; return true; } //-------------------------------------------------------------------------------------------------------------- bool ImportBaseEntryWrapper::isValid() { if (this->invalidEntries > 0) return false; char *libName = this->getLibraryName(); if (!imports_util::isNameValid(m_Exe, libName)) return false; return true; } bool ImportBaseEntryWrapper::wrap() { clear(); thunkToFuncMap.clear(); this->invalidEntries = 0; const size_t LIMIT = (-1); const size_t INVALID_LIMIT = 100; if (!isValid()) { return false; } if (this->getPtr() == NULL) { return false; } size_t cntr = 0; size_t invalidSeries = 0; for (cntr = 0; cntr < LIMIT; cntr++) { if (loadNextEntry(cntr) == false) break; ExeNodeWrapper* entry = this->entries.at(cntr); if (!entry) break; if (entry->isValid()) { invalidSeries = 0; } else { invalidSeries++; this->invalidEntries++; if (invalidSeries >= INVALID_LIMIT) break; } } //printf("Entries: %d\n", entries.size()); return true; } //-------------------------------------------------------------------------------------------------------------- QString ImportBaseFuncWrapper::getShortName() { QString functionName; if (isByOrdinal()) { uint64_t val = getOrdinal(); QString out; #if QT_VERSION >= 0x050000 out = QString::asprintf("", static_cast(val)); #else out.sprintf("", static_cast(val)); #endif functionName = out; } else { char *fName = this->getFunctionName(); if (!fName) return ""; functionName = fName; } return functionName; } QString ImportBaseFuncWrapper::getLibName() { ImportBaseEntryWrapper *p = dynamic_cast(this->getParentNode()); if (!p) return ""; char *libName = p->getLibraryName(); if (!libName) return ""; return QString(libName); } QString ImportBaseFuncWrapper::getName() { QString libName = getLibName(); QString functionName = getShortName(); if (!libName.length()) return functionName; return "[" + QString(libName) + "]." + functionName; } bool ImportBaseFuncWrapper::isValid() { ImportBaseEntryWrapper *p = dynamic_cast(this->getParentNode()); if (!p) return false; char *libName = p->getLibraryName(); if (!imports_util::isNameValid(m_Exe, libName)) return false; if (!isByOrdinal()) { char *fName = this->getFunctionName(); if (!imports_util::isNameValid(m_Exe, fName)) return false; } return true; }