PE-sieve
Scans all running processes. Recognizes and dumps a variety of potentially malicious implants (replaced/implanted PEs, shellcodes, hooks, in-memory patches).
Loading...
Searching...
No Matches
iat_finder.h
Go to the documentation of this file.
1#pragma once
2
3#include <windows.h>
4#include <peconv.h>
5
6#include "iat_block.h"
7
8#ifndef MASK_TO_DWORD
9#define MASK_TO_DWORD(val) (val & 0xffffffff)
10#endif
11
12namespace pesieve {
13
16 {
17 public:
19 {
20 }
21
23 virtual bool shouldProcessVA(ULONGLONG va) = 0;
24
26 virtual bool shouldAcceptExport(ULONGLONG va, const peconv::ExportedFunc &exp) = 0;
27 };
28 //---
29
30 template <typename FIELD_T>
31 size_t fill_iat(BYTE* vBuf, size_t vBufSize, IN const peconv::ExportsMapper* exportsMap, IN OUT IATBlock &iat, IN ThunkFoundCallback *callback)
32 {
33 if (!vBuf || !exportsMap || !iat.iatOffset) return 0;
34
35 size_t max_check = vBufSize - sizeof(FIELD_T);
36 if (max_check < sizeof(FIELD_T)) {
37 return 0; //size check failed
38 }
39
40 iat.isTerminated = true;
41 const peconv::ExportedFunc *exp = nullptr;
42
43 IATThunksSeries *series = nullptr;
44 bool is_terminated = true;
45 FIELD_T *imp = (FIELD_T*)(iat.iatOffset + (ULONG_PTR)vBuf);
46 for (; imp < (FIELD_T*)(vBuf + max_check); imp++) {
47 if (*imp == 0) {
48 is_terminated = true;
49 if (series) {
50 iat.appendSeries(series); //add filled series
51 series = nullptr;
52 }
53 continue;
54 }
55
56 const FIELD_T imp_va = (*imp);
57
58 if (callback) {
59 if (!callback->shouldProcessVA(imp_va)) break;
60 }
61
62 //std::cout << "checking: " << std::hex << possible_rva << std::endl;
63 const peconv::ExportedFunc *exp = exportsMap->find_export_by_va(imp_va);
64 if (!exp) break;
65
66 if (callback) {
67 if (!callback->shouldAcceptExport(imp_va, *exp)) break;
68 }
69
70 is_terminated = false;
71 DWORD offset = MASK_TO_DWORD((BYTE*)imp - vBuf);
72 iat.append(offset, imp_va, exp);
73
74 if (!series) series = new IATThunksSeries(offset);
75 if (series) {
76 series->insert(offset, imp_va);
77 }
78 }
79 if (series) {
80 iat.appendSeries(series); //add filled series
81 series = nullptr;
82 }
83 iat.isTerminated = is_terminated;
84 if (!exp && iat.iatOffset && iat.countThunks() > 0) {
85 BYTE *iat_ptr = (BYTE*)(iat.iatOffset + (ULONG_PTR)vBuf);
86 size_t diff = (BYTE*)imp - iat_ptr;
87 iat.iatSize = diff;
88 return iat.iatSize;
89 }
90 return 0; // invalid IAT
91 }
92
93 template <typename FIELD_T>
94 IATBlock* find_iat(BYTE* vBuf, size_t vBufSize, IN const peconv::ExportsMapper* exportsMap, IN size_t search_offset, IN ThunkFoundCallback *callback)
95 {
96 if (!vBuf || !vBufSize || !exportsMap) return nullptr;
97
98 const bool is64bit = (sizeof(FIELD_T) == sizeof(DWORD)) ? false : true;
99
100 size_t max_check = vBufSize - sizeof(FIELD_T);
101 if (search_offset > vBufSize || max_check < sizeof(FIELD_T)) {
102 return nullptr; //size check failed
103 }
104
105 for (BYTE* ptr = vBuf + search_offset; ptr < vBuf + max_check; ptr++) {
106 FIELD_T *to_check = (FIELD_T*)ptr;
107 if (!peconv::validate_ptr(vBuf, vBufSize, to_check, sizeof(FIELD_T))) break;
108 FIELD_T possible_va = (*to_check);
109 if (possible_va == 0) continue;
110
111 if (callback) {
112 if (!callback->shouldProcessVA(possible_va)) continue;
113 }
114
115 //std::cout << "checking: " << std::hex << possible_rva << std::endl;
116 const peconv::ExportedFunc *exp = exportsMap->find_export_by_va(possible_va);
117 if (!exp) continue;
118
119 if (callback) {
120 if (!callback->shouldAcceptExport(possible_va, *exp)) continue;
121 }
122
123 DWORD iat_offset = DWORD(ptr - vBuf);
124 IATBlock *iat_block = new IATBlock(is64bit, iat_offset);
125 //validate IAT:
126 size_t _iat_size = fill_iat<FIELD_T>(vBuf, vBufSize, exportsMap, *iat_block, callback);
127 if (_iat_size > 0) {
128 iat_block->iatSize = _iat_size;
129 return iat_block;
130 }
131 delete iat_block; iat_block = nullptr;
132 }
133 return nullptr;
134 }
135
136}; //namespace pesieve
137
bool insert(DWORD rva, ULONGLONG funcAddr)
Definition iat_block.h:29
A class containing callbacks for functions: find_iat, fill_iat.
Definition iat_finder.h:16
virtual bool shouldProcessVA(ULONGLONG va)=0
the callback that will be called for each candidate for the imported function VA
virtual bool shouldAcceptExport(ULONGLONG va, const peconv::ExportedFunc &exp)=0
the callback that will be called validly resolved import
#define MASK_TO_DWORD(val)
Definition iat_finder.h:9
size_t fill_iat(BYTE *vBuf, size_t vBufSize, IN const peconv::ExportsMapper *exportsMap, IN OUT IATBlock &iat, IN ThunkFoundCallback *callback)
Definition iat_finder.h:31
IATBlock * find_iat(BYTE *vBuf, size_t vBufSize, IN const peconv::ExportsMapper *exportsMap, IN size_t search_offset, IN ThunkFoundCallback *callback)
Definition iat_finder.h:94