From 92833475a33d2346d739a2403013896b117760b5 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sat, 8 Dec 2018 17:53:22 +0100 Subject: [PATCH 01/11] [REFACT] Search artefacts in a loop, till you find a matching set --- pe_sieve.h | 2 +- scanners/artefact_scanner.cpp | 117 ++++++++++++++++++++++------------ scanners/artefact_scanner.h | 8 ++- 3 files changed, 83 insertions(+), 44 deletions(-) diff --git a/pe_sieve.h b/pe_sieve.h index 4adb50846..5ec793ca4 100644 --- a/pe_sieve.h +++ b/pe_sieve.h @@ -8,7 +8,7 @@ #include "scanners/scan_report.h" #include "postprocessors/report_formatter.h" -static char PESIEVE_VERSION[] = "0.1.5.4-b"; +static char PESIEVE_VERSION[] = "0.1.5.4-e"; static DWORD PESIEVE_VERSION_ID = 0x00010504; // 00 01 05 04 static char PESIEVE_URL[] = "https://github.com/hasherezade/pe-sieve"; diff --git a/scanners/artefact_scanner.cpp b/scanners/artefact_scanner.cpp index d307fc772..95fcaf542 100644 --- a/scanners/artefact_scanner.cpp +++ b/scanners/artefact_scanner.cpp @@ -6,6 +6,20 @@ #include "peconv.h" #include "peconv/fix_imports.h" +#define INVALID_OFFSET (-1) + +size_t calc_offset(MemPageData &memPage, LPVOID field) +{ + if (!field) return INVALID_OFFSET; + + BYTE* loadedData = memPage.getLoadedData(); + size_t loadedSize = memPage.getLoadedSize(); + if (!peconv::validate_ptr(loadedData, loadedSize, field, sizeof(BYTE))) { + return INVALID_OFFSET; + } + return size_t((ULONG_PTR)field - (ULONG_PTR)loadedData); +} + bool is_valid_section(BYTE *loadedData, size_t loadedSize, BYTE *hdr_ptr, DWORD charact) { PIMAGE_SECTION_HEADER hdr_candidate = (PIMAGE_SECTION_HEADER) hdr_ptr; @@ -238,14 +252,19 @@ IMAGE_FILE_HEADER* ArtefactScanner::findNtFileHdr(BYTE* loadedData, size_t loade return reinterpret_cast(arch_ptr); } -IMAGE_DOS_HEADER* ArtefactScanner::findMzPeHeader(MemPageData &memPage) +IMAGE_DOS_HEADER* ArtefactScanner::findMzPeHeader(MemPageData &memPage, const size_t search_offset) { if (!memPage.load()) { return nullptr; } - const size_t scan_size = memPage.getLoadedSize(); - BYTE* buffer_ptr = memPage.getLoadedData(); - + if (memPage.getLoadedSize() <= search_offset) { + return nullptr; + } + const size_t scan_size = memPage.getLoadedSize() - search_offset; + BYTE* buffer_ptr = memPage.getLoadedData() + search_offset; + if (!peconv::validate_ptr(memPage.getLoadedData(), memPage.getLoadedSize(), buffer_ptr, scan_size)) { + return nullptr; + } const size_t minimal_size = sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER32); @@ -263,9 +282,9 @@ IMAGE_DOS_HEADER* ArtefactScanner::findMzPeHeader(MemPageData &memPage) return nullptr; } -bool ArtefactScanner::findMzPe(ArtefactScanner::ArtefactsMapping &aMap) +bool ArtefactScanner::findMzPe(ArtefactScanner::ArtefactsMapping &aMap, const size_t search_offset) { - IMAGE_DOS_HEADER* dos_hdr = findMzPeHeader(aMap.memPage); + IMAGE_DOS_HEADER* dos_hdr = findMzPeHeader(aMap.memPage, search_offset); if (!dos_hdr) { return false; } @@ -274,8 +293,6 @@ bool ArtefactScanner::findMzPe(ArtefactScanner::ArtefactsMapping &aMap) if (!peconv::validate_ptr(loadedData, loadedSize, dos_hdr, sizeof(IMAGE_DOS_HEADER))) { return false; } - aMap.pe_image_base = aMap.memPage.region_start + ((ULONGLONG)dos_hdr - (ULONGLONG)loadedData); - if (setMzPe(aMap, dos_hdr)) { aMap.isMzPeFound = true; } @@ -285,10 +302,13 @@ bool ArtefactScanner::findMzPe(ArtefactScanner::ArtefactsMapping &aMap) bool ArtefactScanner::setMzPe(ArtefactsMapping &aMap, IMAGE_DOS_HEADER* _dos_hdr) { if (!_dos_hdr) return false; - + + aMap.dos_hdr = _dos_hdr; BYTE* loadedData = aMap.memPage.getLoadedData(); size_t loadedSize = aMap.memPage.getLoadedSize(); + aMap.pe_image_base = aMap.memPage.region_start + ((ULONGLONG)aMap.dos_hdr - (ULONGLONG)loadedData); + IMAGE_NT_HEADERS32* pe_hdrs = (IMAGE_NT_HEADERS32*)((ULONGLONG)_dos_hdr + _dos_hdr->e_lfanew); if (!peconv::validate_ptr(loadedData, loadedSize, pe_hdrs, sizeof(IMAGE_NT_HEADERS32))) { return false; @@ -343,8 +363,7 @@ bool ArtefactScanner::setNtFileHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAG BYTE* loadedData = aMap.memPage.getLoadedData(); size_t loadedSize = aMap.memPage.getLoadedSize(); - size_t nt_offset = size_t((ULONGLONG)aMap.nt_file_hdr - (ULONGLONG)loadedData); - + size_t nt_offset = calc_offset(aMap.memPage, aMap.nt_file_hdr); //calculate sections header offset from FileHeader: const size_t headers_size = aMap.nt_file_hdr->SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER); size_t sec_hdr_offset = headers_size + nt_offset; @@ -352,12 +371,13 @@ bool ArtefactScanner::setNtFileHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAG if (!aMap.sec_hdr) { //sections headers are not set yet, try to detect them basing on File Header: IMAGE_SECTION_HEADER *sec_hdr = (IMAGE_SECTION_HEADER*)((ULONGLONG)loadedData + sec_hdr_offset); - setSecHdr(aMap, sec_hdr); + aMap.sec_hdr = sec_hdr; + //setSecHdr(aMap, sec_hdr); return true; } //validate sections headers: - size_t found_offset = (ULONGLONG)aMap.sec_hdr - (ULONGLONG)loadedData; - if (sec_hdr_offset != found_offset) { + size_t found_offset = calc_offset(aMap.memPage, aMap.sec_hdr); + if (found_offset != INVALID_OFFSET && sec_hdr_offset != found_offset) { aMap.nt_file_hdr = nullptr; //it has sections headers detected, but not validly aligned: std::cout << "[WARNING] Sections header misaligned with FileHeader. " @@ -402,35 +422,52 @@ PeArtefacts* ArtefactScanner::generateArtefacts(ArtefactScanner::ArtefactsMappin return peArt; } -PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage) +PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_offset) { - ArtefactsMapping aMap(memPage); - findMzPe(aMap); - - size_t max_section_search = memPage.getLoadedSize(); - size_t min_offset = 0; - if (aMap.nt_file_hdr) { - min_offset = (BYTE*)aMap.nt_file_hdr - memPage.getLoadedData(); - //don't search in full module, only in the first mem page: - max_section_search = PAGE_SIZE < memPage.getLoadedSize() ? PAGE_SIZE : memPage.getLoadedSize(); - } + std::cout << "findArtefacts" << std::endl; + const size_t step_size = sizeof(IMAGE_DOS_HEADER); - IMAGE_SECTION_HEADER *sec_hdr = findSectionsHdr(memPage, max_section_search, min_offset); - if (sec_hdr) { - setSecHdr(aMap, sec_hdr); - } + for (size_t min_offset = start_offset; min_offset < memPage.getLoadedSize(); ) + { + std::cout << "Searching DOS header, min_offset: " << std::hex << min_offset << std::endl; + ArtefactsMapping aMap(memPage); + if (findMzPe(aMap, min_offset)) { + size_t dos_offset = calc_offset(memPage, aMap.dos_hdr); + min_offset = dos_offset != INVALID_OFFSET ? dos_offset : min_offset; + std::cout << "Setting minOffset: " << std::hex << min_offset << std::endl; + } + size_t max_section_search = memPage.getLoadedSize(); + if (aMap.nt_file_hdr) { + size_t nt_offset = (BYTE*)aMap.nt_file_hdr - memPage.getLoadedData(); + if (nt_offset > min_offset) { + min_offset = nt_offset; + } + else { + std::cout << "Wrong NT offset: " << std::hex << nt_offset << " vs min_offset: " << min_offset << std::endl; + } + //don't search in full module, only in the first mem page: + max_section_search = PAGE_SIZE < memPage.getLoadedSize() ? PAGE_SIZE : memPage.getLoadedSize(); + } + IMAGE_SECTION_HEADER *sec_hdr = findSectionsHdr(memPage, max_section_search - min_offset, min_offset); + if (sec_hdr) { + setSecHdr(aMap, sec_hdr); + } - if (!aMap.foundAny()) { - //std::cout << "Not found!" << std::endl; - //neither sections header nor file header found - return nullptr; - } + if (!aMap.foundAny()) { + //neither sections header nor file header found + return nullptr; + } - //validate the header and search sections on its base: - setNtFileHdr(aMap, aMap.nt_file_hdr); + //validate the header and search sections on its base: + if (setNtFileHdr(aMap, aMap.nt_file_hdr)) { + // passed validation, generate aftefacts: + return generateArtefacts(aMap); + } + std::cout << "Validation failed, try another search...\n"; + min_offset += step_size; - //generate aftefacts: - return generateArtefacts(aMap); + } + return nullptr; } PeArtefacts* ArtefactScanner::findInPrevPages(ULONGLONG addr_start, ULONGLONG addr_stop) @@ -443,7 +480,7 @@ PeArtefacts* ArtefactScanner::findInPrevPages(ULONGLONG addr_start, ULONGLONG ad break; } this->prevMemPage = new MemPageData(this->processHandle, next_addr); - peArt = findArtefacts(*prevMemPage); + peArt = findArtefacts(*prevMemPage, 0); if (peArt) { break; } @@ -478,7 +515,7 @@ ArtefactScanReport* ArtefactScanner::scanRemote() ULONGLONG region_start = memPage.region_start; this->artPagePtr = &memPage; - PeArtefacts *peArt = findArtefacts(memPage); + PeArtefacts *peArt = findArtefacts(memPage, 0); if (!peArt && (region_start > memPage.alloc_base)) { peArt = findInPrevPages(memPage.alloc_base, memPage.region_start); if (prevMemPage) { diff --git a/scanners/artefact_scanner.h b/scanners/artefact_scanner.h index e9c137b77..2678b3ff6 100644 --- a/scanners/artefact_scanner.h +++ b/scanners/artefact_scanner.h @@ -145,6 +145,7 @@ class ArtefactScanner { memPage(_memPage) { pe_image_base = PE_NOT_FOUND; + dos_hdr = nullptr; nt_file_hdr = nullptr; sec_hdr = nullptr; isMzPeFound = false; @@ -160,6 +161,7 @@ class ArtefactScanner { MemPageData &memPage; ULONGLONG pe_image_base; + IMAGE_DOS_HEADER *dos_hdr; IMAGE_FILE_HEADER* nt_file_hdr; IMAGE_SECTION_HEADER* sec_hdr; bool isMzPeFound; @@ -174,13 +176,13 @@ class ArtefactScanner { bool hasShellcode(HMODULE region_start, size_t region_size, PeArtefacts &peArt); - bool findMzPe(ArtefactsMapping &mapping); + bool findMzPe(ArtefactsMapping &mapping, const size_t search_offset); bool setMzPe(ArtefactsMapping &mapping, IMAGE_DOS_HEADER* _dos_hdr); bool setSecHdr(ArtefactsMapping &mapping, IMAGE_SECTION_HEADER* _sec_hdr); bool setNtFileHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAGE_FILE_HEADER* _nt_hdr); PeArtefacts *generateArtefacts(ArtefactsMapping &aMap); - PeArtefacts* findArtefacts(MemPageData &memPage); + PeArtefacts* findArtefacts(MemPageData &memPage, size_t start_offset); PeArtefacts* findInPrevPages(ULONGLONG addr_start, ULONGLONG addr_stop); ULONGLONG calcPeBase(MemPageData &memPage, BYTE *hdr_ptr); @@ -189,7 +191,7 @@ class ArtefactScanner { IMAGE_FILE_HEADER* findNtFileHdr(BYTE* loadedData, size_t loadedSize); BYTE* findSecByPatterns(BYTE *search_ptr, const size_t max_search_size); IMAGE_SECTION_HEADER* findSectionsHdr(MemPageData &memPageData, const size_t max_search_size, const size_t search_offset); - IMAGE_DOS_HEADER* findMzPeHeader(MemPageData &memPage); + IMAGE_DOS_HEADER* findMzPeHeader(MemPageData &memPage, const size_t search_offset); HANDLE processHandle; MemPageData &memPage; From 312e7a4a436e0d7cedd9c4844e765fdbb7f029cd Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sat, 8 Dec 2018 20:36:34 +0100 Subject: [PATCH 02/11] [BUGFIX] Refactored conditions of setting SectionHeaders and FleHeader. Choose the best set of artefacts --- scanners/artefact_scanner.cpp | 112 +++++++++++++++++++--------------- scanners/artefact_scanner.h | 22 +++++++ 2 files changed, 85 insertions(+), 49 deletions(-) diff --git a/scanners/artefact_scanner.cpp b/scanners/artefact_scanner.cpp index 95fcaf542..21de9d0b5 100644 --- a/scanners/artefact_scanner.cpp +++ b/scanners/artefact_scanner.cpp @@ -6,8 +6,6 @@ #include "peconv.h" #include "peconv/fix_imports.h" -#define INVALID_OFFSET (-1) - size_t calc_offset(MemPageData &memPage, LPVOID field) { if (!field) return INVALID_OFFSET; @@ -20,6 +18,27 @@ size_t calc_offset(MemPageData &memPage, LPVOID field) return size_t((ULONG_PTR)field - (ULONG_PTR)loadedData); } +size_t calc_sec_hdrs_offset(MemPageData &memPage, IMAGE_FILE_HEADER* nt_file_hdr) +{ + const size_t headers_size = nt_file_hdr->SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER); + size_t nt_offset = calc_offset(memPage, nt_file_hdr); + size_t sec_hdr_offset = headers_size + nt_offset; + return sec_hdr_offset; +} + +bool validate_hdrs_alignment(MemPageData &memPage, IMAGE_FILE_HEADER *nt_file_hdr, IMAGE_SECTION_HEADER* _sec_hdr) +{ + if (!_sec_hdr) return false; + if (!nt_file_hdr) return false; + + size_t sec_offset_hdrs = calc_sec_hdrs_offset(memPage, nt_file_hdr); + size_t sec_offset = calc_offset(memPage, _sec_hdr); + if (sec_offset_hdrs != sec_offset) { + return false; + } + return true; +} + bool is_valid_section(BYTE *loadedData, size_t loadedSize, BYTE *hdr_ptr, DWORD charact) { PIMAGE_SECTION_HEADER hdr_candidate = (PIMAGE_SECTION_HEADER) hdr_ptr; @@ -325,27 +344,27 @@ bool ArtefactScanner::setSecHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAGE_S BYTE* loadedData = aMap.memPage.getLoadedData(); size_t loadedSize = aMap.memPage.getLoadedSize(); - // try to find NT header relative to the sections header: - size_t nt_hdr_search_bound = size_t((ULONGLONG)_sec_hdr - (ULONGLONG)loadedData); - - //search before sections header: - aMap.nt_file_hdr = findNtFileHdr(loadedData, nt_hdr_search_bound); - if (aMap.nt_file_hdr) { - //found relative NT file header before, validation passed - aMap.sec_hdr = _sec_hdr; - - if (!aMap.pe_image_base) { - aMap.pe_image_base = calcPeBase(memPage, (BYTE*)aMap.nt_file_hdr); - } - return true; - } - //validate by counting the sections: size_t count = count_section_hdrs(loadedData, loadedSize, _sec_hdr); if (count == 0) { // sections header didn't passed validation return false; } + //if NT headers not found, search before sections header: + if (!aMap.nt_file_hdr) { + // try to find NT header relative to the sections header: + size_t nt_hdr_search_bound = calc_offset(aMap.memPage, _sec_hdr); + if (nt_hdr_search_bound == INVALID_OFFSET) { + return false; + } + //TODO: make some minimal limit: + aMap.nt_file_hdr = findNtFileHdr(loadedData, nt_hdr_search_bound); + } + if (aMap.nt_file_hdr) { + if (!validate_hdrs_alignment(memPage, aMap.nt_file_hdr, _sec_hdr)) { + return false; + } + } aMap.sec_hdr = _sec_hdr; if (!aMap.pe_image_base) { aMap.pe_image_base = calcPeBase(memPage, (BYTE*)aMap.sec_hdr); @@ -365,23 +384,16 @@ bool ArtefactScanner::setNtFileHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAG size_t nt_offset = calc_offset(aMap.memPage, aMap.nt_file_hdr); //calculate sections header offset from FileHeader: - const size_t headers_size = aMap.nt_file_hdr->SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER); - size_t sec_hdr_offset = headers_size + nt_offset; - if (!aMap.sec_hdr) { - //sections headers are not set yet, try to detect them basing on File Header: - IMAGE_SECTION_HEADER *sec_hdr = (IMAGE_SECTION_HEADER*)((ULONGLONG)loadedData + sec_hdr_offset); - aMap.sec_hdr = sec_hdr; - //setSecHdr(aMap, sec_hdr); + // set sections headers basing on File Header, do not validate yet + size_t sec_hdr_offset = calc_sec_hdrs_offset(aMap.memPage, aMap.nt_file_hdr); + aMap.sec_hdr = (IMAGE_SECTION_HEADER*)((ULONGLONG)loadedData + sec_hdr_offset); return true; } - //validate sections headers: - size_t found_offset = calc_offset(aMap.memPage, aMap.sec_hdr); - if (found_offset != INVALID_OFFSET && sec_hdr_offset != found_offset) { - aMap.nt_file_hdr = nullptr; - //it has sections headers detected, but not validly aligned: - std::cout << "[WARNING] Sections header misaligned with FileHeader. " - << "Expected offset: " << std::hex << sec_hdr_offset << " vs found offset: " << found_offset << std::endl; + // sections headers were set before, validate if they match NT header: + if (!validate_hdrs_alignment(aMap.memPage, aMap.nt_file_hdr, aMap.sec_hdr)) { + aMap.nt_file_hdr = nullptr; // do not allow setting mismatching NT header + std::cout << "[WARNING] Sections header misaligned with FileHeader." << std::endl; return false; } //validation passed: @@ -403,13 +415,12 @@ PeArtefacts* ArtefactScanner::generateArtefacts(ArtefactScanner::ArtefactsMappin peArt->regionStart = memPage.region_start; peArt->isMzPeFound = aMap.isMzPeFound; - peArt->secHdrsOffset = size_t((ULONGLONG)aMap.sec_hdr - (ULONGLONG)loadedData); + peArt->secHdrsOffset = calc_offset(memPage, aMap.sec_hdr); peArt->secCount = count_section_hdrs(loadedData, loadedSize, aMap.sec_hdr); // if File Header found, use it to validate or find sections headers: - if (aMap.nt_file_hdr) { - peArt->ntFileHdrsOffset = size_t((ULONGLONG)aMap.nt_file_hdr - (ULONGLONG)loadedData);; - } + peArt->ntFileHdrsOffset = calc_offset(memPage, aMap.nt_file_hdr); + std::cout << "NT offset: " << std::hex << peArt->ntFileHdrsOffset << std::endl; if (!aMap.pe_image_base) { aMap.pe_image_base = calcPeBase(memPage, (BYTE*)aMap.sec_hdr); } @@ -424,12 +435,14 @@ PeArtefacts* ArtefactScanner::generateArtefacts(ArtefactScanner::ArtefactsMappin PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_offset) { - std::cout << "findArtefacts" << std::endl; const size_t step_size = sizeof(IMAGE_DOS_HEADER); + ArtefactsMapping bestMapping(memPage); + for (size_t min_offset = start_offset; min_offset < memPage.getLoadedSize(); ) { std::cout << "Searching DOS header, min_offset: " << std::hex << min_offset << std::endl; + ArtefactsMapping aMap(memPage); if (findMzPe(aMap, min_offset)) { size_t dos_offset = calc_offset(memPage, aMap.dos_hdr); @@ -438,8 +451,8 @@ PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_o } size_t max_section_search = memPage.getLoadedSize(); if (aMap.nt_file_hdr) { - size_t nt_offset = (BYTE*)aMap.nt_file_hdr - memPage.getLoadedData(); - if (nt_offset > min_offset) { + size_t nt_offset = calc_offset(memPage, aMap.nt_file_hdr); + if (nt_offset != INVALID_OFFSET && nt_offset > min_offset) { min_offset = nt_offset; } else { @@ -453,21 +466,22 @@ PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_o setSecHdr(aMap, sec_hdr); } - if (!aMap.foundAny()) { - //neither sections header nor file header found - return nullptr; - } - //validate the header and search sections on its base: - if (setNtFileHdr(aMap, aMap.nt_file_hdr)) { - // passed validation, generate aftefacts: - return generateArtefacts(aMap); + if (setNtFileHdr(aMap, aMap.nt_file_hdr) && setSecHdr(aMap, aMap.sec_hdr)) { + //valid PE found: + bestMapping = aMap; + break; } - std::cout << "Validation failed, try another search...\n"; - min_offset += step_size; + + bestMapping = (bestMapping < aMap) ? aMap : bestMapping; + if (!bestMapping.foundAny()) { + return nullptr; + } + min_offset++; } - return nullptr; + //use the best found set of artefacts: + return generateArtefacts(bestMapping); } PeArtefacts* ArtefactScanner::findInPrevPages(ULONGLONG addr_start, ULONGLONG addr_stop) diff --git a/scanners/artefact_scanner.h b/scanners/artefact_scanner.h index 2678b3ff6..2d667496f 100644 --- a/scanners/artefact_scanner.h +++ b/scanners/artefact_scanner.h @@ -159,6 +159,28 @@ class ArtefactScanner { return false; } + size_t getScore() const + { + size_t score = 0; + if (sec_hdr) score += 3; + if (nt_file_hdr) score += 2; + if (dos_hdr) score++; + return score; + } + + bool operator < (const ArtefactsMapping& map2) const { + return getScore() < map2.getScore(); + } + + ArtefactsMapping& operator = (const ArtefactsMapping& other) { + this->pe_image_base = other.pe_image_base; + this->dos_hdr = other.dos_hdr; + this->nt_file_hdr = other.nt_file_hdr; + this->sec_hdr = other.sec_hdr; + this->isMzPeFound = other.isMzPeFound; + return *this; + } + MemPageData &memPage; ULONGLONG pe_image_base; IMAGE_DOS_HEADER *dos_hdr; From 3ac9c99b892258b6646fff0d2d1df7cde36b1149 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sat, 8 Dec 2018 21:09:28 +0100 Subject: [PATCH 03/11] [BUGFIX] Break search when no artefacts found. Fixed min_offset --- scanners/artefact_scanner.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/scanners/artefact_scanner.cpp b/scanners/artefact_scanner.cpp index 21de9d0b5..21385fa13 100644 --- a/scanners/artefact_scanner.cpp +++ b/scanners/artefact_scanner.cpp @@ -347,6 +347,7 @@ bool ArtefactScanner::setSecHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAGE_S //validate by counting the sections: size_t count = count_section_hdrs(loadedData, loadedSize, _sec_hdr); if (count == 0) { + std::cout << "Sections count == 0\n"; // sections header didn't passed validation return false; } @@ -464,19 +465,25 @@ PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_o IMAGE_SECTION_HEADER *sec_hdr = findSectionsHdr(memPage, max_section_search - min_offset, min_offset); if (sec_hdr) { setSecHdr(aMap, sec_hdr); + size_t sec_offset = calc_offset(memPage, aMap.sec_hdr); + min_offset = (sec_offset != INVALID_OFFSET && min_offset > sec_offset) ? min_offset : sec_offset; } //validate the header and search sections on its base: - if (setNtFileHdr(aMap, aMap.nt_file_hdr) && setSecHdr(aMap, aMap.sec_hdr)) { - //valid PE found: - bestMapping = aMap; - break; + if (setNtFileHdr(aMap, aMap.nt_file_hdr)) { + if (setSecHdr(aMap, aMap.sec_hdr)) { + //valid PE found: + bestMapping = aMap; + break; + } else { + std::cout << "[WARNING] Sections header didn't pass validation\n"; + } } bestMapping = (bestMapping < aMap) ? aMap : bestMapping; - if (!bestMapping.foundAny()) { - return nullptr; + if (!aMap.foundAny()) { + break; } min_offset++; } From 0fb51f71e2b7410a82d8ad1a505f261cc5098235 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sun, 9 Dec 2018 00:54:10 +0100 Subject: [PATCH 04/11] [BUGFIX] Fixed wrong returned value in MemPageData::load --- scanners/mempage_data.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scanners/mempage_data.h b/scanners/mempage_data.h index ca408ffff..af948eb11 100644 --- a/scanners/mempage_data.h +++ b/scanners/mempage_data.h @@ -48,7 +48,7 @@ class MemPageData if (loadedData) { return true; } - return true; + return false; } bool hasMappedName(); From af10931ff4c6e9c3e4389bff8f85aa85a7a99534 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sun, 9 Dec 2018 00:55:08 +0100 Subject: [PATCH 05/11] [BUGFIX] Ensure the memory area is loaded before searching artefacts --- scanners/artefact_scanner.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scanners/artefact_scanner.cpp b/scanners/artefact_scanner.cpp index 21385fa13..1571aee10 100644 --- a/scanners/artefact_scanner.cpp +++ b/scanners/artefact_scanner.cpp @@ -436,7 +436,10 @@ PeArtefacts* ArtefactScanner::generateArtefacts(ArtefactScanner::ArtefactsMappin PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_offset) { - const size_t step_size = sizeof(IMAGE_DOS_HEADER); + if (!memPage.load()) { + std::cerr << "Cannot read memory page!\n"; + return nullptr; + } ArtefactsMapping bestMapping(memPage); From 1ef8128d6e29ff35afd3d7ab9ffd9474c6d362df Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sun, 9 Dec 2018 03:09:29 +0100 Subject: [PATCH 06/11] [REFACT] Implemented validatePtr in MemPageData --- scanners/artefact_scanner.cpp | 16 +++++++--------- scanners/mempage_data.h | 5 +++++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/scanners/artefact_scanner.cpp b/scanners/artefact_scanner.cpp index 1571aee10..b51a6925d 100644 --- a/scanners/artefact_scanner.cpp +++ b/scanners/artefact_scanner.cpp @@ -176,7 +176,7 @@ BYTE* ArtefactScanner::findSecByPatterns(BYTE *search_ptr, const size_t max_sear IMAGE_SECTION_HEADER* ArtefactScanner::findSectionsHdr(MemPageData &memPage, const size_t max_search_size, const size_t search_offset) { BYTE *search_ptr = search_offset + memPage.getLoadedData(); - if (!peconv::validate_ptr(memPage.getLoadedData(), memPage.getLoadedSize(), search_ptr, max_search_size)) { + if (!memPage.validatePtr(search_ptr, max_search_size)) { return nullptr; } BYTE *hdr_ptr = findSecByPatterns(search_ptr, max_search_size); @@ -281,7 +281,7 @@ IMAGE_DOS_HEADER* ArtefactScanner::findMzPeHeader(MemPageData &memPage, const si } const size_t scan_size = memPage.getLoadedSize() - search_offset; BYTE* buffer_ptr = memPage.getLoadedData() + search_offset; - if (!peconv::validate_ptr(memPage.getLoadedData(), memPage.getLoadedSize(), buffer_ptr, scan_size)) { + if (!memPage.validatePtr(buffer_ptr, scan_size)) { return nullptr; } const size_t minimal_size = sizeof(IMAGE_DOS_HEADER) @@ -307,9 +307,7 @@ bool ArtefactScanner::findMzPe(ArtefactScanner::ArtefactsMapping &aMap, const si if (!dos_hdr) { return false; } - BYTE* loadedData = aMap.memPage.getLoadedData(); - size_t loadedSize = aMap.memPage.getLoadedSize(); - if (!peconv::validate_ptr(loadedData, loadedSize, dos_hdr, sizeof(IMAGE_DOS_HEADER))) { + if (!aMap.memPage.validatePtr(dos_hdr, sizeof(IMAGE_DOS_HEADER))) { return false; } if (setMzPe(aMap, dos_hdr)) { @@ -323,13 +321,13 @@ bool ArtefactScanner::setMzPe(ArtefactsMapping &aMap, IMAGE_DOS_HEADER* _dos_hdr if (!_dos_hdr) return false; aMap.dos_hdr = _dos_hdr; - BYTE* loadedData = aMap.memPage.getLoadedData(); - size_t loadedSize = aMap.memPage.getLoadedSize(); - aMap.pe_image_base = aMap.memPage.region_start + ((ULONGLONG)aMap.dos_hdr - (ULONGLONG)loadedData); + size_t dos_hdr_offset = calc_offset(aMap.memPage, aMap.dos_hdr); + aMap.pe_image_base = aMap.memPage.region_start + dos_hdr_offset; IMAGE_NT_HEADERS32* pe_hdrs = (IMAGE_NT_HEADERS32*)((ULONGLONG)_dos_hdr + _dos_hdr->e_lfanew); - if (!peconv::validate_ptr(loadedData, loadedSize, pe_hdrs, sizeof(IMAGE_NT_HEADERS32))) { + if (!aMap.memPage.validatePtr(pe_hdrs, sizeof(IMAGE_NT_HEADERS32))) + { return false; } setNtFileHdr(aMap, &pe_hdrs->FileHeader); diff --git a/scanners/mempage_data.h b/scanners/mempage_data.h index af948eb11..d58d845ef 100644 --- a/scanners/mempage_data.h +++ b/scanners/mempage_data.h @@ -25,6 +25,11 @@ class MemPageData size_t getLoadedSize() { return loadedSize; } const PBYTE getLoadedData() { return loadedData; } + bool validatePtr(const LPVOID field_bgn, size_t field_size) + { + return peconv::validate_ptr(this->loadedData, this->loadedSize, field_bgn, field_size); + } + ULONGLONG start_va; // VA that was requested. May not be beginning of the region. DWORD protection; DWORD initial_protect; From fbb0d20290ff4c1527b79f97467f0e5e8039ec39 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sun, 9 Dec 2018 05:09:43 +0100 Subject: [PATCH 07/11] [FEATURE] Reconstruct erased SizeOfOptionalHeader --- pe_sieve.h | 2 +- postprocessors/pe_reconstructor.cpp | 7 ++++ scanners/artefact_scanner.cpp | 50 ++++++++++++++++++++++------- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/pe_sieve.h b/pe_sieve.h index 5ec793ca4..06f234d40 100644 --- a/pe_sieve.h +++ b/pe_sieve.h @@ -8,7 +8,7 @@ #include "scanners/scan_report.h" #include "postprocessors/report_formatter.h" -static char PESIEVE_VERSION[] = "0.1.5.4-e"; +static char PESIEVE_VERSION[] = "0.1.5.4-f"; static DWORD PESIEVE_VERSION_ID = 0x00010504; // 00 01 05 04 static char PESIEVE_URL[] = "https://github.com/hasherezade/pe-sieve"; diff --git a/postprocessors/pe_reconstructor.cpp b/postprocessors/pe_reconstructor.cpp index 42d0a360d..20799c0b5 100644 --- a/postprocessors/pe_reconstructor.cpp +++ b/postprocessors/pe_reconstructor.cpp @@ -127,6 +127,13 @@ bool PeReconstructor::reconstructPeHdr() //write signature: nt32->Signature = IMAGE_NT_SIGNATURE; + IMAGE_FILE_HEADER *file_hdr = &nt32->FileHeader; + + bool is64bit = (file_hdr->Machine == IMAGE_FILE_MACHINE_AMD64) ? true : false; + + if (nt32->FileHeader.SizeOfOptionalHeader == 0) { + nt32->FileHeader.SizeOfOptionalHeader = is64bit ? sizeof(IMAGE_OPTIONAL_HEADER64) : sizeof(IMAGE_OPTIONAL_HEADER32); + } LONG pe_offset = LONG((ULONGLONG)pe_ptr - (ULONGLONG)this->vBuf); IMAGE_DOS_HEADER* dosHdr = (IMAGE_DOS_HEADER*) vBuf; dosHdr->e_magic = IMAGE_DOS_SIGNATURE; diff --git a/scanners/artefact_scanner.cpp b/scanners/artefact_scanner.cpp index b51a6925d..ef6a3ba7d 100644 --- a/scanners/artefact_scanner.cpp +++ b/scanners/artefact_scanner.cpp @@ -20,7 +20,13 @@ size_t calc_offset(MemPageData &memPage, LPVOID field) size_t calc_sec_hdrs_offset(MemPageData &memPage, IMAGE_FILE_HEADER* nt_file_hdr) { - const size_t headers_size = nt_file_hdr->SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER); + size_t opt_hdr_size = nt_file_hdr->SizeOfOptionalHeader; + if (opt_hdr_size == 0) { + //try casual values + bool is64bit = (nt_file_hdr->Machine == IMAGE_FILE_MACHINE_AMD64) ? true : false; + opt_hdr_size = is64bit ? sizeof(IMAGE_OPTIONAL_HEADER64) : sizeof(IMAGE_OPTIONAL_HEADER32); + } + const size_t headers_size = opt_hdr_size + sizeof(IMAGE_FILE_HEADER); size_t nt_offset = calc_offset(memPage, nt_file_hdr); size_t sec_hdr_offset = headers_size + nt_offset; return sec_hdr_offset; @@ -213,18 +219,17 @@ bool is_valid_file_hdr(BYTE *loadedData, size_t loadedSize, BYTE *hdr_ptr, DWORD // wrong machine ID return false; } - - if (hdr_candidate->SizeOfOptionalHeader < opt_hdr_size) { - return false; - } if (hdr_candidate->SizeOfOptionalHeader > PAGE_SIZE) { return false; } if (!peconv::validate_ptr(loadedData, loadedSize, hdr_candidate, - sizeof(IMAGE_FILE_HEADER) + hdr_candidate->SizeOfOptionalHeader)) + sizeof(IMAGE_FILE_HEADER) + opt_hdr_size)) { return false; } + if (hdr_candidate->SizeOfOptionalHeader == opt_hdr_size) { + return true; + } //check characteristics: if (charact != 0 && (hdr_candidate->Characteristics & charact) == 0) { return false; @@ -256,6 +261,7 @@ IMAGE_FILE_HEADER* ArtefactScanner::findNtFileHdr(BYTE* loadedData, size_t loade } } if (!arch_ptr) { + std::cout << "No architecture pattern found...\n"; return nullptr; } DWORD charact = IMAGE_FILE_EXECUTABLE_IMAGE; @@ -265,6 +271,7 @@ IMAGE_FILE_HEADER* ArtefactScanner::findNtFileHdr(BYTE* loadedData, size_t loade else { charact |= IMAGE_FILE_LARGE_ADDRESS_AWARE; } + std::cout << "Found NT header, validating...\n"; if (!is_valid_file_hdr(loadedData, loadedSize, arch_ptr, charact)) { return nullptr; } @@ -345,19 +352,37 @@ bool ArtefactScanner::setSecHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAGE_S //validate by counting the sections: size_t count = count_section_hdrs(loadedData, loadedSize, _sec_hdr); if (count == 0) { - std::cout << "Sections count == 0\n"; + std::cout << "Sections header didn't passed validation\n"; // sections header didn't passed validation return false; } //if NT headers not found, search before sections header: if (!aMap.nt_file_hdr) { + std::cout << "Trying to find NT header\n"; // try to find NT header relative to the sections header: - size_t nt_hdr_search_bound = calc_offset(aMap.memPage, _sec_hdr); - if (nt_hdr_search_bound == INVALID_OFFSET) { + size_t sec_hdrs_start = calc_offset(aMap.memPage, _sec_hdr); + if (sec_hdrs_start == INVALID_OFFSET) { return false; } - //TODO: make some minimal limit: - aMap.nt_file_hdr = findNtFileHdr(loadedData, nt_hdr_search_bound); + //search till the valid header found: + for (size_t start_offset = 0; + start_offset < sec_hdrs_start; + start_offset += sizeof(IMAGE_FILE_HEADER)) + { + BYTE *search_ptr = loadedData + start_offset; + size_t search_size = sec_hdrs_start - start_offset; //must be before sections headers + IMAGE_FILE_HEADER* nt_file_hdr = findNtFileHdr(search_ptr, search_size); + if (!nt_file_hdr) { + std::cout << "Not found any, failure!\n"; + break; //not found any, break with failure + } + size_t nt_file_offset = calc_offset(memPage, nt_file_hdr); + std::cout << "Trying NT header at: " << std::hex << nt_file_offset << std::endl; + if (validate_hdrs_alignment(memPage, nt_file_hdr, _sec_hdr)) { + aMap.nt_file_hdr = nt_file_hdr; + break; //found valid one, break with success + } + } } if (aMap.nt_file_hdr) { if (!validate_hdrs_alignment(memPage, aMap.nt_file_hdr, _sec_hdr)) { @@ -480,6 +505,9 @@ PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_o std::cout << "[WARNING] Sections header didn't pass validation\n"; } } + else { + std::cout << "[WARNING] NT header didn't pass validation\n"; + } bestMapping = (bestMapping < aMap) ? aMap : bestMapping; From 5a815e971890c407ae5cda9c5f08a07a8aa44700 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Sun, 9 Dec 2018 21:32:30 +0100 Subject: [PATCH 08/11] [REFACT] Simplified searching NT header basing on sections header --- scanners/artefact_scanner.cpp | 47 ++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/scanners/artefact_scanner.cpp b/scanners/artefact_scanner.cpp index ef6a3ba7d..1be47bd85 100644 --- a/scanners/artefact_scanner.cpp +++ b/scanners/artefact_scanner.cpp @@ -32,6 +32,19 @@ size_t calc_sec_hdrs_offset(MemPageData &memPage, IMAGE_FILE_HEADER* nt_file_hdr return sec_hdr_offset; } +size_t calc_nt_hdr_offset(MemPageData &memPage, IMAGE_SECTION_HEADER* first_sec, bool is64bit = true) +{ + size_t sec_hdr_offset = calc_offset(memPage, first_sec); + if (sec_hdr_offset == INVALID_OFFSET) { + return INVALID_OFFSET; + } + size_t opt_hdr_size = is64bit ? sizeof(IMAGE_OPTIONAL_HEADER64) : sizeof(IMAGE_OPTIONAL_HEADER32); + const size_t headers_size = opt_hdr_size + sizeof(IMAGE_FILE_HEADER); + size_t nt_offset = sec_hdr_offset - headers_size; + return nt_offset; +} + + bool validate_hdrs_alignment(MemPageData &memPage, IMAGE_FILE_HEADER *nt_file_hdr, IMAGE_SECTION_HEADER* _sec_hdr) { if (!_sec_hdr) return false; @@ -360,34 +373,22 @@ bool ArtefactScanner::setSecHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAGE_S if (!aMap.nt_file_hdr) { std::cout << "Trying to find NT header\n"; // try to find NT header relative to the sections header: - size_t sec_hdrs_start = calc_offset(aMap.memPage, _sec_hdr); - if (sec_hdrs_start == INVALID_OFFSET) { + size_t sec_hdr_offset = calc_offset(aMap.memPage, _sec_hdr); + if (sec_hdr_offset == INVALID_OFFSET) { return false; } - //search till the valid header found: - for (size_t start_offset = 0; - start_offset < sec_hdrs_start; - start_offset += sizeof(IMAGE_FILE_HEADER)) - { - BYTE *search_ptr = loadedData + start_offset; - size_t search_size = sec_hdrs_start - start_offset; //must be before sections headers - IMAGE_FILE_HEADER* nt_file_hdr = findNtFileHdr(search_ptr, search_size); - if (!nt_file_hdr) { - std::cout << "Not found any, failure!\n"; - break; //not found any, break with failure - } - size_t nt_file_offset = calc_offset(memPage, nt_file_hdr); - std::cout << "Trying NT header at: " << std::hex << nt_file_offset << std::endl; - if (validate_hdrs_alignment(memPage, nt_file_hdr, _sec_hdr)) { - aMap.nt_file_hdr = nt_file_hdr; - break; //found valid one, break with success + std::cout << "Sections header at: " << std::hex << sec_hdr_offset << " passed validation\n"; + //if NT headers not found, search before sections header: + if (!aMap.nt_file_hdr) { + // try to find NT header relative to the sections header: + size_t suggested_offset = calc_nt_hdr_offset(aMap.memPage, _sec_hdr); + if (suggested_offset != INVALID_OFFSET) { + aMap.nt_file_hdr = findNtFileHdr(loadedData + suggested_offset, sec_hdr_offset - suggested_offset); } } } - if (aMap.nt_file_hdr) { - if (!validate_hdrs_alignment(memPage, aMap.nt_file_hdr, _sec_hdr)) { - return false; - } + if (aMap.nt_file_hdr && (ULONG_PTR)aMap.nt_file_hdr > (ULONG_PTR)_sec_hdr) { + return false; //misaligned } aMap.sec_hdr = _sec_hdr; if (!aMap.pe_image_base) { From a6c05323e57741b91b822ad948a428beb2323e81 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Mon, 10 Dec 2018 00:49:20 +0100 Subject: [PATCH 09/11] [REFACT] Refactored calcPeBase --- pe_sieve.h | 2 +- scanners/artefact_scanner.cpp | 21 ++++++++++----------- scanners/artefact_scanner.h | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/pe_sieve.h b/pe_sieve.h index 06f234d40..ddf12a597 100644 --- a/pe_sieve.h +++ b/pe_sieve.h @@ -8,7 +8,7 @@ #include "scanners/scan_report.h" #include "postprocessors/report_formatter.h" -static char PESIEVE_VERSION[] = "0.1.5.4-f"; +static char PESIEVE_VERSION[] = "0.1.5.4-g"; static DWORD PESIEVE_VERSION_ID = 0x00010504; // 00 01 05 04 static char PESIEVE_URL[] = "https://github.com/hasherezade/pe-sieve"; diff --git a/scanners/artefact_scanner.cpp b/scanners/artefact_scanner.cpp index 1be47bd85..8cd502070 100644 --- a/scanners/artefact_scanner.cpp +++ b/scanners/artefact_scanner.cpp @@ -99,18 +99,17 @@ size_t count_section_hdrs(BYTE *loadedData, size_t loadedSize, IMAGE_SECTION_HEA return counter; } -ULONGLONG ArtefactScanner::calcPeBase(MemPageData &memPage, BYTE *sec_hdr) +ULONGLONG ArtefactScanner::calcPeBase(MemPageData &memPage, LPVOID sec_hdr) { - ULONGLONG pe_base_offset = 0; - - ULONGLONG hdrs_offset = (ULONGLONG)sec_hdr - (ULONGLONG)memPage.getLoadedData(); - for (ULONGLONG offset = hdrs_offset; offset > PAGE_SIZE; offset -= PAGE_SIZE) { - pe_base_offset += PAGE_SIZE; + size_t hdrs_offset = calc_offset(memPage, sec_hdr); + if (hdrs_offset == INVALID_OFFSET) { + std::cout << "Invalid sec_hdr_offset\n"; + return 0; } - pe_base_offset += memPage.region_start; - return pe_base_offset; + size_t full_pages = hdrs_offset / PAGE_SIZE; + std::cout << "Full pages: " << std::dec << full_pages << std::endl; + return memPage.region_start + (full_pages * PAGE_SIZE); } - //calculate image size basing on the sizes of sections size_t ArtefactScanner::calcImageSize(MemPageData &memPage, IMAGE_SECTION_HEADER *hdr_ptr, ULONGLONG pe_image_base) { @@ -392,7 +391,7 @@ bool ArtefactScanner::setSecHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAGE_S } aMap.sec_hdr = _sec_hdr; if (!aMap.pe_image_base) { - aMap.pe_image_base = calcPeBase(memPage, (BYTE*)aMap.sec_hdr); + aMap.pe_image_base = calcPeBase(aMap.memPage, (BYTE*)aMap.sec_hdr); } return true; } @@ -447,7 +446,7 @@ PeArtefacts* ArtefactScanner::generateArtefacts(ArtefactScanner::ArtefactsMappin peArt->ntFileHdrsOffset = calc_offset(memPage, aMap.nt_file_hdr); std::cout << "NT offset: " << std::hex << peArt->ntFileHdrsOffset << std::endl; if (!aMap.pe_image_base) { - aMap.pe_image_base = calcPeBase(memPage, (BYTE*)aMap.sec_hdr); + aMap.pe_image_base = calcPeBase(aMap.memPage, (BYTE*)aMap.sec_hdr); } peArt->peBaseOffset = size_t(aMap.pe_image_base - memPage.region_start); peArt->calculatedImgSize = calcImageSize(memPage, aMap.sec_hdr, aMap.pe_image_base); diff --git a/scanners/artefact_scanner.h b/scanners/artefact_scanner.h index 2d667496f..12d343e6e 100644 --- a/scanners/artefact_scanner.h +++ b/scanners/artefact_scanner.h @@ -207,7 +207,7 @@ class ArtefactScanner { PeArtefacts* findArtefacts(MemPageData &memPage, size_t start_offset); PeArtefacts* findInPrevPages(ULONGLONG addr_start, ULONGLONG addr_stop); - ULONGLONG calcPeBase(MemPageData &memPage, BYTE *hdr_ptr); + ULONGLONG calcPeBase(MemPageData &memPage, LPVOID hdr_ptr); size_t calcImageSize(MemPageData &memPage, IMAGE_SECTION_HEADER *hdr_ptr, ULONGLONG pe_image_base); IMAGE_FILE_HEADER* findNtFileHdr(BYTE* loadedData, size_t loadedSize); From 17e2d60188e169b49d6b6d2f805073bbfb9fa2d6 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Mon, 10 Dec 2018 21:46:12 +0100 Subject: [PATCH 10/11] [REFACT] Small code cleanup --- scanners/artefact_scanner.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/scanners/artefact_scanner.cpp b/scanners/artefact_scanner.cpp index 8cd502070..778ddf87f 100644 --- a/scanners/artefact_scanner.cpp +++ b/scanners/artefact_scanner.cpp @@ -44,7 +44,6 @@ size_t calc_nt_hdr_offset(MemPageData &memPage, IMAGE_SECTION_HEADER* first_sec, return nt_offset; } - bool validate_hdrs_alignment(MemPageData &memPage, IMAGE_FILE_HEADER *nt_file_hdr, IMAGE_SECTION_HEADER* _sec_hdr) { if (!_sec_hdr) return false; @@ -101,6 +100,7 @@ size_t count_section_hdrs(BYTE *loadedData, size_t loadedSize, IMAGE_SECTION_HEA ULONGLONG ArtefactScanner::calcPeBase(MemPageData &memPage, LPVOID sec_hdr) { + //WARNING: this will be inacurate in cases if the PE is not aligned to the beginning of the page size_t hdrs_offset = calc_offset(memPage, sec_hdr); if (hdrs_offset == INVALID_OFFSET) { std::cout << "Invalid sec_hdr_offset\n"; @@ -110,6 +110,7 @@ ULONGLONG ArtefactScanner::calcPeBase(MemPageData &memPage, LPVOID sec_hdr) std::cout << "Full pages: " << std::dec << full_pages << std::endl; return memPage.region_start + (full_pages * PAGE_SIZE); } + //calculate image size basing on the sizes of sections size_t ArtefactScanner::calcImageSize(MemPageData &memPage, IMAGE_SECTION_HEADER *hdr_ptr, ULONGLONG pe_image_base) { @@ -417,6 +418,7 @@ bool ArtefactScanner::setNtFileHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAG // sections headers were set before, validate if they match NT header: if (!validate_hdrs_alignment(aMap.memPage, aMap.nt_file_hdr, aMap.sec_hdr)) { aMap.nt_file_hdr = nullptr; // do not allow setting mismatching NT header + std::cout << "[WARNING] Sections header misaligned with FileHeader." << std::endl; return false; } @@ -466,7 +468,7 @@ PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_o ArtefactsMapping bestMapping(memPage); - for (size_t min_offset = start_offset; min_offset < memPage.getLoadedSize(); ) + for (size_t min_offset = start_offset; min_offset < memPage.getLoadedSize(); min_offset++) { std::cout << "Searching DOS header, min_offset: " << std::hex << min_offset << std::endl; @@ -482,9 +484,6 @@ PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_o if (nt_offset != INVALID_OFFSET && nt_offset > min_offset) { min_offset = nt_offset; } - else { - std::cout << "Wrong NT offset: " << std::hex << nt_offset << " vs min_offset: " << min_offset << std::endl; - } //don't search in full module, only in the first mem page: max_section_search = PAGE_SIZE < memPage.getLoadedSize() ? PAGE_SIZE : memPage.getLoadedSize(); } @@ -492,7 +491,7 @@ PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_o if (sec_hdr) { setSecHdr(aMap, sec_hdr); size_t sec_offset = calc_offset(memPage, aMap.sec_hdr); - min_offset = (sec_offset != INVALID_OFFSET && min_offset > sec_offset) ? min_offset : sec_offset; + if (sec_offset != INVALID_OFFSET) min_offset = sec_offset; } //validate the header and search sections on its base: @@ -511,10 +510,8 @@ PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_o bestMapping = (bestMapping < aMap) ? aMap : bestMapping; - if (!aMap.foundAny()) { - break; - } - min_offset++; + //do not continue the search if no artefacts found: + if (!aMap.foundAny()) break; } //use the best found set of artefacts: return generateArtefacts(bestMapping); From 384391838b6646d39a8b035a07c1c75258dde458 Mon Sep 17 00:00:00 2001 From: hasherezade Date: Mon, 10 Dec 2018 21:51:47 +0100 Subject: [PATCH 11/11] [REFACT] Commented out debug strings --- scanners/artefact_scanner.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/scanners/artefact_scanner.cpp b/scanners/artefact_scanner.cpp index 778ddf87f..79c93fbe1 100644 --- a/scanners/artefact_scanner.cpp +++ b/scanners/artefact_scanner.cpp @@ -73,10 +73,10 @@ bool is_valid_section(BYTE *loadedData, size_t loadedSize, BYTE *hdr_ptr, DWORD } if (charact != 0 && (hdr_candidate->Characteristics & charact) == 0) { // required characteristics not found - //std::cout << "The section " << hdr_candidate->Name << " NOT valid, charact:" << std::hex << hdr_candidate->Characteristics << std::endl; + ////std::cout << "The section " << hdr_candidate->Name << " NOT valid, charact:" << std::hex << hdr_candidate->Characteristics << std::endl; return false; } - //std::cout << "The section " << hdr_candidate->Name << " is valid!" << std::endl; + ////std::cout << "The section " << hdr_candidate->Name << " is valid!" << std::endl; return true; } @@ -103,11 +103,11 @@ ULONGLONG ArtefactScanner::calcPeBase(MemPageData &memPage, LPVOID sec_hdr) //WARNING: this will be inacurate in cases if the PE is not aligned to the beginning of the page size_t hdrs_offset = calc_offset(memPage, sec_hdr); if (hdrs_offset == INVALID_OFFSET) { - std::cout << "Invalid sec_hdr_offset\n"; + //std::cout << "Invalid sec_hdr_offset\n"; return 0; } size_t full_pages = hdrs_offset / PAGE_SIZE; - std::cout << "Full pages: " << std::dec << full_pages << std::endl; + //std::cout << "Full pages: " << std::dec << full_pages << std::endl; return memPage.region_start + (full_pages * PAGE_SIZE); } @@ -134,7 +134,7 @@ size_t ArtefactScanner::calcImageSize(MemPageData &memPage, IMAGE_SECTION_HEADER size_t last_sec_size = fetch_region_size(processHandle, (PBYTE)last_sec_va); size_t total_size = max_addr + last_sec_size; #ifdef _DEBUG - std::cout << "Total Size:" << std::hex << total_size << std::endl; + //std::cout << "Total Size:" << std::hex << total_size << std::endl; #endif return total_size; } @@ -274,7 +274,7 @@ IMAGE_FILE_HEADER* ArtefactScanner::findNtFileHdr(BYTE* loadedData, size_t loade } } if (!arch_ptr) { - std::cout << "No architecture pattern found...\n"; + //std::cout << "No architecture pattern found...\n"; return nullptr; } DWORD charact = IMAGE_FILE_EXECUTABLE_IMAGE; @@ -284,7 +284,7 @@ IMAGE_FILE_HEADER* ArtefactScanner::findNtFileHdr(BYTE* loadedData, size_t loade else { charact |= IMAGE_FILE_LARGE_ADDRESS_AWARE; } - std::cout << "Found NT header, validating...\n"; + //std::cout << "Found NT header, validating...\n"; if (!is_valid_file_hdr(loadedData, loadedSize, arch_ptr, charact)) { return nullptr; } @@ -365,19 +365,19 @@ bool ArtefactScanner::setSecHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAGE_S //validate by counting the sections: size_t count = count_section_hdrs(loadedData, loadedSize, _sec_hdr); if (count == 0) { - std::cout << "Sections header didn't passed validation\n"; + //std::cout << "Sections header didn't passed validation\n"; // sections header didn't passed validation return false; } //if NT headers not found, search before sections header: if (!aMap.nt_file_hdr) { - std::cout << "Trying to find NT header\n"; + //std::cout << "Trying to find NT header\n"; // try to find NT header relative to the sections header: size_t sec_hdr_offset = calc_offset(aMap.memPage, _sec_hdr); if (sec_hdr_offset == INVALID_OFFSET) { return false; } - std::cout << "Sections header at: " << std::hex << sec_hdr_offset << " passed validation\n"; + //std::cout << "Sections header at: " << std::hex << sec_hdr_offset << " passed validation\n"; //if NT headers not found, search before sections header: if (!aMap.nt_file_hdr) { // try to find NT header relative to the sections header: @@ -419,7 +419,7 @@ bool ArtefactScanner::setNtFileHdr(ArtefactScanner::ArtefactsMapping &aMap, IMAG if (!validate_hdrs_alignment(aMap.memPage, aMap.nt_file_hdr, aMap.sec_hdr)) { aMap.nt_file_hdr = nullptr; // do not allow setting mismatching NT header - std::cout << "[WARNING] Sections header misaligned with FileHeader." << std::endl; + //std::cout << "[WARNING] Sections header misaligned with FileHeader." << std::endl; return false; } //validation passed: @@ -446,7 +446,7 @@ PeArtefacts* ArtefactScanner::generateArtefacts(ArtefactScanner::ArtefactsMappin // if File Header found, use it to validate or find sections headers: peArt->ntFileHdrsOffset = calc_offset(memPage, aMap.nt_file_hdr); - std::cout << "NT offset: " << std::hex << peArt->ntFileHdrsOffset << std::endl; + //std::cout << "NT offset: " << std::hex << peArt->ntFileHdrsOffset << std::endl; if (!aMap.pe_image_base) { aMap.pe_image_base = calcPeBase(aMap.memPage, (BYTE*)aMap.sec_hdr); } @@ -470,13 +470,13 @@ PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_o for (size_t min_offset = start_offset; min_offset < memPage.getLoadedSize(); min_offset++) { - std::cout << "Searching DOS header, min_offset: " << std::hex << min_offset << std::endl; + //std::cout << "Searching DOS header, min_offset: " << std::hex << min_offset << std::endl; ArtefactsMapping aMap(memPage); if (findMzPe(aMap, min_offset)) { size_t dos_offset = calc_offset(memPage, aMap.dos_hdr); min_offset = dos_offset != INVALID_OFFSET ? dos_offset : min_offset; - std::cout << "Setting minOffset: " << std::hex << min_offset << std::endl; + //std::cout << "Setting minOffset: " << std::hex << min_offset << std::endl; } size_t max_section_search = memPage.getLoadedSize(); if (aMap.nt_file_hdr) { @@ -501,11 +501,11 @@ PeArtefacts* ArtefactScanner::findArtefacts(MemPageData &memPage, size_t start_o bestMapping = aMap; break; } else { - std::cout << "[WARNING] Sections header didn't pass validation\n"; + //std::cout << "[WARNING] Sections header didn't pass validation\n"; } } else { - std::cout << "[WARNING] NT header didn't pass validation\n"; + //std::cout << "[WARNING] NT header didn't pass validation\n"; } bestMapping = (bestMapping < aMap) ? aMap : bestMapping;