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
code_scanner.h
Go to the documentation of this file.
1#pragma once
2#include <windows.h>
3#include <vector>
4#include <fstream>
5
6#include "module_scanner.h"
7#include "pe_section.h"
8#include "patch_list.h"
9
10namespace pesieve {
11
14 {
15 public:
22
23 CodeScanReport(HMODULE _module, size_t _moduleSize)
24 : ModuleScanReport(_module, _moduleSize)
25 {
26 }
27
28 size_t countSectionsWithStatus(const t_section_status neededStatus)
29 {
30 size_t counter = 0;
31 std::map<DWORD, t_section_status>::iterator itr;
32 for (itr = sectionToResult.begin(); itr != sectionToResult.end(); ++itr) {
33 const t_section_status status = itr->second;
34 if (status == neededStatus) {
35 counter++;
36 }
37 }
38 return counter;
39 }
40
41 const virtual void fieldsToJSON(std::stringstream &outs, size_t level, const pesieve::t_json_level &jdetails)
42 {
43 const size_t inaccessibleCount = countInaccessibleSections();
44 const size_t scannedCount = sectionToResult.size() - inaccessibleCount;
45 ModuleScanReport::_toJSON(outs, level);
46 if (sectionToResult.size() > 0) {
47 outs << ",\n";
48 OUT_PADDED(outs, level, "\"scanned_sections\" : ");
49 outs << std::dec << scannedCount;
50 }
51 if (inaccessibleCount > 0) {
52 outs << ",\n";
53 OUT_PADDED(outs, level, "\"inaccessible_sections\" : ");
54 outs << std::dec << inaccessibleCount;
55 }
56 const size_t unpacked = countUnpackedSections();
57 if (unpacked > 0) {
58 outs << ",\n";
59 OUT_PADDED(outs, level, "\"unpacked_sections\" : ");
60 outs << std::dec << unpacked;
61 }
62 if (patchesList.size() > 0) {
63 outs << ",\n";
64 OUT_PADDED(outs, level, "\"patches\" : ");
65 outs << std::dec << patchesList.size();
66
67 if (jdetails >= JSON_DETAILS) {
68 outs << ",\n";
69 const bool is_short = (jdetails < JSON_DETAILS2) ? true : false;
70 patchesList.toJSON(outs, level, is_short);
71 }
72 }
73 }
74
75 const virtual bool toJSON(std::stringstream &outs, size_t level, const pesieve::t_json_level &jdetails)
76 {
77 OUT_PADDED(outs, level, "\"code_scan\" : {\n");
78 fieldsToJSON(outs, level + 1, jdetails);
79 outs << "\n";
80 OUT_PADDED(outs, level, "}");
81 return true;
82 }
83
84 virtual ULONGLONG getRelocBase()
85 {
86 return this->relocBase;
87 }
88
93
98
99 size_t generateTags(const std::string &reportPath);
100
101 std::map<DWORD, t_section_status> sectionToResult;
103 };
104
105
107 class CodeScanner : public ModuleScanner {
108 public:
109
112 isScanData(false), isScanInaccessible(false)
113 {
114 }
115
116 virtual CodeScanReport* scanRemote();
117
118 void setScanData(bool enable) { this->isScanData = enable; }
119 void setScanInaccessible(bool enable) { this->isScanInaccessible = enable; }
120
121 private:
122
123 size_t collectExecutableSections(RemoteModuleData &remoteModData, std::map<size_t, PeSection*> &sections, CodeScanReport &my_report);
124
125 void freeExecutableSections(std::map<size_t, PeSection*> &sections);
126
127 bool postProcessScan(IN OUT CodeScanReport &report);
128
129 t_scan_status scanUsingBase(IN ULONGLONG load_base, IN std::map<size_t, PeSection*> &remote_code, OUT std::map<DWORD, CodeScanReport::t_section_status> &sectionToResult, OUT PatchList &patchesList);
130
131 CodeScanReport::t_section_status scanSection(PeSection &originalSec, PeSection &remoteSec, OUT PatchList &patchesList);
132
133 bool clearIAT(PeSection &originalSec, PeSection &remoteSec);
134
135 bool clearExports(PeSection &originalSec, PeSection &remoteSec);
136
137 bool clearLoadConfig(PeSection &originalSec, PeSection &remoteSec);
138
139 size_t collectPatches(DWORD section_rva, PBYTE orig_code, PBYTE patched_code, size_t code_size, OUT PatchList &patchesList);
140
141 bool isScanData;
142 bool isScanInaccessible;
143 };
144
145}; //namespace pesieve
146
A report from the code scan, generated by CodeScanner.
size_t generateTags(const std::string &reportPath)
enum pesieve::CodeScanReport::section_status t_section_status
size_t countSectionsWithStatus(const t_section_status neededStatus)
virtual ULONGLONG getRelocBase()
size_t countInaccessibleSections()
virtual const void fieldsToJSON(std::stringstream &outs, size_t level, const pesieve::t_json_level &jdetails)
virtual const bool toJSON(std::stringstream &outs, size_t level, const pesieve::t_json_level &jdetails)
CodeScanReport(HMODULE _module, size_t _moduleSize)
std::map< DWORD, t_section_status > sectionToResult
A scanner for detection of patches in the code.
void setScanInaccessible(bool enable)
void setScanData(bool enable)
virtual CodeScanReport * scanRemote()
CodeScanner(HANDLE hProc, ModuleData &moduleData, RemoteModuleData &remoteModData)
Loads a module from the disk, corresponding to the module in the scanned process' memory.
Definition module_data.h:15
A base class of all the reports detailing on the output of the performed module's scan.
virtual const bool _toJSON(std::stringstream &outs, size_t level=JSON_LEVEL, const pesieve::t_json_level &jdetails=JSON_BASIC)
A base class for all the scanners operating on module data.
RemoteModuleData & remoteModData
const bool toJSON(std::stringstream &outs, size_t level, bool short_info)
Buffers the defined PE section belonging to the module loaded in the scanned process into the local m...
Definition pe_section.h:12
Buffers the data from the module loaded in the scanned process into the local memory.
#define OUT_PADDED(stream, field_size, str)
Definition format_util.h:12
enum pesieve::module_scan_status t_scan_status
@ JSON_DETAILS
include the basic list patches in the main JSON report
@ JSON_DETAILS2
include the extended list patches in the main JSON report
Final summary about the scanned process.