1
0
Fork 0
x64dbg/x64_dbg_dbg/AnalysisPass.cpp

95 lines
2.2 KiB
C++

#include <assert.h>
#include <thread>
#include "AnalysisPass.h"
#include "memory.h"
AnalysisPass::AnalysisPass(uint VirtualStart, uint VirtualEnd, BBlockArray & MainBlocks) : m_MainBlocks(MainBlocks)
{
assert(VirtualEnd > VirtualStart);
// Internal class data
m_VirtualStart = VirtualStart;
m_VirtualEnd = VirtualEnd;
m_InternalMaxThreads = 0;
// Read remote instruction data to local memory
m_DataSize = VirtualEnd - VirtualStart;
m_Data = (unsigned char*)BridgeAlloc(m_DataSize);
if(!MemRead(VirtualStart, m_Data, m_DataSize, nullptr))
{
BridgeFree(m_Data);
assert(false);
}
}
AnalysisPass::~AnalysisPass()
{
if(m_Data)
BridgeFree(m_Data);
}
BasicBlock* AnalysisPass::FindBBlockInRange(uint Address)
{
// NOTE: __MUST__ BE A SORTED VECTOR
//
// Use a binary search
uint indexLo = 0;
uint indexHi = m_MainBlocks.size();
// Get a pointer to pure data
const auto blocks = m_MainBlocks.data();
while(indexHi > indexLo)
{
uint indexMid = (indexLo + indexHi) / 2;
auto entry = &blocks[indexMid];
if(Address < entry->VirtualStart)
{
// Continue search in lower half
indexHi = indexMid;
}
else if(Address >= entry->VirtualEnd)
{
// Continue search in upper half
indexLo = indexMid + 1;
}
else
{
// Address is within limits, return entry
return entry;
}
}
// Not found
return nullptr;
}
uint AnalysisPass::FindBBlockIndex(BasicBlock* Block)
{
// Fast pointer arithmetic to find index
return ((uint)Block - (uint)m_MainBlocks.data()) / sizeof(BasicBlock);
}
uint AnalysisPass::IdealThreadCount()
{
if(m_InternalMaxThreads == 0)
{
// Determine the maximum hardware thread count at once
uint maximumThreads = max(std::thread::hardware_concurrency(), 1);
// Don't consume 100% of the CPU, adjust accordingly
if(maximumThreads > 1)
maximumThreads -= 1;
SetIdealThreadCount(maximumThreads);
}
return m_InternalMaxThreads;
}
void AnalysisPass::SetIdealThreadCount(uint Count)
{
m_InternalMaxThreads = (BYTE)min(Count, 255);
}