mirror of
https://github.com/hasherezade/pe-sieve
synced 2026-06-08 14:34:52 +00:00
[FEATURE] In Thread Scan: report all suspicious areas, dump only the strongest candidate (#135)
* [FEATURE] In thread scan: store multiple suspicious areas * [REFACT] Minimize VirtualQueryEx on suspicious area: reuse stored * [BUGFIX] Fixed the report formatting * [FEATURE] Changed formatting of suspicious areas in the JSON * [BUGFIX] Fixed scoring the results * [BUGFIX] Fixed Debug build. Changed adding indicators to the report * [BUGFIX] Added exclusion for syscall integrity check. Changes in report filtering * Small fix in the json reporting of suspected addresses Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
+93
-54
@@ -11,6 +11,7 @@
|
||||
extern pesieve::SyscallTable g_SyscallTable;
|
||||
|
||||
#define ENTROPY_THRESHOLD 3.0
|
||||
#define ENTROPY_ENC_THRESHOLD 6.0
|
||||
//#define NO_ENTROPY_CHECK
|
||||
|
||||
#ifdef _DEBUG
|
||||
@@ -185,6 +186,11 @@ bool pesieve::ThreadScanner::checkReturnAddrIntegrity(IN const std::vector<ULONG
|
||||
}
|
||||
|
||||
if (this->info.ext.wait_reason == UserRequest) {
|
||||
if (syscallFuncName.rfind("NtDxgkGet", 0) == 0 &&
|
||||
lastFuncCalled.rfind("NtWaitFor", 0) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (syscallFuncName.find("WaitFor", 0) != std::string::npos &&
|
||||
(lastFuncCalled.find("WaitFor", 0) != std::string::npos))
|
||||
{
|
||||
@@ -568,37 +574,45 @@ void pesieve::ThreadScanner::printThreadInfo(const pesieve::util::thread_info& t
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
bool pesieve::ThreadScanner::fillAreaStats(ThreadScanReport* my_report)
|
||||
bool pesieve::ThreadScanner::fillAreaStats(SuspAddrReport* report)
|
||||
{
|
||||
if (!my_report) return false;
|
||||
if (!report) return false;
|
||||
|
||||
ULONG_PTR end_va = (ULONG_PTR)my_report->module + my_report->moduleSize;
|
||||
MemPageData mem(this->processHandle, this->isReflection, (ULONG_PTR)my_report->module, end_va);
|
||||
ULONG_PTR end_va = (ULONG_PTR)report->module + report->moduleSize;
|
||||
MemPageData mem(this->processHandle, this->isReflection, (ULONG_PTR)report->module, end_va);
|
||||
if (!mem.fillInfo() || !mem.load()) {
|
||||
return false;
|
||||
}
|
||||
my_report->is_code = util::is_code(mem.loadedData.getData(true), mem.loadedData.getDataSize(true));
|
||||
report->is_code = util::is_code(mem.loadedData.getData(true), mem.loadedData.getDataSize(true));
|
||||
AreaStatsCalculator calc(mem.loadedData);
|
||||
return calc.fill(my_report->stats, nullptr);
|
||||
return calc.fill(report->stats, nullptr);
|
||||
}
|
||||
|
||||
bool pesieve::ThreadScanner::reportSuspiciousAddr(ThreadScanReport* my_report, ULONGLONG susp_addr)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION page_info = { 0 };
|
||||
if (!get_page_details(processHandle, (LPVOID)susp_addr, page_info)) {
|
||||
SuspAddrReport* susRep = my_report->findAreaForAddress(susp_addr);
|
||||
if (!susRep) {
|
||||
MEMORY_BASIC_INFORMATION page_info = { 0 };
|
||||
if (!get_page_details(processHandle, (LPVOID)susp_addr, page_info)) {
|
||||
return false;
|
||||
}
|
||||
if (!(page_info.State & MEM_COMMIT)) {
|
||||
return false;
|
||||
}
|
||||
ULONGLONG base = (ULONGLONG)page_info.BaseAddress;
|
||||
susRep = new SuspAddrReport(base, page_info.RegionSize, page_info.AllocationProtect);
|
||||
susRep->curr_protection = page_info.Protect;
|
||||
my_report->suspAreaReports[base] = susRep;
|
||||
fillAreaStats(susRep);
|
||||
}
|
||||
if (!susRep) {
|
||||
return false;
|
||||
}
|
||||
if (!(page_info.State & MEM_COMMIT)) {
|
||||
return false;
|
||||
}
|
||||
ULONGLONG base = (ULONGLONG)page_info.BaseAddress;
|
||||
my_report->module = (HMODULE)base;
|
||||
my_report->moduleSize = page_info.RegionSize;
|
||||
my_report->alloc_protection = page_info.AllocationProtect;
|
||||
my_report->curr_protection = page_info.Protect;
|
||||
my_report->susp_addr = susp_addr;
|
||||
susRep->addSuspAddr(susp_addr);
|
||||
#ifdef _DEBUG
|
||||
susRep->print();
|
||||
#endif //_DEBUG
|
||||
my_report->status = SCAN_SUSPICIOUS;
|
||||
fillAreaStats(my_report);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -640,9 +654,7 @@ bool pesieve::ThreadScanner::scanRemoteThreadCtx(HANDLE hThread, ThreadScanRepor
|
||||
if (is_unnamed) {
|
||||
my_report.indicators.insert(THI_SUS_IP);
|
||||
if (reportSuspiciousAddr(&my_report, cDetails.rip)) {
|
||||
if (my_report.status == SCAN_SUSPICIOUS) {
|
||||
my_report.indicators.insert(THI_SUS_CALLSTACK_SHC);
|
||||
}
|
||||
my_report.indicators.insert(THI_SUS_CALLSTACK_SHC);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,18 +665,10 @@ bool pesieve::ThreadScanner::scanRemoteThreadCtx(HANDLE hThread, ThreadScanRepor
|
||||
#endif //_SHOW_THREAD_INFO
|
||||
//automatically verifies if the address is legit:
|
||||
if (reportSuspiciousAddr(&my_report, addr)) {
|
||||
if (my_report.status == SCAN_SUSPICIOUS) {
|
||||
my_report.indicators.insert(THI_SUS_CALLSTACK_SHC);
|
||||
my_report.indicators.insert(THI_SUS_CALLSTACK_SHC);
|
||||
#ifdef _DEBUG
|
||||
std::cout << "[@]" << std::dec << tid << " : " << "Suspicious, possible shc: " << std::hex << addr << " Entropy: " << std::dec << my_report.stats.entropy << " : " << my_report.is_code << std::endl;
|
||||
std::cout << "[@]" << std::dec << tid << " : " << "Suspicious, possible shc: " << std::hex << addr << std::endl;
|
||||
#endif //_DEBUG
|
||||
if (my_report.is_code) {
|
||||
break;
|
||||
}
|
||||
#ifdef _SHOW_THREAD_INFO
|
||||
std::cout << "Found! " << std::hex << addr << "\n";
|
||||
#endif //_SHOW_THREAD_INFO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,18 +681,11 @@ bool pesieve::ThreadScanner::scanRemoteThreadCtx(HANDLE hThread, ThreadScanRepor
|
||||
std::cout << "Return addr: " << std::hex << ret_addr << "\n";
|
||||
printResolvedAddr(ret_addr);
|
||||
#endif //_SHOW_THREAD_INFO
|
||||
if (is_unnamed && reportSuspiciousAddr(&my_report, (ULONGLONG)ret_addr)) {
|
||||
if (is_unnamed) {
|
||||
my_report.indicators.insert(THI_SUS_RET);
|
||||
if (my_report.status == SCAN_SUSPICIOUS) {
|
||||
if (reportSuspiciousAddr(&my_report, (ULONGLONG)ret_addr)) {
|
||||
my_report.indicators.insert(THI_SUS_CALLSTACK_SHC);
|
||||
}
|
||||
else {
|
||||
my_report.status = SCAN_SUSPICIOUS;
|
||||
if (my_report.stats.entropy < 1) { // discard, do not dump
|
||||
my_report.module = 0;
|
||||
my_report.moduleSize = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,7 +722,7 @@ bool pesieve::ThreadScanner::filterDotNet(ThreadScanReport& my_report)
|
||||
switch (indicator) {
|
||||
case THI_SUS_CALLSTACK_SHC:
|
||||
case THI_SUS_IP:
|
||||
case THI_SUS_RET:
|
||||
case THI_SUS_START:
|
||||
dnet_common++;
|
||||
break;
|
||||
default:
|
||||
@@ -739,6 +736,25 @@ bool pesieve::ThreadScanner::filterDotNet(ThreadScanReport& my_report)
|
||||
return false;
|
||||
}
|
||||
|
||||
static int scoreArea(const SuspAddrReport& area)
|
||||
{
|
||||
int score = 0;
|
||||
|
||||
if (area.is_code) {
|
||||
score += 10;
|
||||
}
|
||||
|
||||
if (area.stats.isFilled()) {
|
||||
if (area.stats.entropy >= ENTROPY_THRESHOLD) {
|
||||
score += 10;
|
||||
}
|
||||
if (area.stats.entropy >= ENTROPY_ENC_THRESHOLD) {
|
||||
score += 10;
|
||||
}
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
bool pesieve::ThreadScanner::assessIndicators(HANDLE hThread, ThreadScanReport& my_report)
|
||||
{
|
||||
if (my_report.status == SCAN_NOT_SUSPICIOUS) {
|
||||
@@ -748,9 +764,31 @@ bool pesieve::ThreadScanner::assessIndicators(HANDLE hThread, ThreadScanReport&
|
||||
my_report.status = SCAN_NOT_SUSPICIOUS;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (filterDotNet(my_report)) {
|
||||
return true;
|
||||
}
|
||||
ULONGLONG best_base = 0;
|
||||
size_t best_module_size = 0;
|
||||
int best_score = 0;
|
||||
double best_entropy = 0;
|
||||
for (auto itr1 = my_report.suspAreaReports.begin(); itr1 != my_report.suspAreaReports.end(); ++itr1) {
|
||||
ULONGLONG base = itr1->first;
|
||||
const SuspAddrReport* rep = itr1->second;
|
||||
if (!rep) continue;
|
||||
|
||||
const int score = scoreArea(*rep);
|
||||
if (score == 0) continue;
|
||||
|
||||
if (score > best_score
|
||||
|| (score == best_score && rep->stats.entropy > best_entropy))
|
||||
{
|
||||
best_base = rep->module;
|
||||
best_module_size = rep->moduleSize;
|
||||
best_score = score;
|
||||
best_entropy = rep->stats.entropy;
|
||||
}
|
||||
}
|
||||
|
||||
std::set< ThSusIndicator> validatedIndicators;
|
||||
for (auto itr = my_report.indicators.begin();
|
||||
@@ -758,23 +796,25 @@ bool pesieve::ThreadScanner::assessIndicators(HANDLE hThread, ThreadScanReport&
|
||||
++itr)
|
||||
{
|
||||
const ThSusIndicator& indicator = *itr;
|
||||
|
||||
if (!my_report.susp_addr) {
|
||||
validatedIndicators.insert(indicator);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (my_report.stats.isFilled()
|
||||
&& my_report.stats.entropy >= ENTROPY_THRESHOLD)
|
||||
{
|
||||
switch (indicator) {
|
||||
case THI_SUS_START:
|
||||
case THI_SUS_CALLSTACK_SHC:
|
||||
if (best_base) {
|
||||
validatedIndicators.insert(indicator);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
validatedIndicators.insert(indicator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!validatedIndicators.size()) {
|
||||
my_report.status = SCAN_NOT_SUSPICIOUS;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
my_report.module = (HMODULE)best_base;
|
||||
my_report.moduleSize = best_module_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
void pesieve::ThreadScanner::initReport(ThreadScanReport& my_report)
|
||||
@@ -817,10 +857,9 @@ ThreadScanReport* pesieve::ThreadScanner::scanRemote()
|
||||
|
||||
bool is_unnamed = !isAddrInNamedModule(info.start_addr);
|
||||
if (is_unnamed) {
|
||||
my_report->indicators.insert(THI_SUS_START);
|
||||
if (reportSuspiciousAddr(my_report, info.start_addr)) {
|
||||
if (my_report->status == SCAN_SUSPICIOUS) {
|
||||
my_report->indicators.insert(THI_SUS_START);
|
||||
}
|
||||
my_report->indicators.insert(THI_SUS_CALLSTACK_SHC);
|
||||
}
|
||||
}
|
||||
if (!should_scan_context(info)) {
|
||||
|
||||
+159
-46
@@ -66,6 +66,114 @@ namespace pesieve {
|
||||
|
||||
} ctx_details;
|
||||
|
||||
class SuspAddrReport {
|
||||
public:
|
||||
SuspAddrReport(ULONGLONG _module = 0 , size_t _moduleSize = 0, DWORD _allocProtection = 0)
|
||||
: module(_module), moduleSize(_moduleSize),
|
||||
alloc_protection(_allocProtection), curr_protection(0),
|
||||
is_code(false)
|
||||
{
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
std::cout << __FUNCTION__ << " : " << std::hex << module << " : " << moduleSize
|
||||
<< " alloc_protect: " << alloc_protection
|
||||
<< " curr_protect: " << curr_protection
|
||||
<< " is_code: " << is_code
|
||||
<< " entropy: " << stats.entropy
|
||||
<< " susp_addr [";
|
||||
for (auto itr = suspAddresses.begin(); itr != suspAddresses.end(); ++itr) {
|
||||
ULONGLONG susp_addr = *itr;
|
||||
std::cout << " " << susp_addr;
|
||||
}
|
||||
std::cout << " ]" << std::endl;
|
||||
}
|
||||
|
||||
const bool toJSON(std::stringstream& outs, size_t level, const pesieve::t_json_level& jdetails) const
|
||||
{
|
||||
if (addressesToJSON(outs, level, jdetails)) {
|
||||
outs << ",\n";
|
||||
}
|
||||
moduleInfoToJSON(outs, level, jdetails);
|
||||
return true;
|
||||
}
|
||||
|
||||
void addSuspAddr(ULONGLONG addr)
|
||||
{
|
||||
this->suspAddresses.insert(addr);
|
||||
}
|
||||
|
||||
bool addressesToJSON(std::stringstream& outs, size_t level, const pesieve::t_json_level& jdetails) const
|
||||
{
|
||||
if (!suspAddresses.size()) {
|
||||
return false;
|
||||
}
|
||||
std::string addrTypeStr = "susp_return_addr";
|
||||
if (this->module && this->moduleSize) {
|
||||
addrTypeStr = "susp_addr";
|
||||
}
|
||||
OUT_PADDED(outs, level, "\"" << addrTypeStr << "\" : [");
|
||||
OUT_PADDED(outs, level, "\"" << addrTypeStr << "\" : [");
|
||||
bool isFirst = true;
|
||||
for (auto itr = suspAddresses.begin(); itr != suspAddresses.end(); ++itr) {
|
||||
ULONGLONG susp_addr = *itr;
|
||||
if (!susp_addr) continue;
|
||||
|
||||
if (!isFirst) {
|
||||
outs << ", ";
|
||||
}
|
||||
outs << "\"" << std::hex << susp_addr << "\"";
|
||||
isFirst = false;
|
||||
}
|
||||
outs << "]";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool moduleInfoToJSON(std::stringstream& outs, size_t level, const pesieve::t_json_level& jdetails) const
|
||||
{
|
||||
if (!this->module) {
|
||||
return false;
|
||||
}
|
||||
OUT_PADDED(outs, level, "\"module\" : ");
|
||||
outs << "\"" << std::hex << (ULONGLONG)module << "\"";
|
||||
if (moduleSize) {
|
||||
outs << ",\n";
|
||||
OUT_PADDED(outs, level, "\"module_size\" : ");
|
||||
outs << "\"" << std::hex << (ULONGLONG)moduleSize << "\"";
|
||||
}
|
||||
outs << ",\n";
|
||||
if (alloc_protection != curr_protection) {
|
||||
OUT_PADDED(outs, level, "\"alloc_protection\" : ");
|
||||
outs << "\"" << std::hex << alloc_protection << "\"";
|
||||
outs << ",\n";
|
||||
OUT_PADDED(outs, level, "\"curr_protection\" : ");
|
||||
outs << "\"" << std::hex << curr_protection << "\"";
|
||||
}
|
||||
else {
|
||||
OUT_PADDED(outs, level, "\"protection\" : ");
|
||||
outs << "\"" << std::hex << curr_protection << "\"";
|
||||
}
|
||||
outs << ",\n";
|
||||
OUT_PADDED(outs, level, "\"is_code\" : ");
|
||||
outs << "\"" << std::dec << is_code << "\"";
|
||||
if (stats.isFilled()) {
|
||||
outs << ",\n";
|
||||
stats.toJSON(outs, level);
|
||||
}
|
||||
outs << "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
ULONG_PTR module;
|
||||
size_t moduleSize;
|
||||
std::set<ULONGLONG> suspAddresses;
|
||||
DWORD alloc_protection;
|
||||
DWORD curr_protection;
|
||||
AreaEntropyStats stats;
|
||||
bool is_code;
|
||||
};
|
||||
|
||||
//! A report from the thread scan, generated by ThreadScanner
|
||||
class ThreadScanReport : public ModuleScanReport
|
||||
{
|
||||
@@ -80,13 +188,37 @@ namespace pesieve {
|
||||
|
||||
ThreadScanReport(DWORD _tid)
|
||||
: ModuleScanReport(0, 0),
|
||||
tid(_tid),
|
||||
susp_addr(0), alloc_protection(0), curr_protection(0), stack_ptr(0),
|
||||
tid(_tid), stack_ptr(0),
|
||||
thread_state(THREAD_STATE_UNKNOWN),
|
||||
thread_wait_reason(0), thread_wait_time(0), is_code(false)
|
||||
thread_wait_reason(0), thread_wait_time(0)
|
||||
{
|
||||
}
|
||||
|
||||
~ThreadScanReport()
|
||||
{
|
||||
for (auto itr = this->suspAreaReports.begin(); itr != this->suspAreaReports.end(); ++itr) {
|
||||
SuspAddrReport* rep = itr->second;
|
||||
delete rep;
|
||||
}
|
||||
suspAreaReports.clear();
|
||||
}
|
||||
|
||||
SuspAddrReport* findAreaForAddress(const ULONGLONG &susp_addr)
|
||||
{
|
||||
auto found = this->suspAreaReports.find(susp_addr);
|
||||
if (found != this->suspAreaReports.end()) {
|
||||
return found->second;
|
||||
}
|
||||
for (auto itr = this->suspAreaReports.begin(); itr != this->suspAreaReports.end(); ++itr) {
|
||||
SuspAddrReport* rep = itr->second;
|
||||
if (!rep) continue;
|
||||
if (susp_addr >= rep->module && susp_addr < (rep->module + rep->moduleSize)) {
|
||||
return rep;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const virtual void callstackToJSON(std::stringstream& outs, size_t level, const pesieve::t_json_level& jdetails)
|
||||
{
|
||||
bool printCallstack = (jdetails >= JSON_DETAILS) ? true : false;
|
||||
@@ -113,42 +245,18 @@ namespace pesieve {
|
||||
outs << "\"" << std::hex << addr;
|
||||
auto sItr = this->addrToSymbol.find(addr);
|
||||
if (sItr != this->addrToSymbol.end()) {
|
||||
outs << ";" << sItr->second;
|
||||
const std::string &sym = sItr->second;
|
||||
if (!sym.empty()) {
|
||||
outs << ";" << sym;
|
||||
}
|
||||
}
|
||||
outs << "\"";
|
||||
|
||||
}
|
||||
outs << "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool moduleInfoToJSON(std::stringstream& outs, size_t level, const pesieve::t_json_level& jdetails)
|
||||
{
|
||||
if (!this->module) {
|
||||
return false;
|
||||
}
|
||||
outs << ",\n";
|
||||
OUT_PADDED(outs, level, "\"module\" : ");
|
||||
outs << "\"" << std::hex << (ULONGLONG)module << "\"";
|
||||
if (moduleSize) {
|
||||
outs << ",\n";
|
||||
OUT_PADDED(outs, level, "\"module_size\" : ");
|
||||
outs << "\"" << std::hex << (ULONGLONG)moduleSize << "\"";
|
||||
}
|
||||
outs << ",\n";
|
||||
OUT_PADDED(outs, level, "\"alloc_protection\" : ");
|
||||
outs << "\"" << std::hex << alloc_protection << "\"";
|
||||
outs << ",\n";
|
||||
OUT_PADDED(outs, level, "\"curr_protection\" : ");
|
||||
outs << "\"" << std::hex << curr_protection << "\"";
|
||||
if (stats.isFilled()) {
|
||||
outs << ",\n";
|
||||
stats.toJSON(outs, level);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool threadInfoToJSON(std::stringstream& outs, size_t level, const pesieve::t_json_level& jdetails)
|
||||
{
|
||||
OUT_PADDED(outs, level, "\"state\" : ");
|
||||
@@ -218,17 +326,27 @@ namespace pesieve {
|
||||
outs << ",\n";
|
||||
indicatorsToJSON(outs, level, jdetails);
|
||||
|
||||
if (susp_addr) {
|
||||
if (!suspAreaReports.empty()) {
|
||||
outs << ",\n";
|
||||
if (this->module && this->moduleSize) {
|
||||
OUT_PADDED(outs, level, "\"susp_addr\" : ");
|
||||
OUT_PADDED(outs, level, "\"susp_areas\" : [\n");
|
||||
|
||||
bool isFirst = true;
|
||||
for (const auto& entry : suspAreaReports) {
|
||||
const SuspAddrReport* suspr = entry.second;
|
||||
if (!suspr) {
|
||||
continue;
|
||||
}
|
||||
if (!isFirst) {
|
||||
outs << ",\n";
|
||||
}
|
||||
OUT_PADDED(outs, level + 1, "{\n");
|
||||
suspr->toJSON(outs, level + 2, jdetails);
|
||||
OUT_PADDED(outs, level + 1, "}");
|
||||
isFirst = false;
|
||||
}
|
||||
else {
|
||||
OUT_PADDED(outs, level, "\"susp_return_addr\" : ");
|
||||
}
|
||||
outs << "\"" << std::hex << susp_addr << "\"";
|
||||
outs << "\n";
|
||||
OUT_PADDED(outs, level, "]");
|
||||
}
|
||||
moduleInfoToJSON(outs, level, jdetails);
|
||||
}
|
||||
|
||||
const virtual bool toJSON(std::stringstream& outs, size_t level, const pesieve::t_json_level &jdetails)
|
||||
@@ -241,9 +359,6 @@ namespace pesieve {
|
||||
}
|
||||
|
||||
DWORD tid;
|
||||
ULONGLONG susp_addr;
|
||||
DWORD alloc_protection;
|
||||
DWORD curr_protection;
|
||||
ULONGLONG stack_ptr;
|
||||
DWORD thread_state;
|
||||
DWORD thread_wait_reason;
|
||||
@@ -256,9 +371,7 @@ namespace pesieve {
|
||||
std::map<ULONGLONG, std::string> addrToSymbol;
|
||||
std::set<ULONGLONG> shcCandidates;
|
||||
std::set<ThSusIndicator> indicators;
|
||||
|
||||
AreaEntropyStats stats;
|
||||
bool is_code;
|
||||
std::map<ULONGLONG, SuspAddrReport*> suspAreaReports;
|
||||
};
|
||||
|
||||
//! A scanner for threads
|
||||
@@ -292,7 +405,7 @@ namespace pesieve {
|
||||
|
||||
bool checkReturnAddrIntegrity(IN const std::vector<ULONGLONG>& callStack, IN OUT ThreadScanReport& my_report);
|
||||
|
||||
bool fillAreaStats(ThreadScanReport* my_report);
|
||||
bool fillAreaStats(SuspAddrReport* my_report);
|
||||
bool reportSuspiciousAddr(ThreadScanReport* my_report, ULONGLONG susp_addr);
|
||||
bool filterDotNet(ThreadScanReport& my_report);
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace pesieve {
|
||||
double entropy;
|
||||
|
||||
protected:
|
||||
const virtual void fieldsToJSON(std::stringstream& outs, size_t level)
|
||||
virtual void fieldsToJSON(std::stringstream& outs, size_t level) const
|
||||
{
|
||||
OUT_PADDED(outs, level, "\"area_start\" : ");
|
||||
outs << "\"" << std::hex << area_start << "\"";
|
||||
|
||||
+2
-2
@@ -129,7 +129,7 @@ namespace pesieve {
|
||||
lastStr.clear();
|
||||
}
|
||||
|
||||
const virtual void fieldsToJSON(std::stringstream& outs, size_t level)
|
||||
virtual void fieldsToJSON(std::stringstream& outs, size_t level) const
|
||||
{
|
||||
OUT_PADDED(outs, level, "\"offset\" : ");
|
||||
outs << std::hex << "\"" << offset << "\"";
|
||||
@@ -208,7 +208,7 @@ namespace pesieve {
|
||||
return true;
|
||||
}
|
||||
|
||||
const virtual void fieldsToJSON(std::stringstream& outs, size_t level)
|
||||
virtual void fieldsToJSON(std::stringstream& outs, size_t level) const
|
||||
{
|
||||
OUT_PADDED(outs, level, "\"full_area\" : {\n");
|
||||
currArea.fieldsToJSON(outs, level + 1);
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@ namespace pesieve {
|
||||
area_size++;
|
||||
}
|
||||
|
||||
const virtual void fieldsToJSON(std::stringstream& outs, size_t level) = 0;
|
||||
virtual void fieldsToJSON(std::stringstream& outs, size_t level) const = 0;
|
||||
|
||||
bool isFilled() const
|
||||
{
|
||||
@@ -46,7 +46,7 @@ namespace pesieve {
|
||||
|
||||
virtual bool fillSettings(StatsSettings* _settings) { return false; }
|
||||
|
||||
const virtual bool toJSON(std::stringstream& outs, size_t level)
|
||||
virtual bool toJSON(std::stringstream& outs, size_t level) const
|
||||
{
|
||||
if (!isFilled()) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user