diff --git a/CMakeLists.txt b/CMakeLists.txt index ce88706de..e5468fa6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,6 +178,7 @@ set (utils_hdrs utils/console_color.h utils/strings_util.h utils/byte_buffer.h + utils/code_patterns.h ) set (params_info_hdrs diff --git a/postprocessors/imp_rec/imp_reconstructor.h b/postprocessors/imp_rec/imp_reconstructor.h index b9f47d9f8..9d94cf58d 100644 --- a/postprocessors/imp_rec/imp_reconstructor.h +++ b/postprocessors/imp_rec/imp_reconstructor.h @@ -166,7 +166,7 @@ namespace pesieve { } else { const size_t found_pattern = pesieve::util::is_64bit_code(peBuffer.vBuf, peBuffer.vBufSize); - this->is64bit = (found_pattern != CODE_PATTERN_NOT_FOUND); + this->is64bit = (found_pattern != PATTERN_NOT_FOUND); } collectMainIatData(); } diff --git a/utils/artefacts_util.cpp b/utils/artefacts_util.cpp index ee308b1ba..b24ebf9d3 100644 --- a/utils/artefacts_util.cpp +++ b/utils/artefacts_util.cpp @@ -1,6 +1,8 @@ #include "artefacts_util.h" #include -#include + +#include "code_patterns.h" + using namespace sig_finder; #ifdef _DEBUG @@ -18,91 +20,46 @@ BYTE* pesieve::util::find_pattern(BYTE* buffer, size_t buf_size, BYTE* pattern_b return nullptr; } -bool init_32_patterns(Node* rootN) -{ - if (!rootN) return false; - - BYTE prolog32_pattern[] = { - 0x55, // PUSH EBP - 0x8b, 0xEC // MOV EBP, ESP - }; - - BYTE prolog32_2_pattern[] = { - 0x55, // PUSH EBP - 0x89, 0xE5 // MOV EBP, ESP - }; - - BYTE prolog32_3_pattern[] = { - 0x60, // PUSHAD - 0x89, 0xE5 // MOV EBP, ESP - }; - - 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; -} +namespace pesieve { -bool init_64_patterns(Node* rootN64) -{ - if (!rootN64) return false; - - BYTE prolog64_pattern[] = { - 0x40, 0x53, // PUSH RBX - 0x48, 0x83, 0xEC // SUB RSP, - }; - BYTE prolog64_2_pattern[] = { - 0x55, // PUSH RBP - 0x48, 0x8B, 0xEC // MOV RBP, RSP - }; - BYTE prolog64_3_pattern[] = { - 0x40, 0x55, // PUSH RBP - 0x48, 0x83, 0xEC // SUB RSP, - }; - BYTE prolog64_4_pattern[] = { - 0x53, // PUSH RBX - 0x48, 0x81, 0xEC // SUB RSP, - }; - BYTE prolog64_5_pattern[] = { - 0x48, 0x83, 0xE4, 0xF0 // AND rsp, FFFFFFFFFFFFFFF0; Align RSP to 16 bytes - }; - BYTE prolog64_6_pattern[] = { - 0x57, // PUSH RDI - 0x48, 0x89, 0xE7 // MOV RDI, RSP - }; - BYTE prolog64_7_pattern[] = { - 0x48, 0x8B, 0xC4, // MOV RAX, RSP - 0x48, 0x89, 0x58, 0x08, // MOV QWORD PTR [RAX + 8], RBX - 0x4C, 0x89, 0x48, 0x20, // MOV QWORD PTR [RAX + 0X20], R9 - 0x4C, 0x89, 0x40, 0x18, // MOV QWORD PTR [RAX + 0X18], R8 - 0x48, 0x89, 0x50, 0x10, // MOV QWORD PTR [RAX + 0X10], RDX - 0x55, // PUSH RBP - 0x56, // PUSH RSI - 0x57, // PUSH RDI - 0x41, 0x54, // PUSH R12 - 0x41, 0x55, // PUSH R13 - 0x41, 0x56, // PUSH R14 - 0x41, 0x57 // PUSH R15 - }; - - 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 init_32_patterns(Node* rootN) + { + if (!rootN) return 0; -size_t search_till_pattern(sig_finder::Node& rootN, const BYTE* loadedData, size_t loadedSize) -{ - Match m = sig_finder::find_first_match(rootN, loadedData, loadedSize); - if (!m.sign) { - return CODE_PATTERN_NOT_FOUND; + size_t added = 0; + for (size_t i = 0; i < _countof(patterns32); i++) + { + const t_pattern& pattern = patterns32[i]; + std::string name = "prolog32_" + std::to_string(i); + if (rootN->addPattern(name.c_str(), pattern.ptr, pattern.size)) added++; + } + return added; } - return m.offset; -} + + size_t init_64_patterns(Node* rootN) + { + if (!rootN) return 0; + + size_t added = 0; + for (size_t i = 0; i < _countof(patterns64); i++) + { + const t_pattern &pattern = patterns64[i]; + std::string name = "prolog64_" + std::to_string(i); + if (rootN->addPattern(name.c_str(), pattern.ptr, pattern.size)) added++; + } + return added; + } + + inline size_t search_till_pattern(sig_finder::Node& rootN, const BYTE* loadedData, size_t loadedSize) + { + Match m = sig_finder::find_first_match(rootN, loadedData, loadedSize); + if (!m.sign) { + return PATTERN_NOT_FOUND; + } + return m.offset; + } + +}; //namespace pesieve size_t pesieve::util::is_32bit_code(BYTE *loadedData, size_t loadedSize) { @@ -127,14 +84,12 @@ bool pesieve::util::is_code(BYTE* loadedData, size_t loadedSize) if (peconv::is_padding(loadedData, loadedSize, 0)) { return false; } - - static Node rootN; + static sig_finder::Node rootN; if (rootN.isEnd()) { init_32_patterns(&rootN); init_64_patterns(&rootN); } - - if ((search_till_pattern(rootN, loadedData, loadedSize)) != CODE_PATTERN_NOT_FOUND) { + if ((search_till_pattern(rootN, loadedData, loadedSize)) != PATTERN_NOT_FOUND) { return true; } return false; diff --git a/utils/artefacts_util.h b/utils/artefacts_util.h index 8b9a2ba9e..829d22d03 100644 --- a/utils/artefacts_util.h +++ b/utils/artefacts_util.h @@ -1,12 +1,12 @@ #pragma once #include - -#define CODE_PATTERN_NOT_FOUND (-1) +#include +#define PATTERN_NOT_FOUND (-1) namespace pesieve { namespace util { /* - Scans the buffer of given size, in a search of the supplied pattern. + Scans the buffer of given size, in a search of the supplied pattern (using simple memcmp) 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. */ diff --git a/utils/code_patterns.h b/utils/code_patterns.h new file mode 100644 index 000000000..9c2134399 --- /dev/null +++ b/utils/code_patterns.h @@ -0,0 +1,80 @@ +#pragma once +#include + +namespace pesieve { + + typedef struct _t_pattern { + BYTE* ptr; + size_t size; + } t_pattern; + + BYTE prolog32_pattern[] = { + 0x55, // PUSH EBP + 0x8b, 0xEC // MOV EBP, ESP + }; + + BYTE prolog32_2_pattern[] = { + 0x55, // PUSH EBP + 0x89, 0xE5 // MOV EBP, ESP + }; + + BYTE prolog32_3_pattern[] = { + 0x60, // PUSHAD + 0x89, 0xE5 // MOV EBP, ESP + }; + + t_pattern patterns32[] = { + { prolog32_pattern, sizeof(prolog32_pattern) }, + { prolog32_2_pattern, sizeof(prolog32_2_pattern) }, + { prolog32_3_pattern, sizeof(prolog32_3_pattern) } + }; + + BYTE prolog64_pattern[] = { + 0x40, 0x53, // PUSH RBX + 0x48, 0x83, 0xEC // SUB RSP, + }; + BYTE prolog64_2_pattern[] = { + 0x55, // PUSH RBP + 0x48, 0x8B, 0xEC // MOV RBP, RSP + }; + BYTE prolog64_3_pattern[] = { + 0x40, 0x55, // PUSH RBP + 0x48, 0x83, 0xEC // SUB RSP, + }; + BYTE prolog64_4_pattern[] = { + 0x53, // PUSH RBX + 0x48, 0x81, 0xEC // SUB RSP, + }; + BYTE prolog64_5_pattern[] = { + 0x48, 0x83, 0xE4, 0xF0 // AND rsp, FFFFFFFFFFFFFFF0; Align RSP to 16 bytes + }; + BYTE prolog64_6_pattern[] = { + 0x57, // PUSH RDI + 0x48, 0x89, 0xE7 // MOV RDI, RSP + }; + BYTE prolog64_7_pattern[] = { + 0x48, 0x8B, 0xC4, // MOV RAX, RSP + 0x48, 0x89, 0x58, 0x08, // MOV QWORD PTR [RAX + 8], RBX + 0x4C, 0x89, 0x48, 0x20, // MOV QWORD PTR [RAX + 0X20], R9 + 0x4C, 0x89, 0x40, 0x18, // MOV QWORD PTR [RAX + 0X18], R8 + 0x48, 0x89, 0x50, 0x10, // MOV QWORD PTR [RAX + 0X10], RDX + 0x55, // PUSH RBP + 0x56, // PUSH RSI + 0x57, // PUSH RDI + 0x41, 0x54, // PUSH R12 + 0x41, 0x55, // PUSH R13 + 0x41, 0x56, // PUSH R14 + 0x41, 0x57 // PUSH R15 + }; + + t_pattern patterns64[] = { + { prolog64_pattern, sizeof(prolog64_pattern) }, + { prolog64_2_pattern, sizeof(prolog64_2_pattern) }, + { prolog64_3_pattern, sizeof(prolog64_3_pattern) }, + { prolog64_4_pattern, sizeof(prolog64_4_pattern) }, + { prolog64_5_pattern, sizeof(prolog64_5_pattern) }, + { prolog64_6_pattern, sizeof(prolog64_6_pattern) }, + { prolog64_7_pattern, sizeof(prolog64_7_pattern) } + }; + +}; // namespace pesieve