From 2bd40ef5adb6afce7c7aafc7fa769088c20312f8 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Thu, 8 Feb 2024 12:01:36 -0800 Subject: [PATCH 1/8] [FEATURE] In pattern_tree: allow for patterns with wildcards --- pe_sieve_ver_short.h | 4 +- utils/pattern_tree.h | 160 +++++++++++++++++++++++++++++++++---------- 2 files changed, 125 insertions(+), 39 deletions(-) diff --git a/pe_sieve_ver_short.h b/pe_sieve_ver_short.h index 3769feee4..1fa356bfc 100644 --- a/pe_sieve_ver_short.h +++ b/pe_sieve_ver_short.h @@ -3,6 +3,6 @@ #define PESIEVE_MAJOR_VERSION 0 #define PESIEVE_MINOR_VERSION 3 #define PESIEVE_MICRO_VERSION 8 -#define PESIEVE_PATCH_VERSION 3 +#define PESIEVE_PATCH_VERSION 4 -#define PESIEVE_VERSION_STR "0.3.8.3" +#define PESIEVE_VERSION_STR "0.3.8.4" diff --git a/utils/pattern_tree.h b/utils/pattern_tree.h index b8d5e396d..5c03e363f 100644 --- a/utils/pattern_tree.h +++ b/utils/pattern_tree.h @@ -6,19 +6,37 @@ #include #include +#define MASK_IMM 0xFF +#define MASK_PARTIAL1 0x0F +#define MASK_PARTIAL2 0xF0 +#define MASK_WILDCARD 0 + namespace pattern_tree { class Signature { public: - Signature(std::string _name, const BYTE* _pattern, size_t _pattern_size) - : name(_name), pattern(nullptr), pattern_size(0) + Signature(std::string _name, const BYTE* _pattern, size_t _pattern_size, const BYTE* _mask) + : name(_name), pattern(nullptr), pattern_size(0), mask(nullptr) { this->pattern = (BYTE*)::calloc(_pattern_size, 1); if (!this->pattern) return; ::memcpy(this->pattern, _pattern, _pattern_size); this->pattern_size = _pattern_size; + + if (_mask) { + this->mask = (BYTE*)::calloc(_pattern_size, 1); + if (this->mask) { + ::memcpy(this->mask, _mask, _pattern_size); + } + } + } + + Signature(const Signature& _sign) // copy constructor + : pattern(nullptr), pattern_size(0), mask(nullptr) + { + init(_sign.name, _sign.pattern, _sign.pattern_size, _sign.mask); } size_t size() @@ -29,8 +47,32 @@ namespace pattern_tree { std::string name; protected: + size_t pattern_size; BYTE* pattern; + BYTE* mask; + + private: + bool init(std::string _name, const BYTE* _pattern, size_t _pattern_size, const BYTE* _mask) + { + if (this->pattern || this->mask) return false; + + this->pattern = (BYTE*)::calloc(_pattern_size, 1); + if (!this->pattern) return false; + + ::memcpy(this->pattern, _pattern, _pattern_size); + this->pattern_size = _pattern_size; + + if (_mask) { + this->mask = (BYTE*)::calloc(_pattern_size, 1); + if (this->mask) { + ::memcpy(this->mask, _mask, _pattern_size); + } + } + return true; + } + + friend class Node; }; class Match @@ -113,18 +155,18 @@ namespace pattern_tree { class Node { public: - - static bool addPattern(Node* rootN, const char* _name, const BYTE* pattern, size_t pattern_size) + static bool addPattern(Node* rootN, const char* _name, const BYTE* pattern, size_t pattern_size, const BYTE* pattern_mask=nullptr) { if (!rootN || !pattern || !pattern_size) { return false; } Node* next = rootN; for (size_t i = 0; i < pattern_size; i++) { - next = next->addNext(pattern[i]); + BYTE mask = (pattern_mask != nullptr) ? pattern_mask[i] : MASK_IMM; + next = next->addNext(pattern[i], mask); if (!next) return false; } - next->sign = new Signature(_name, pattern, pattern_size); + next->sign = new Signature(_name, pattern, pattern_size, pattern_mask); return true; } @@ -133,16 +175,21 @@ namespace pattern_tree { return Node::addPattern(rootN, pattern1, (const BYTE*)pattern1, strlen(pattern1)); } + static bool addSignature(Node* rootN, const Signature& sign) + { + return addPattern(rootN, sign.name.c_str(), sign.pattern, sign.pattern_size, sign.mask); + } + //--- Node() - : level(0), val(0), + : level(0), val(0), mask(MASK_IMM), sign(nullptr) { } - Node(BYTE _val, size_t _level) - : val(_val), level(_level), + Node(BYTE _val, size_t _level, BYTE _mask) + : val(_val), level(_level), mask(_mask), sign(nullptr) { } @@ -159,21 +206,43 @@ namespace pattern_tree { } } - Node* getNode(BYTE _val) + Node* getNode(BYTE _val, BYTE _mask) { - auto found = immediates.find(_val); - if (found != immediates.end()) { - return found->second; + BYTE maskedVal = _val & _mask; + if (_mask == MASK_IMM) { + return _findInChildren(immediates, maskedVal); + } + else if (_mask == MASK_PARTIAL1 || _mask == MASK_PARTIAL2) { + return _findInChildren(partials, maskedVal); + } + else if (_mask == MASK_WILDCARD) { + return _findInChildren(wildcards, maskedVal); } return nullptr; } - Node* addNext(BYTE _val) + Node* addNext(BYTE _val, BYTE _mask) { - Node* nextN = getNode(_val); - if (!nextN) { - nextN = new Node(_val, this->level + 1); - immediates[_val] = nextN; + Node* nextN = getNode(_val, _mask); + if (nextN) { + return nextN; + } + + BYTE maskedVal = _val & _mask; + nextN = new Node(_val, this->level + 1, _mask); + if (_mask == MASK_IMM) { + immediates[maskedVal] = nextN; + } + else if (_mask == MASK_PARTIAL1 || _mask == MASK_PARTIAL2) { + partials[maskedVal] = nextN; + } + else if (_mask == MASK_WILDCARD) { + wildcards[maskedVal] = nextN; + } + else { + delete nextN; + std::cout << "Invalid mask supplied for value: " << std::hex << (unsigned int)_val << " Mask:" << (unsigned int)_mask << "\n"; + return nullptr; // invalid mask } return nextN; } @@ -207,7 +276,7 @@ namespace pattern_tree { processed = i; // processed bytes level2_ptr->clear(); for (size_t k = 0; k < level1_ptr->size(); k++) { - Node * curr = level1_ptr->at(k); + Node* curr = level1_ptr->at(k); if (curr->isSign()) { size_t match_start = i - curr->sign->size(); Match m(match_start, curr->sign); @@ -216,18 +285,11 @@ namespace pattern_tree { return match_start; } } - Node* prev = curr; - curr = prev->getNode(data[i]); - if (curr) { - level2_ptr->push_back(curr); - } + _followAllMasked(level2_ptr, curr, data[i]); #ifdef SEARCH_BACK - if (prev != this) { + if (curr != this) { // the current value may also be a beginning of a new pattern: - Node* start = this->getNode(data[i]); - if (start) { - level2_ptr->push_back(start); - } + _followAllMasked(level2_ptr, this, data[i]); } #endif } @@ -249,7 +311,7 @@ namespace pattern_tree { bool isEnd() { - return this->immediates.size() ? false : true; + return (!immediates.size() && !partials.size() && !wildcards.size()) ? true : false; } bool isSign() @@ -258,24 +320,48 @@ namespace pattern_tree { } protected: + Node* _findInChildren(std::map& children, BYTE _val) + { + auto found = children.find(_val); + if (found != children.end()) { + return found->second; + } + return nullptr; + } + + bool _followMasked(ShortList* level2_ptr, Node* curr, BYTE val, BYTE mask) + { + Node* next = curr->getNode(val, mask); + if (!next) { + return false; + } + return level2_ptr->push_back(next); + } + + void _followAllMasked(ShortList* level2_ptr, Node* node, BYTE val) + { + _followMasked(level2_ptr, node, val, MASK_IMM); + _followMasked(level2_ptr, node, val, MASK_PARTIAL1); + _followMasked(level2_ptr, node, val, MASK_PARTIAL2); + _followMasked(level2_ptr, node, val, MASK_WILDCARD); + } + Signature* sign; BYTE val; + BYTE mask; size_t level; std::map immediates; + std::map partials; + std::map wildcards; }; - - inline size_t find_all_matches(Node& rootN, const BYTE* loadedData, size_t loadedSize, std::vector &allMatches) + inline size_t find_all_matches(Node& rootN, const BYTE* loadedData, size_t loadedSize, std::vector& allMatches) { if (!loadedData || !loadedSize) { return 0; } - size_t counter = 0; rootN.getMatching(loadedData, loadedSize, allMatches, false); - if (allMatches.size()) { - counter += allMatches.size(); - } - return counter; + return allMatches.size(); } inline Match find_first_match(Node& rootN, const BYTE* loadedData, size_t loadedSize) From 1c0255b2d2853fdfec5f201f13801e6f12d407f2 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Thu, 8 Feb 2024 13:18:38 -0800 Subject: [PATCH 2/8] [BUGFIX] In Node destructor: delete all the lists. Cleanup --- utils/pattern_tree.h | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/utils/pattern_tree.h b/utils/pattern_tree.h index 5c03e363f..f14f84721 100644 --- a/utils/pattern_tree.h +++ b/utils/pattern_tree.h @@ -196,11 +196,9 @@ namespace pattern_tree { ~Node() { - for (auto itr = immediates.begin(); itr != immediates.end(); ++itr) { - Node* next = itr->second; - delete next; - } - immediates.clear(); + _deleteChildren(immediates); + _deleteChildren(partials); + _deleteChildren(wildcards); if (sign) { delete sign; } @@ -322,6 +320,9 @@ namespace pattern_tree { protected: Node* _findInChildren(std::map& children, BYTE _val) { + if (!children.size()) { + return nullptr; + } auto found = children.find(_val); if (found != children.end()) { return found->second; @@ -346,6 +347,15 @@ namespace pattern_tree { _followMasked(level2_ptr, node, val, MASK_WILDCARD); } + void _deleteChildren(std::map& children) + { + for (auto itr = children.begin(); itr != children.end(); ++itr) { + Node* next = itr->second; + delete next; + } + children.clear(); + } + Signature* sign; BYTE val; BYTE mask; From e031a5d6ae02371cecc8c7976ce080429548e4b5 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sat, 10 Feb 2024 17:58:34 -0800 Subject: [PATCH 3/8] Added sig_finder submodule --- .gitmodules | 3 +++ sig_finder | 1 + 2 files changed, 4 insertions(+) create mode 160000 sig_finder diff --git a/.gitmodules b/.gitmodules index 65ee92521..1f7402658 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "paramkit"] path = paramkit url = https://github.com/hasherezade/paramkit +[submodule "sig_finder"] + path = sig_finder + url = https://github.com/hasherezade/sig_finder diff --git a/sig_finder b/sig_finder new file mode 160000 index 000000000..e2feef8a8 --- /dev/null +++ b/sig_finder @@ -0,0 +1 @@ +Subproject commit e2feef8a88aeee3f0a59a4997ae9195b3412266a From 04ab5506008c3323fbe7bcbac990ab002eda236b Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sat, 10 Feb 2024 19:12:07 -0800 Subject: [PATCH 4/8] [FEATURE] Refactored to use new sig_finder for pattern matching --- CMakeLists.txt | 16 +- pe_sieve_ver_short.h | 4 +- utils/artefacts_util.cpp | 33 ++-- utils/pattern_tree.h | 392 --------------------------------------- 4 files changed, 29 insertions(+), 416 deletions(-) delete mode 100644 utils/pattern_tree.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ea24a80bb..ce88706de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,15 +34,21 @@ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") # modules: set ( M_PARSER "libpeconv/libpeconv" ) +set ( M_SIGFIND "sig_finder/sig_finder" ) # modules paths: -set (PECONV_DIR "${PROJECT_SOURCE_DIR}/${M_PARSER}" CACHE PATH "PEConv main path") +set ( PECONV_DIR "${PROJECT_SOURCE_DIR}/${M_PARSER}" CACHE PATH "PEConv main path") +set ( SIGFIND_DIR "${PROJECT_SOURCE_DIR}/${M_SIGFIND}" CACHE PATH "SigFinder main path") # modules headers: include_directories ( ${PECONV_DIR}/include ) +include_directories ( ${SIGFIND_DIR}/include ) + # libs -add_subdirectory (libpeconv/libpeconv) +add_subdirectory (${M_PARSER}) set ( PECONV_LIB $ CACHE PATH "PEConvLib library path" ) +add_subdirectory(${M_SIGFIND}) +set ( SIGFIND_LIB $ CACHE PATH "SigFinder library path" ) if( NOT PESIEVE_AS_STATIC_LIB AND NOT PESIEVE_AS_DLL) set ( M_PARAMKIT_LIB "paramkit" ) @@ -168,7 +174,6 @@ set (utils_hdrs utils/workingset_enum.h utils/modules_enum.h utils/artefacts_util.h - utils/pattern_tree.h utils/process_reflection.h utils/console_color.h utils/strings_util.h @@ -275,11 +280,12 @@ if(PESIEVE_AS_STATIC_LIB OR PESIEVE_AS_DLL) ) set_source_files_properties(main.def PROPERTIES HEADER_FILE_ONLY TRUE) else() - add_executable ( ${PROJECT_NAME} ${hdrs} ${srcs} ${rsrc} pe_sieve_res_icon.rc main.cpp params.h ) + add_executable ( ${PROJECT_NAME} ${hdrs} ${srcs} ${rsrc} pe_sieve_res_icon.rc main.cpp params.h ) endif() set (used_libs ${PECONV_LIB} + ${SIGFIND_LIB} psapi.lib ntdll.lib shlwapi @@ -287,7 +293,7 @@ set (used_libs ) # dependencies -add_dependencies(${PROJECT_NAME} libpeconv ) +add_dependencies( ${PROJECT_NAME} libpeconv sig_finder ) if(PESIEVE_AS_STATIC_LIB OR PESIEVE_AS_DLL) include(GNUInstallDirs) diff --git a/pe_sieve_ver_short.h b/pe_sieve_ver_short.h index 1fa356bfc..5a10a90bf 100644 --- a/pe_sieve_ver_short.h +++ b/pe_sieve_ver_short.h @@ -3,6 +3,6 @@ #define PESIEVE_MAJOR_VERSION 0 #define PESIEVE_MINOR_VERSION 3 #define PESIEVE_MICRO_VERSION 8 -#define PESIEVE_PATCH_VERSION 4 +#define PESIEVE_PATCH_VERSION 5 -#define PESIEVE_VERSION_STR "0.3.8.4" +#define PESIEVE_VERSION_STR "0.3.8.5" diff --git a/utils/artefacts_util.cpp b/utils/artefacts_util.cpp index a1876027d..ee308b1ba 100644 --- a/utils/artefacts_util.cpp +++ b/utils/artefacts_util.cpp @@ -1,13 +1,12 @@ #include "artefacts_util.h" #include -#include "pattern_tree.h" +#include +using namespace sig_finder; #ifdef _DEBUG #include #endif -using namespace pattern_tree; - BYTE* pesieve::util::find_pattern(BYTE* buffer, size_t buf_size, BYTE* pattern_buf, size_t pattern_size, size_t max_iter) { for (size_t i = 0; (i + pattern_size) < buf_size; i++) { @@ -38,9 +37,9 @@ bool init_32_patterns(Node* rootN) 0x89, 0xE5 // MOV EBP, ESP }; - Node::addPattern(rootN, "prolog32_1", prolog32_pattern, sizeof(prolog32_pattern)); - Node::addPattern(rootN, "prolog32_2", prolog32_2_pattern, sizeof(prolog32_2_pattern)); - Node::addPattern(rootN, "prolog32_3", prolog32_3_pattern, sizeof(prolog32_3_pattern)); + rootN->addPattern("prolog32_1", prolog32_pattern, sizeof(prolog32_pattern)); + rootN->addPattern("prolog32_2", prolog32_2_pattern, sizeof(prolog32_2_pattern)); + rootN->addPattern("prolog32_3", prolog32_3_pattern, sizeof(prolog32_3_pattern)); return true; } @@ -86,19 +85,19 @@ bool init_64_patterns(Node* rootN64) 0x41, 0x57 // PUSH R15 }; - Node::addPattern(rootN64, "prolog64_1", prolog64_pattern, sizeof(prolog64_pattern)); - Node::addPattern(rootN64, "prolog64_2", prolog64_2_pattern, sizeof(prolog64_2_pattern)); - Node::addPattern(rootN64, "prolog64_3", prolog64_3_pattern, sizeof(prolog64_3_pattern)); - Node::addPattern(rootN64, "prolog64_4", prolog64_4_pattern, sizeof(prolog64_4_pattern)); - Node::addPattern(rootN64, "prolog64_5", prolog64_5_pattern, sizeof(prolog64_5_pattern)); - Node::addPattern(rootN64, "prolog64_6", prolog64_6_pattern, sizeof(prolog64_6_pattern)); - Node::addPattern(rootN64, "prolog64_7", prolog64_7_pattern, sizeof(prolog64_7_pattern)); + rootN64->addPattern("prolog64_1", prolog64_pattern, sizeof(prolog64_pattern)); + rootN64->addPattern("prolog64_2", prolog64_2_pattern, sizeof(prolog64_2_pattern)); + rootN64->addPattern("prolog64_3", prolog64_3_pattern, sizeof(prolog64_3_pattern)); + rootN64->addPattern("prolog64_4", prolog64_4_pattern, sizeof(prolog64_4_pattern)); + rootN64->addPattern("prolog64_5", prolog64_5_pattern, sizeof(prolog64_5_pattern)); + rootN64->addPattern("prolog64_6", prolog64_6_pattern, sizeof(prolog64_6_pattern)); + rootN64->addPattern("prolog64_7", prolog64_7_pattern, sizeof(prolog64_7_pattern)); return true; } -size_t search_till_pattern(Node& rootN, const BYTE* loadedData, size_t loadedSize) +size_t search_till_pattern(sig_finder::Node& rootN, const BYTE* loadedData, size_t loadedSize) { - Match m = pattern_tree::find_first_match(rootN, loadedData, loadedSize); + Match m = sig_finder::find_first_match(rootN, loadedData, loadedSize); if (!m.sign) { return CODE_PATTERN_NOT_FOUND; } @@ -107,7 +106,7 @@ size_t search_till_pattern(Node& rootN, const BYTE* loadedData, size_t loadedSiz size_t pesieve::util::is_32bit_code(BYTE *loadedData, size_t loadedSize) { - static Node rootN; + static sig_finder::Node rootN; if(rootN.isEnd()) { init_32_patterns(&rootN); } @@ -116,7 +115,7 @@ size_t pesieve::util::is_32bit_code(BYTE *loadedData, size_t loadedSize) size_t pesieve::util::is_64bit_code(BYTE* loadedData, size_t loadedSize) { - static Node rootN; + static sig_finder::Node rootN; if (rootN.isEnd()) { init_64_patterns(&rootN); } diff --git a/utils/pattern_tree.h b/utils/pattern_tree.h deleted file mode 100644 index f14f84721..000000000 --- a/utils/pattern_tree.h +++ /dev/null @@ -1,392 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#define MASK_IMM 0xFF -#define MASK_PARTIAL1 0x0F -#define MASK_PARTIAL2 0xF0 -#define MASK_WILDCARD 0 - -namespace pattern_tree { - - class Signature - { - public: - Signature(std::string _name, const BYTE* _pattern, size_t _pattern_size, const BYTE* _mask) - : name(_name), pattern(nullptr), pattern_size(0), mask(nullptr) - { - this->pattern = (BYTE*)::calloc(_pattern_size, 1); - if (!this->pattern) return; - - ::memcpy(this->pattern, _pattern, _pattern_size); - this->pattern_size = _pattern_size; - - if (_mask) { - this->mask = (BYTE*)::calloc(_pattern_size, 1); - if (this->mask) { - ::memcpy(this->mask, _mask, _pattern_size); - } - } - } - - Signature(const Signature& _sign) // copy constructor - : pattern(nullptr), pattern_size(0), mask(nullptr) - { - init(_sign.name, _sign.pattern, _sign.pattern_size, _sign.mask); - } - - size_t size() - { - return pattern_size; - } - - std::string name; - - protected: - - size_t pattern_size; - BYTE* pattern; - BYTE* mask; - - private: - bool init(std::string _name, const BYTE* _pattern, size_t _pattern_size, const BYTE* _mask) - { - if (this->pattern || this->mask) return false; - - this->pattern = (BYTE*)::calloc(_pattern_size, 1); - if (!this->pattern) return false; - - ::memcpy(this->pattern, _pattern, _pattern_size); - this->pattern_size = _pattern_size; - - if (_mask) { - this->mask = (BYTE*)::calloc(_pattern_size, 1); - if (this->mask) { - ::memcpy(this->mask, _mask, _pattern_size); - } - } - return true; - } - - friend class Node; - }; - - class Match - { - public: - Match() - : offset(0), sign(nullptr) - { - } - - Match(size_t _offset, Signature* _sign) - : offset(_offset), sign(_sign) - { - } - - Match(const Match& _match) // copy constructor - { - offset = _match.offset; - sign = _match.sign; - } - - size_t offset; - Signature* sign; - }; - - template class ShortList - { - public: - ShortList() - : elCount(0) - { - } - - bool push_back(Element n) - { - if (elCount >= _countof(list)) { - return false; - } - if (find(n)) { - return true; - } - list[elCount] = n; - elCount++; - return true; - } - - Element at(size_t i) - { - if (i < _countof(list)) { - return list[i]; - } - return nullptr; - } - - Element find(Element& searched) - { - for (size_t i = 0; i < elCount; i++) { - if (list[i] == searched) { - return list[i]; - } - } - return nullptr; - } - - void clear() - { - elCount = 0; - } - - size_t size() - { - return elCount; - } - - protected: - size_t elCount; - Element list[100]; - }; - - class Node - { - public: - static bool addPattern(Node* rootN, const char* _name, const BYTE* pattern, size_t pattern_size, const BYTE* pattern_mask=nullptr) - { - if (!rootN || !pattern || !pattern_size) { - return false; - } - Node* next = rootN; - for (size_t i = 0; i < pattern_size; i++) { - BYTE mask = (pattern_mask != nullptr) ? pattern_mask[i] : MASK_IMM; - next = next->addNext(pattern[i], mask); - if (!next) return false; - } - next->sign = new Signature(_name, pattern, pattern_size, pattern_mask); - return true; - } - - static bool addTextPattern(Node* rootN, const char* pattern1) - { - return Node::addPattern(rootN, pattern1, (const BYTE*)pattern1, strlen(pattern1)); - } - - static bool addSignature(Node* rootN, const Signature& sign) - { - return addPattern(rootN, sign.name.c_str(), sign.pattern, sign.pattern_size, sign.mask); - } - - //--- - - Node() - : level(0), val(0), mask(MASK_IMM), - sign(nullptr) - { - } - - Node(BYTE _val, size_t _level, BYTE _mask) - : val(_val), level(_level), mask(_mask), - sign(nullptr) - { - } - - ~Node() - { - _deleteChildren(immediates); - _deleteChildren(partials); - _deleteChildren(wildcards); - if (sign) { - delete sign; - } - } - - Node* getNode(BYTE _val, BYTE _mask) - { - BYTE maskedVal = _val & _mask; - if (_mask == MASK_IMM) { - return _findInChildren(immediates, maskedVal); - } - else if (_mask == MASK_PARTIAL1 || _mask == MASK_PARTIAL2) { - return _findInChildren(partials, maskedVal); - } - else if (_mask == MASK_WILDCARD) { - return _findInChildren(wildcards, maskedVal); - } - return nullptr; - } - - Node* addNext(BYTE _val, BYTE _mask) - { - Node* nextN = getNode(_val, _mask); - if (nextN) { - return nextN; - } - - BYTE maskedVal = _val & _mask; - nextN = new Node(_val, this->level + 1, _mask); - if (_mask == MASK_IMM) { - immediates[maskedVal] = nextN; - } - else if (_mask == MASK_PARTIAL1 || _mask == MASK_PARTIAL2) { - partials[maskedVal] = nextN; - } - else if (_mask == MASK_WILDCARD) { - wildcards[maskedVal] = nextN; - } - else { - delete nextN; - std::cout << "Invalid mask supplied for value: " << std::hex << (unsigned int)_val << " Mask:" << (unsigned int)_mask << "\n"; - return nullptr; // invalid mask - } - return nextN; - } - - void print() - { - std::cout << std::hex << (unsigned int)val << " [" << level << "]" << " [" << immediates.size() << "]"; - if (!immediates.size()) { - printf("\n"); - return; - } - for (auto itr = immediates.begin(); itr != immediates.end(); ++itr) { - itr->second->print(); - } - } - -#define SEARCH_BACK - size_t getMatching(const BYTE* data, size_t data_size, std::vector &matches, bool stopOnFirst) - { - size_t processed = 0; - // - ShortList level; - level.push_back(this); - ShortList level2; - - auto level1_ptr = &level; - auto level2_ptr = &level2; - - for (size_t i = 0; i < data_size; i++) - { - processed = i; // processed bytes - level2_ptr->clear(); - for (size_t k = 0; k < level1_ptr->size(); k++) { - Node* curr = level1_ptr->at(k); - if (curr->isSign()) { - size_t match_start = i - curr->sign->size(); - Match m(match_start, curr->sign); - matches.push_back(m); - if (stopOnFirst) { - return match_start; - } - } - _followAllMasked(level2_ptr, curr, data[i]); -#ifdef SEARCH_BACK - if (curr != this) { - // the current value may also be a beginning of a new pattern: - _followAllMasked(level2_ptr, this, data[i]); - } -#endif - } - if (!level2_ptr->size()) { -#ifdef SEARCH_BACK - // restart search from the beginning - level2_ptr->push_back(this); -#else - return results; -#endif //SEARCH_BACK - } - //swap: - auto tmp = level1_ptr; - level1_ptr = level2_ptr; - level2_ptr = tmp; - } - return processed; - } - - bool isEnd() - { - return (!immediates.size() && !partials.size() && !wildcards.size()) ? true : false; - } - - bool isSign() - { - return sign ? true : false; - } - - protected: - Node* _findInChildren(std::map& children, BYTE _val) - { - if (!children.size()) { - return nullptr; - } - auto found = children.find(_val); - if (found != children.end()) { - return found->second; - } - return nullptr; - } - - bool _followMasked(ShortList* level2_ptr, Node* curr, BYTE val, BYTE mask) - { - Node* next = curr->getNode(val, mask); - if (!next) { - return false; - } - return level2_ptr->push_back(next); - } - - void _followAllMasked(ShortList* level2_ptr, Node* node, BYTE val) - { - _followMasked(level2_ptr, node, val, MASK_IMM); - _followMasked(level2_ptr, node, val, MASK_PARTIAL1); - _followMasked(level2_ptr, node, val, MASK_PARTIAL2); - _followMasked(level2_ptr, node, val, MASK_WILDCARD); - } - - void _deleteChildren(std::map& children) - { - for (auto itr = children.begin(); itr != children.end(); ++itr) { - Node* next = itr->second; - delete next; - } - children.clear(); - } - - Signature* sign; - BYTE val; - BYTE mask; - size_t level; - std::map immediates; - std::map partials; - std::map wildcards; - }; - - inline size_t find_all_matches(Node& rootN, const BYTE* loadedData, size_t loadedSize, std::vector& allMatches) - { - if (!loadedData || !loadedSize) { - return 0; - } - rootN.getMatching(loadedData, loadedSize, allMatches, false); - return allMatches.size(); - } - - inline Match find_first_match(Node& rootN, const BYTE* loadedData, size_t loadedSize) - { - Match empty; - if (!loadedData || !loadedSize) { - return empty; - } - std::vector allMatches; - rootN.getMatching(loadedData, loadedSize, allMatches, true); - if (allMatches.size()) { - auto itr = allMatches.begin(); - return *itr; - } - return empty; - } - -}; //namespace pattern_tree From 6f3c73010d15fa83d40d603d7ac08e061d21a42a Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sat, 10 Feb 2024 22:48:16 -0800 Subject: [PATCH 5/8] Updates sig_finder --- sig_finder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sig_finder b/sig_finder index e2feef8a8..773da4039 160000 --- a/sig_finder +++ b/sig_finder @@ -1 +1 @@ -Subproject commit e2feef8a88aeee3f0a59a4997ae9195b3412266a +Subproject commit 773da4039f42eb57561023280517fe7c2c9eeba3 From 288eee2873740c775732e8c07a87fe8933108929 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sun, 11 Feb 2024 11:01:18 -0800 Subject: [PATCH 6/8] Updated sig_finder --- sig_finder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sig_finder b/sig_finder index 773da4039..bef3cd882 160000 --- a/sig_finder +++ b/sig_finder @@ -1 +1 @@ -Subproject commit 773da4039f42eb57561023280517fe7c2c9eeba3 +Subproject commit bef3cd8825e9c569bfe37a70a6c2059774139eb3 From 3a44c47b233746a4d8aa44547f7165b2408d7588 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sun, 11 Feb 2024 16:05:46 -0800 Subject: [PATCH 7/8] [BUGFIX] Updates sig_finder with a bugfix --- sig_finder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sig_finder b/sig_finder index bef3cd882..9f88b8baf 160000 --- a/sig_finder +++ b/sig_finder @@ -1 +1 @@ -Subproject commit bef3cd8825e9c569bfe37a70a6c2059774139eb3 +Subproject commit 9f88b8bafe99c117577b4eb5dedabe9df2452795 From 79cd4b753d75dbd177e4ff04c68580ab0c45ac37 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sun, 11 Feb 2024 16:32:02 -0800 Subject: [PATCH 8/8] [VERSION] 0.3.8.6 --- pe_sieve_ver_short.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pe_sieve_ver_short.h b/pe_sieve_ver_short.h index 5a10a90bf..1e729760f 100644 --- a/pe_sieve_ver_short.h +++ b/pe_sieve_ver_short.h @@ -5,4 +5,4 @@ #define PESIEVE_MICRO_VERSION 8 #define PESIEVE_PATCH_VERSION 5 -#define PESIEVE_VERSION_STR "0.3.8.5" +#define PESIEVE_VERSION_STR "0.3.8.6"