Skip to content

Commit

Permalink
[FEATURE] Added a new parameter, regulating what type of results shou…
Browse files Browse the repository at this point in the history
…ld be reported
  • Loading branch information
hasherezade committed Oct 30, 2024
1 parent 2b05630 commit b1b169c
Show file tree
Hide file tree
Showing 14 changed files with 192 additions and 59 deletions.
12 changes: 12 additions & 0 deletions include/pe_sieve_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ namespace pesieve {
OUT_FILTERS_COUNT
} t_output_filter;

typedef enum {
SHOW_NONE = 0,
SHOW_ERRORS = 1,
SHOW_NOT_SUSPICIOUS = 2,
SHOW_SUSPICIOUS = 4,
SHOW_SUSPICIOUS_AND_ERRORS = SHOW_ERRORS | SHOW_SUSPICIOUS,
SHOW_SUCCESSFUL_ONLY = SHOW_NOT_SUSPICIOUS | SHOW_SUSPICIOUS,
SHOW_ALL = SHOW_ERRORS | SHOW_NOT_SUSPICIOUS | SHOW_SUSPICIOUS,
SHOW_FILTERS_COUNT
} t_results_filter;

typedef enum {
SHELLC_NONE = 0, ///< do not detect shellcode
SHELLC_PATTERNS, ///< detect shellcodes by patterns
Expand Down Expand Up @@ -128,6 +139,7 @@ namespace pesieve {
bool make_reflection; ///< operate on a process reflection rather than on the live process (this allows i.e. to force-read inaccessible pages)
bool use_cache; ///< enable cache for the scanned modules
t_json_level json_lvl; ///< level of the details of the JSON report
t_results_filter results_filter; ///< what type of results should be included in the report
char output_dir[MAX_PATH + 1]; ///< the root directory where the output should be saved (default: current directory)
PARAM_STRING modules_ignored; ///< a list of modules that will not be scanned, separated by PARAM_LIST_SEPARATOR
PARAM_STRING pattern_file; ///< a file with additional patterns for code recognition
Expand Down
12 changes: 7 additions & 5 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void print_report(const pesieve::ReportEx& report, const t_params args)

std::string report_str;
if (args.json_output) {
report_str = report_to_json(report, pesieve::REPORT_ALL, ProcessScanReport::REPORT_SUSPICIOUS_AND_ERRORS, args.json_lvl);
report_str = report_to_json(report, pesieve::REPORT_ALL, args.results_filter, args.json_lvl);
} else {
report_str = scan_report_to_string(*report.scan_report);
}
Expand All @@ -48,6 +48,7 @@ void free_params(t_params &args)
int main(int argc, char *argv[])
{
t_params args = { 0 };
args.results_filter = SHOW_SUSPICIOUS;

PEsieveParams uParams(PESIEVE_VERSION_STR);
if (argc < 2) {
Expand Down Expand Up @@ -81,10 +82,11 @@ int main(int argc, char *argv[])
t_pesieve_res res = PESIEVE_ERROR;
if (report != nullptr) {
print_report(*report, args);

pesieve::t_report summary = report->scan_report->generateSummary();
if (summary.scanned > 0) {
res = (summary.suspicious > 0) ? PESIEVE_DETECTED : PESIEVE_NOT_DETECTED;
if (report->scan_report) {
pesieve::t_report summary = report->scan_report->generateSummary();
if (summary.scanned > 0) {
res = (summary.suspicious > 0) ? PESIEVE_DETECTED : PESIEVE_NOT_DETECTED;
}
}
delete report;
report = nullptr;
Expand Down
15 changes: 15 additions & 0 deletions params.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ using namespace pesieve;
#define PARAM_DUMP_MODE "dmode"
//output options:
#define PARAM_OUT_FILTER "ofilter"
#define PARAM_RESULTS_FILTER "report"
#define PARAM_QUIET "quiet"
#define PARAM_JSON "json"
#define PARAM_JSON_LVL "jlvl"
Expand Down Expand Up @@ -82,6 +83,18 @@ class PEsieveParams : public Params
}
}

enumParam = new EnumParam(PARAM_RESULTS_FILTER, "result_type", false);
if (enumParam) {
this->addParam(enumParam);
this->setInfo(PARAM_RESULTS_FILTER, "Define what type of results are reported.");
for (size_t i = SHOW_SUSPICIOUS; i < SHOW_FILTERS_COUNT; i++) {
t_results_filter mode = (t_results_filter)(i);
std::string info = translate_results_filter(mode);
if (info.empty()) continue;
enumParam->addEnumValue(mode, results_filter_to_id(i), info);
}
}

this->addParam(new StringListParam(PARAM_MODULES_IGNORE, false, PARAM_LIST_SEPARATOR));
{
std::stringstream ss1;
Expand Down Expand Up @@ -202,6 +215,7 @@ class PEsieveParams : public Params
this->addParamToGroup(PARAM_JSON, str_group);
this->addParamToGroup(PARAM_JSON_LVL, str_group);
this->addParamToGroup(PARAM_OUT_FILTER, str_group);
this->addParamToGroup(PARAM_RESULTS_FILTER, str_group);

str_group = "1. scanner settings";
this->addGroup(new ParamGroup(str_group));
Expand Down Expand Up @@ -253,6 +267,7 @@ class PEsieveParams : public Params
copyVal<IntParam>(PARAM_PID, ps.pid);
copyVal<EnumParam>(PARAM_IMP_REC, ps.imprec_mode);
copyVal<EnumParam>(PARAM_OUT_FILTER, ps.out_filter);
copyVal<EnumParam>(PARAM_RESULTS_FILTER, ps.results_filter);

fillStringParam(PARAM_MODULES_IGNORE, ps.modules_ignored);

Expand Down
44 changes: 35 additions & 9 deletions params_info/pe_sieve_params_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ std::string pesieve::translate_dump_mode(const DWORD dump_mode)
case pesieve::PE_DUMP_REALIGN:
return "realigned raw (converted raw format to be the same as virtual)";
}
return "undefined";
return "";
}

std::string pesieve::dump_mode_to_id(const DWORD dump_mode)
Expand Down Expand Up @@ -44,7 +44,33 @@ std::string pesieve::translate_out_filter(const pesieve::t_output_filter o_filte
case pesieve::OUT_NO_DIR:
return "don't dump any files";
}
return "undefined";
return "";
}

std::string pesieve::translate_results_filter(const pesieve::t_results_filter r_filter)
{
switch (r_filter) {
case pesieve::SHOW_SUSPICIOUS:
return "only suspicious (default)";
case pesieve::SHOW_SUSPICIOUS_AND_ERRORS:
return "suspicious and errors";
case pesieve::SHOW_ALL:
return "all scanned";
}
return "";
}

std::string pesieve::results_filter_to_id(const DWORD r_filter)
{
switch (r_filter) {
case pesieve::SHOW_SUSPICIOUS:
return "S";
case pesieve::SHOW_SUSPICIOUS_AND_ERRORS:
return "SE";
case pesieve::SHOW_ALL:
return "L";
}
return "";
}

std::string pesieve::translate_imprec_mode(const pesieve::t_imprec_mode imprec_mode)
Expand All @@ -63,7 +89,7 @@ std::string pesieve::translate_imprec_mode(const pesieve::t_imprec_mode imprec_m
case pesieve::PE_IMPREC_REBUILD2:
return "build the ImportTable from scratch, basing on the found IATs:\n\t use all found blocks (aggressive mode)";
}
return "undefined";
return "";
}


Expand Down Expand Up @@ -101,7 +127,7 @@ std::string pesieve::translate_dotnet_policy(const pesieve::t_dotnet_policy &mod
case pesieve::PE_DNET_SKIP_ALL:
return "skip all the above (mapping, shellcodes, hooks)";
}
return "undefined";
return "";
}

std::string pesieve::translate_data_mode(const pesieve::t_data_scan_mode &mode)
Expand All @@ -120,7 +146,7 @@ std::string pesieve::translate_data_mode(const pesieve::t_data_scan_mode &mode)
case pesieve::PE_DATA_SCAN_INACCESSIBLE_ONLY:
return "scan inaccessible pages, but exclude other non-executable;\n\t works in reflection mode (/refl) only";
}
return "undefined";
return "";
}

std::string pesieve::translate_json_level(const pesieve::t_json_level &mode)
Expand All @@ -133,7 +159,7 @@ std::string pesieve::translate_json_level(const pesieve::t_json_level &mode)
case pesieve::JSON_DETAILS2:
return "details #2 (list patches: extended)";
}
return "undefined";
return "";
}

std::string pesieve::shellc_mode_mode_to_id(const pesieve::t_shellc_mode& mode)
Expand Down Expand Up @@ -165,7 +191,7 @@ std::string pesieve::translate_shellc_mode(const pesieve::t_shellc_mode& mode)
case pesieve::SHELLC_PATTERNS_AND_STATS:
return "detect shellcodes by patterns and stats (both match)";
}
return "undefined";
return "";
}

std::string pesieve::translate_obfusc_mode(const pesieve::t_obfusc_mode& mode)
Expand All @@ -180,7 +206,7 @@ std::string pesieve::translate_obfusc_mode(const pesieve::t_obfusc_mode& mode)
case pesieve::OBFUSC_ANY:
return "detect any: possible strong or weak encryption";
}
return "undefined";
return "";
}

std::string pesieve::obfusc_mode_mode_to_id(const pesieve::t_obfusc_mode& mode)
Expand Down Expand Up @@ -209,5 +235,5 @@ std::string pesieve::translate_iat_scan_mode(const pesieve::t_iat_scan_mode mode
case pesieve::PE_IATS_UNFILTERED:
return "unfiltered: scan for IAT Hooks, report all";
}
return "undefined";
return "";
}
2 changes: 2 additions & 0 deletions params_info/pe_sieve_params_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
namespace pesieve {
std::string translate_dump_mode(const DWORD dump_mode);
std::string translate_out_filter(const pesieve::t_output_filter o_filter);
std::string translate_results_filter(const pesieve::t_results_filter r_filter);
std::string results_filter_to_id(const DWORD r_filter);
std::string translate_data_mode(const pesieve::t_data_scan_mode &mode);
std::string translate_imprec_mode(const pesieve::t_imprec_mode imprec_mode);
std::string translate_dotnet_policy(const pesieve::t_dotnet_policy &mode);
Expand Down
12 changes: 7 additions & 5 deletions pe_sieve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pesieve::PatternMatcher g_Matcher;
pesieve::SyscallTable g_SyscallTable;

namespace pesieve {

void check_access_denied(DWORD processID)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processID);
Expand Down Expand Up @@ -126,7 +127,7 @@ namespace pesieve {
ProcessDumpReport* dumpReport = nullptr;
ResultsDumper dumper(expand_path(args.output_dir), args.quiet);

if (dumper.dumpJsonReport(process_report, ProcessScanReport::REPORT_SUSPICIOUS_AND_ERRORS, args.json_lvl) && !args.quiet) {
if (dumper.dumpJsonReport(process_report, args.results_filter, args.json_lvl) && !args.quiet) {
std::cout << "[+] Report dumped to: " << dumper.getOutputDir() << std::endl;
}

Expand Down Expand Up @@ -248,19 +249,20 @@ pesieve::ReportEx* pesieve::scan_and_dump(IN const pesieve::t_params args)
const bool is_reflection = (cloned_proc) ? true : false;
ProcessScanner scanner(target_proc, is_reflection, args);
report->scan_report = scanner.scanRemote();

if (report->scan_report) {
// dump elements from the process:
report->dump_report = make_dump(target_proc, is_reflection, args, *report->scan_report);
}
}
catch (std::exception &e) {
delete report;
report = nullptr;

report->error_report = new ErrorReport(args.pid, e.what());
if (!args.quiet) {
util::print_in_color(ERROR_COLOR, std::string("[ERROR] ") + e.what() + "\n", true);
}
ResultsDumper dumper(expand_path(args.output_dir), args.quiet);
if (dumper.dumpJsonReport(*report->error_report, args.results_filter) && !args.quiet) {
std::cout << "[+] Report dumped to: " << dumper.getOutputDir() << std::endl;
}
}
if (cloned_proc) {
release_process_reflection(&cloned_proc);
Expand Down
20 changes: 11 additions & 9 deletions pe_sieve_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ using namespace pesieve;

size_t print_report(const pesieve::ReportEx& report, const pesieve::t_params args, const t_report_type rtype, char* json_buf, size_t json_buf_size)
{
if (!report.scan_report || rtype == REPORT_NONE) return 0;
if (rtype == REPORT_NONE) return 0;

size_t level = 1;
std::string report_str = report_to_json(report, rtype, ProcessScanReport::REPORT_SUSPICIOUS_AND_ERRORS, args.json_lvl, level);
std::string report_str = report_to_json(report, rtype, args.report_filter, args.json_lvl, level);
const size_t report_len = report_str.length();

if (json_buf && json_buf_size) {
Expand All @@ -35,13 +35,15 @@ PEsieve_report PESIEVE_API_FUNC PESieve_scan_ex(IN const PEsieve_params &args, I
return empty;
}
const pesieve::ReportEx* report = pesieve::scan_and_dump(args);
if (report == nullptr) {
pesieve::t_report nullrep = { 0 };
nullrep.pid = args.pid;
nullrep.errors = pesieve::ERROR_SCAN_FAILURE;
return nullrep;
pesieve::t_report summary = { 0 };
summary.pid = args.pid;
summary.errors = pesieve::ERROR_SCAN_FAILURE;
if (!report) {
return summary;
}
if (report->scan_report) {
summary = report->scan_report->generateSummary();
}
pesieve::t_report summary = report->scan_report->generateSummary();
//check the pointers:
if (json_buf) {
if (!json_buf_size || IsBadWritePtr(json_buf, json_buf_size)) {
Expand Down
16 changes: 15 additions & 1 deletion pe_sieve_report.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,36 @@

namespace pesieve {

class ErrorReport
{
public:
ErrorReport(DWORD _pid, const std::string &_message)
: pid(_pid), message(_message)
{
}

const DWORD pid;
const std::string message;
};

//! The final report about the actions performed on the process: scanning and dumping
class ReportEx {
public:
ReportEx() :
scan_report(nullptr), dump_report(nullptr)
scan_report(nullptr), dump_report(nullptr), error_report(nullptr)
{
}

~ReportEx()
{
delete scan_report;
delete dump_report;
delete error_report;
}

ProcessScanReport* scan_report; ///< the report aggregating the results of the performed scans
ProcessDumpReport* dump_report; ///< the report aggregating the results of the performed dumps
ErrorReport* error_report; ///< the report detailing on possible errors that prevented the scan
};

};
44 changes: 40 additions & 4 deletions postprocessors/report_formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,37 @@ std::string pesieve::scan_report_to_string(const ProcessScanReport &process_repo
return stream.str();
}

std::string pesieve::err_report_to_json(const pesieve::ErrorReport& err_report,
t_results_filter filter,
size_t start_level
)
{
if ((filter & SHOW_ERRORS) == 0) {
return "";
}
//summary:
std::stringstream stream;

size_t level = start_level + 1;
OUT_PADDED(stream, start_level, "{\n"); // beginning of the report

OUT_PADDED(stream, level, "\"pid\" : ");
stream << std::dec << err_report.pid << ",\n";
OUT_PADDED(stream, level, "\"err_message\" : ");
stream << "\"" << err_report.message << "\"\n";
OUT_PADDED(stream, start_level, "}\n"); // end of the report

std::string report_all = stream.str();
if (report_all.length() == 0) {
return "";
}
return report_all;
}


std::string pesieve::scan_report_to_json(
const ProcessScanReport &process_report,
ProcessScanReport::t_report_filter filter,
t_results_filter filter,
const pesieve::t_json_level &jdetails,
size_t start_level
)
Expand Down Expand Up @@ -75,15 +103,23 @@ std::string pesieve::dump_report_to_json(
return report_all;
}

std::string pesieve::report_to_json(const pesieve::ReportEx& report, const t_report_type rtype, ProcessScanReport::t_report_filter filter, const pesieve::t_json_level& jdetails, size_t start_level)
std::string pesieve::report_to_json(const pesieve::ReportEx& report, const t_report_type rtype, t_results_filter filter, const pesieve::t_json_level& jdetails, size_t start_level)
{
if (!report.scan_report || rtype == REPORT_NONE) return 0;
if (rtype == REPORT_NONE) return 0;

size_t level = 1;
std::stringstream stream;

if (report.error_report && (filter & SHOW_ERRORS)) {
stream << "{\n";
OUT_PADDED(stream, level, "\"error_report\" :\n");
stream << err_report_to_json(*report.error_report, filter, level);
stream << "}\n";
return stream.str();
}
const bool has_dumps = (report.dump_report && report.dump_report->countDumped() > 0) ? true : false;
stream << "{\n";
if (rtype == REPORT_ALL || rtype == REPORT_SCANNED) {
if (report.scan_report && (rtype == REPORT_ALL || rtype == REPORT_SCANNED)) {
OUT_PADDED(stream, level, "\"scan_report\" :\n");
stream << scan_report_to_json(*report.scan_report, filter, jdetails, level);
if (rtype == REPORT_ALL && has_dumps) {
Expand Down
Loading

0 comments on commit b1b169c

Please sign in to comment.