Skip to content

Commit

Permalink
[REFACT] Moved the global pattern matcher into a class
Browse files Browse the repository at this point in the history
  • Loading branch information
hasherezade committed Jun 14, 2024
1 parent ccf82ce commit 6805ada
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 34 deletions.
6 changes: 4 additions & 2 deletions pe_sieve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
using namespace pesieve;
using namespace pesieve::util;

pesieve::PatternMatcher g_Matcher;

namespace pesieve {
void check_access_denied(DWORD processID)
{
Expand Down Expand Up @@ -205,14 +207,14 @@ pesieve::ReportEx* pesieve::scan_and_dump(IN const pesieve::t_params args)
}

if (args.pattern_file.length) {
size_t loaded = matcher::load_pattern_file(args.pattern_file.buffer);
size_t loaded = g_Matcher.loadPatternFile(args.pattern_file.buffer);
if (!args.quiet) {
if (loaded) std::cout << "[+] Pattern file loaded: " << args.pattern_file.buffer << ", Signs: " << loaded << std::endl;
else std::cerr << "[-] Failed to load pattern file: " << args.pattern_file.buffer << std::endl;
}
}
if (is_by_patterns(args.shellcode)) {
matcher::init_shellcode_patterns();
g_Matcher.initShellcodePatterns();
}

try {
Expand Down
9 changes: 5 additions & 4 deletions scanners/workingset_scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using namespace pesieve;
using namespace pesieve::util;

extern pesieve::PatternMatcher g_Matcher;

namespace pesieve {

Expand Down Expand Up @@ -82,10 +83,10 @@ bool pesieve::WorkingSetScanner::checkAreaContent(IN MemPageData& memPage, OUT W

size_t custom_matched_count = 0;

if (matcher::is_matcher_ready()) {
if (g_Matcher.isReady()) {
std::vector<sig_finder::Match> allMatched;
my_report->all_matched_count = matcher::find_all_patterns(memPage.getLoadedData(noPadding), memPage.getLoadedSize(noPadding), allMatched);
custom_matched_count = matcher::filter_custom(allMatched, my_report->custom_matched);
my_report->all_matched_count = g_Matcher.findAllPatterns(memPage.getLoadedData(noPadding), memPage.getLoadedSize(noPadding), allMatched);
custom_matched_count = g_Matcher.filterCustom(allMatched, my_report->custom_matched);
if (my_report->all_matched_count) {
my_report->match_area_start = memPage.getStartOffset(noPadding);
codeP = true;
Expand Down Expand Up @@ -212,7 +213,7 @@ WorkingSetScanReport* pesieve::WorkingSetScanner::scanExecutableArea(MemPageData
return my_report1;
}
}
if ((!matcher::is_matcher_ready())
if ((!g_Matcher.isReady())
&& (this->args.obfuscated == OBFUSC_NONE))
{
// not a PE file, and we are not interested in patterns or obfuscated contents, so just finish it here
Expand Down
28 changes: 13 additions & 15 deletions utils/artefacts_util.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "artefacts_util.h"
#include <peconv.h>
#include "code_patterns.h"
#include "custom_mutex.h"
#ifdef _DEBUG
#include <iostream>
#endif
Expand Down Expand Up @@ -140,20 +139,18 @@ bool pesieve::util::is_normal_inaccessible(DWORD state, DWORD mapping_type, DWOR
return false;
}

//---
// matcher:

sig_finder::Node mainMatcher;
pesieve::util::Mutex g_mainMatcherMutex;

bool pesieve::matcher::is_matcher_ready()
bool pesieve::PatternMatcher::isReady()
{
util::MutexLocker guard(g_mainMatcherMutex);
util::MutexLocker guard(mainMatcherMutex);
return (mainMatcher.isEnd()) ? false : true;
}

size_t pesieve::matcher::load_pattern_file(const char* filename)
size_t pesieve::PatternMatcher::loadPatternFile(const char* filename)
{
util::MutexLocker guard(g_mainMatcherMutex);
util::MutexLocker guard(mainMatcherMutex);
static bool isLoaded = false;
if (isLoaded) return 0; // allow to load file only once

Expand All @@ -166,12 +163,13 @@ size_t pesieve::matcher::load_pattern_file(const char* filename)
Signature* sign = *itr;
delete sign;
}
std::cout << "Added patterns: " << std::dec << added << "\n";
return added;
}

bool pesieve::matcher::init_shellcode_patterns()
bool pesieve::PatternMatcher::initShellcodePatterns()
{
util::MutexLocker guard(g_mainMatcherMutex);
util::MutexLocker guard(mainMatcherMutex);
static bool isLoaded = false;
if (isLoaded) return false; // allow to load only once

Expand All @@ -181,19 +179,19 @@ bool pesieve::matcher::init_shellcode_patterns()
return true;
}

size_t pesieve::matcher::find_all_patterns(BYTE* loadedData, size_t loadedSize, std::vector<sig_finder::Match>& allMatches)
size_t pesieve::PatternMatcher::findAllPatterns(BYTE* loadedData, size_t loadedSize, std::vector<sig_finder::Match>& allMatches)
{
if (!is_matcher_ready()) {
if (!isReady()) {
return false;
}
if (peconv::is_padding(loadedData, loadedSize, 0)) {
return false;
}
const size_t matches = sig_finder::find_all_matches(mainMatcher, loadedData, loadedSize, allMatches);
const size_t matches = sig_finder::find_all_matches(mainMatcher, loadedData, loadedSize, allMatches);
return matches;
}

size_t pesieve::matcher::filter_custom(std::vector<sig_finder::Match>& allMatches, std::vector<sig_finder::Match>& customPatternMatches)
size_t pesieve::PatternMatcher::filterCustom(std::vector<sig_finder::Match>& allMatches, std::vector<sig_finder::Match>& customPatternMatches)
{
util::MutexLocker guard(g_HardcodedPatternsMutex);
size_t customCount = 0;
Expand All @@ -209,4 +207,4 @@ size_t pesieve::matcher::filter_custom(std::vector<sig_finder::Match>& allMatche
}
}
return customCount;
}
}
34 changes: 21 additions & 13 deletions utils/artefacts_util.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once
#include <windows.h>
#include <sig_finder.h>
#include <vector>
#include "custom_mutex.h"
#define PATTERN_NOT_FOUND (-1)

namespace pesieve {
Expand All @@ -10,22 +12,22 @@ namespace pesieve {
If the number of iterations is not specified (0) it scans full space, otherwise it takes only max_iter number of steps.
Returns the pointer to the found pattern, or nullptr if not found.
*/
BYTE* find_pattern(BYTE *buffer, size_t buf_size, BYTE* pattern_buf, size_t pattern_size, size_t max_iter = 0);
BYTE* find_pattern(BYTE* buffer, size_t buf_size, BYTE* pattern_buf, size_t pattern_size, size_t max_iter = 0);

/*
Scans the buffer searching for the hardcoded 32-bit code patterns. If found, returns the match offset, otherwise returns CODE_PATTERN_NOT_FOUND
*/
size_t is_32bit_code(BYTE *loadedData, size_t loadedSize);
size_t is_32bit_code(BYTE* loadedData, size_t loadedSize);

/*
Scans the buffer searching for the hardcoded 64-bit code patterns. If found, returns the match offset, otherwise returns CODE_PATTERN_NOT_FOUND
*/
size_t is_64bit_code(BYTE *loadedData, size_t loadedSize);
size_t is_64bit_code(BYTE* loadedData, size_t loadedSize);

/*
Scans the buffer searching for any hardcoded code patterns (both 32 and 64 bit).
*/
bool is_code(BYTE *loadedData, size_t loadedSize);
bool is_code(BYTE* loadedData, size_t loadedSize);

bool is_executable(DWORD mapping_type, DWORD protection);

Expand All @@ -34,19 +36,25 @@ namespace pesieve {
bool is_normal_inaccessible(DWORD state, DWORD mapping_type, DWORD protection);
}; // namespace util

namespace matcher {

/* using the global matcher */
// matcher:
class PatternMatcher
{
public:
bool isReady();

bool is_matcher_ready();
size_t loadPatternFile(const char* filename);

bool init_shellcode_patterns();
bool initShellcodePatterns();

size_t load_pattern_file(const char* filename);
size_t findAllPatterns(BYTE* loadedData, size_t loadedSize, ::std::vector<sig_finder::Match>& allMatches);

size_t find_all_patterns(BYTE* loadedData, size_t loadedSize, std::vector<sig_finder::Match>& allMatches);
size_t filterCustom(::std::vector<sig_finder::Match>& allMatches, ::std::vector<sig_finder::Match>& customPatternMatches);

size_t filter_custom(std::vector<sig_finder::Match>& allMatches, std::vector<sig_finder::Match>& customPatternMatches);
protected:
sig_finder::Node mainMatcher;
pesieve::util::Mutex mainMatcherMutex;
};

}; //namespace matcher
}

}; //namespace pesieve

0 comments on commit 6805ada

Please sign in to comment.