10#define MIN_THUNKS_COUNT 2
40bool pesieve::ImpReconstructor::hasDynamicIAT()
const
42 size_t maxSize = getMaxDynamicIATSize(
true);
46size_t pesieve::ImpReconstructor::getMainIATSize()
const
48 std::map<DWORD, IATBlock*>::const_iterator
iats_itr;
63size_t pesieve::ImpReconstructor::getMaxDynamicIATSize(
IN bool isIatTerminated)
const
65 std::map<DWORD, IATBlock*>::const_iterator
iats_itr;
88 switch (imprec_mode) {
104 const size_t termIATSize = getMaxDynamicIATSize(
true);
114 while (!findIATsCoverage(exportsMap, (t_imprec_filter)
filter)) {
117 return IMP_RECOVERY_ERROR;
122 if (
filter == IMP_REC_COUNT) {
123 return IMP_RECOVERY_ERROR;
131 if (appendImportTable(*
impBuf)) {
138 return IMP_RECOVERY_ERROR;
143 return IMP_RECREATED_FILTER0;
145 return IMP_RECREATED_FILTER1;
147 return IMP_RECREATED_FILTER2;
149 return IMP_RECREATED_FILTER0;
154 if (!exportsMap || imprec_mode == pesieve::PE_IMPREC_NONE) {
155 return IMP_RECOVERY_SKIPPED;
158 if (!collectIATs(exportsMap)) {
159 return IMP_NOT_FOUND;
162 if (!peBuffer.isValidPe()) {
164 return IMP_RECOVERY_NOT_APPLICABLE;
166 if (!peconv::is_pe_raw_eq_virtual(peBuffer.vBuf, peBuffer.vBufSize)
167 && peconv::is_pe_raw(peBuffer.vBuf, peBuffer.vBufSize))
170 return IMP_RECOVERY_NOT_APPLICABLE;
181 if (findImportTable(exportsMap)) {
186 const bool isDotnet = peconv::is_dot_net(peBuffer.vBuf, peBuffer.vBufSize);
196 return _recreateImportTableFiltered(exportsMap, imprec_mode);
198 return IMP_RECOVERY_ERROR;
203 if (!foundIATs.size()) {
208 if (
report.is_open() ==
false) {
212 std::map<DWORD, IATBlock*>::iterator
itr;
213 for (
itr = foundIATs.begin();
itr != foundIATs.end(); ++
itr) {
220bool pesieve::ImpReconstructor::isDefaultImportValid(
IN const peconv::ExportsMapper* exportsMap)
222 BYTE *vBuf = this->peBuffer.vBuf;
223 const size_t vBufSize = this->peBuffer.vBufSize;
224 if (!vBuf || !vBufSize)
return false;
239 if (
iat_dir->VirtualAddress != 0 &&
imp_dir->VirtualAddress == 0) {
252 const size_t start_offset = peconv::get_hdrs_size(vBuf);
253 const bool is64bit = peconv::is64bit(vBuf);
276IATBlock* pesieve::ImpReconstructor::findIATBlock(
IN const peconv::ExportsMapper* exportsMap,
size_t start_offset)
278 if (!exportsMap)
return nullptr;
298 virtual bool shouldAcceptExport(
ULONGLONG va,
const peconv::ExportedFunc &
exp)
322void pesieve::ImpReconstructor::collectMainIatData()
324 BYTE* vBuf = this->peBuffer.vBuf;
325 const size_t vBufSize = this->peBuffer.vBufSize;
328 if (!peconv::has_valid_import_table(vBuf, vBufSize)) {
332 peconv::collect_thunks(vBuf, vBufSize, mainIatThunks);
335IATBlock* pesieve::ImpReconstructor::findIAT(
IN const peconv::ExportsMapper* exportsMap,
size_t start_offset)
337 BYTE *vBuf = this->peBuffer.vBuf;
338 const size_t vBufSize = this->peBuffer.vBufSize;
339 if (!vBuf)
return nullptr;
353 || mainIatThunks.find(
iat_block->iatOffset) != mainIatThunks.end() )
360size_t pesieve::ImpReconstructor::collectIATs(
IN const peconv::ExportsMapper* exportsMap)
362 BYTE *vBuf = this->peBuffer.vBuf;
363 const size_t vBufSize = this->peBuffer.vBufSize;
367 const size_t pe_hdr_size = peconv::get_hdrs_size(vBuf);
391bool pesieve::ImpReconstructor::findImportTable(
IN const peconv::ExportsMapper* exportsMap)
393 BYTE *vBuf = this->peBuffer.vBuf;
394 const size_t vBufSize = this->peBuffer.vBufSize;
395 if (!vBuf)
return false;
408 const size_t start_offset = peconv::get_hdrs_size(vBuf);
410 std::map<DWORD, IATBlock*>::iterator
itr;
411 for (
itr = foundIATs.begin();
itr != foundIATs.end(); ++
itr) {
416 std::cout <<
"[*] Searching import table for IAT: " << std::hex <<
iat_offset <<
", size: " <<
currIAT->iatSize << std::endl;
418 bool is64bit = peconv::is64bit(vBuf);
447 std::cout <<
"[*] Validated Imports size!\n";
456bool pesieve::ImpReconstructor::findIATsCoverage(
IN const peconv::ExportsMapper* exportsMap, t_imprec_filter
filter)
460 std::map<DWORD, IATBlock*>::iterator
itr;
461 for (
itr = foundIATs.begin();
itr != foundIATs.end(); ++
itr) {
466 if (!
iat->isInMain && !
iat->isTerminated) {
476 if (
iat->makeCoverage(exportsMap)) {
480 std::cout <<
"[-] Failed covering block: " << std::hex <<
itr->first <<
" series: " <<
iat->thunkSeries.size() <<
"\n";
491 BYTE *vBuf = this->peBuffer.vBuf;
492 const size_t vBufSize = this->peBuffer.vBufSize;
493 if (!vBuf || !vBufSize)
return nullptr;
496 std::map<DWORD, IATBlock*>::iterator
itr;
497 for (
itr = foundIATs.begin();
itr != foundIATs.end(); ++
itr) {
499 if (
iat->isValid()) {
517 for (
itr = foundIATs.begin();
itr != foundIATs.end(); ++
itr) {
519 if (!
iat->isValid()) {
522 IATThunksSeriesSet::iterator
sItr;
538 for (
itr = foundIATs.begin();
itr != foundIATs.end(); ++
itr) {
540 if (!
iat->isValid()) {
543 IATThunksSeriesSet::iterator
sItr;
561 for (
itr = foundIATs.begin();
itr != foundIATs.end(); ++
itr) {
563 if (!
iat->isValid()) {
567 IATThunksSeriesSet::iterator
sItr;
587 if (!peBuffer.resizeBuffer(
new_size)) {
593 return importTable.setTableInPe(peBuffer.vBuf, peBuffer.vBufSize);
size_t countThunks() const
t_imprec_res rebuildImportTable(const IN peconv::ExportsMapper *exportsMap, IN const pesieve::t_imprec_mode &imprec_mode)
enum pesieve::ImpReconstructor::imprec_res t_imprec_res
bool printFoundIATs(std::string reportPath)
BYTE * getDllSpaceAt(const DWORD rva, size_t required_size)
BYTE * getNamesSpaceAt(const DWORD rva, size_t required_size)
bool allocDesciptors(size_t descriptors_count)
A class containing callbacks for functions: find_iat, fill_iat.
#define MASK_TO_DWORD(val)
DWORD(__stdcall *_PssCaptureSnapshot)(HANDLE ProcessHandle
BYTE * get_buffer_space_at(IN BYTE *buffer, IN const size_t buffer_size, IN const DWORD buffer_rva, IN const DWORD required_rva, IN const size_t required_size)
size_t fill_iat(BYTE *vBuf, size_t vBufSize, IN const peconv::ExportsMapper *exportsMap, IN OUT IATBlock &iat, IN ThunkFoundCallback *callback)
IMAGE_IMPORT_DESCRIPTOR * find_import_table(IN bool is64bit, IN BYTE *vBuf, IN size_t vBufSize, IN const peconv::ExportsMapper *exportsMap, IN DWORD iat_offset, OUT size_t &table_size, IN OPTIONAL size_t search_offset)
@ PE_IMPREC_AUTO
try to autodetect the most suitable mode
@ PE_IMPREC_REBUILD0
build the import table from the scratch, basing on the found IAT(s): use only terminated blocks (rest...
@ PE_IMPREC_UNERASE
recover erased parts of the partialy damaged import table
@ PE_IMPREC_REBUILD2
build the import table from the scratch, basing on the found IAT(s): use all found blocks (aggressive...
@ PE_IMPREC_REBUILD1
build the import table from the scratch, basing on the found IAT(s): use terminated blocks,...
Final summary about the scanned process.