PE-sieve
Scans all running processes. Recognizes and dumps a variety of potentially malicious implants (replaced/implanted PEs, shellcodes, hooks, in-memory patches).
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 bool is_terminated = true;
44 FIELD_T *imp = (FIELD_T*)(iat.iatOffset + (ULONG_PTR)vBuf);
45 for (; imp < (FIELD_T*)(vBuf + max_check); imp++) {
46 if (*imp == 0) {
47 is_terminated = true;
48 continue;
49 }
50
51 const FIELD_T imp_va = (*imp);
52
53 if (callback) {
54 if (!callback->shouldProcessVA(imp_va)) break;
55 }
56
57 //std::cout << "checking: " << std::hex << possible_rva << std::endl;
58 const peconv::ExportedFunc *exp = exportsMap->find_export_by_va(imp_va);
59 if (!exp) break;
60
61 if (callback) {
62 if (!callback->shouldAcceptExport(imp_va, *exp)) break;
63 }
64
65 is_terminated = false;
66 DWORD offset = MASK_TO_DWORD((BYTE*)imp - vBuf);
67 iat.append(offset, imp_va, exp);
68 }
69 iat.isTerminated = is_terminated;
70 if (!exp && iat.iatOffset && iat.countThunks() > 0) {
71 BYTE *iat_ptr = (BYTE*)(iat.iatOffset + (ULONG_PTR)vBuf);
72 size_t diff = (BYTE*)imp - iat_ptr;
73 iat.iatSize = diff;
74 return iat.iatSize;
75 }
76 return 0; // invalid IAT
77 }
78
79 template <typename FIELD_T>
80 IATBlock* find_iat(BYTE* vBuf, size_t vBufSize, IN const peconv::ExportsMapper* exportsMap, IN size_t search_offset, IN ThunkFoundCallback *callback)
81 {
82 if (!vBuf || !vBufSize || !exportsMap) return nullptr;
83
84 const bool is64bit = (sizeof(FIELD_T) == sizeof(DWORD)) ? false : true;
85
86 size_t max_check = vBufSize - sizeof(FIELD_T);
87 if (search_offset > vBufSize || max_check < sizeof(FIELD_T)) {
88 return nullptr; //size check failed
89 }
90
91 for (BYTE* ptr = vBuf + search_offset; ptr < vBuf + max_check; ptr++) {
92 FIELD_T *to_check = (FIELD_T*)ptr;
93 if (!peconv::validate_ptr(vBuf, vBufSize, to_check, sizeof(FIELD_T))) break;
94 FIELD_T possible_va = (*to_check);
95 if (possible_va == 0) continue;
96
97 if (callback) {
98 if (!callback->shouldProcessVA(possible_va)) continue;
99 }
100
101 //std::cout << "checking: " << std::hex << possible_rva << std::endl;
102 const peconv::ExportedFunc *exp = exportsMap->find_export_by_va(possible_va);
103 if (!exp) continue;
104
105 if (callback) {
106 if (!callback->shouldAcceptExport(possible_va, *exp)) continue;
107 }
108
109 DWORD iat_offset = DWORD(ptr - vBuf);
110 IATBlock *iat_block = new IATBlock(is64bit, iat_offset);
111 //validate IAT:
112 size_t _iat_size = fill_iat<FIELD_T>(vBuf, vBufSize, exportsMap, *iat_block, callback);
113 if (_iat_size > 0) {
114 iat_block->iatSize = _iat_size;
115 return iat_block;
116 }
117 delete iat_block; iat_block = nullptr;
118 }
119 return nullptr;
120 }
121
122}; //namespace pesieve
123
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:80