1
0
Fork 0

DBG: FunctionPass mostly finished

This commit is contained in:
Nukem 2015-07-09 22:24:55 -04:00
parent 5f7c34f8aa
commit 37047a243c
1 changed files with 46 additions and 34 deletions

View File

@ -82,7 +82,7 @@ bool FunctionPass::Analyse()
// Memory allocation optimization // Memory allocation optimization
// TODO: Option to conserve memory // TODO: Option to conserve memory
threadFunctions[i].reserve(10000); threadFunctions[i].reserve(30000);
// Execute // Execute
AnalysisWorker(threadWorkStart, threadWorkStop, &threadFunctions[i]); AnalysisWorker(threadWorkStart, threadWorkStop, &threadFunctions[i]);
@ -97,14 +97,14 @@ bool FunctionPass::Analyse()
// Sort and remove duplicates // Sort and remove duplicates
std::sort(funcs.begin(), funcs.end()); std::sort(funcs.begin(), funcs.end());
funcs.erase(std::unique(funcs.begin(), funcs.end()), funcs.end()); funcs.erase(std::unique(funcs.begin(), funcs.end()), funcs.end());
/*
FunctionClear(); FunctionClear();
for(auto & func : funcs) for(auto & func : funcs)
{ {
FunctionAdd(func.VirtualStart, func.VirtualEnd - 1, true); FunctionAdd(func.VirtualStart, func.VirtualEnd - 1, true);
} }
GuiUpdateAllViews(); GuiUpdateAllViews();
*/
delete[] threadFunctions; delete[] threadFunctions;
return true; return true;
} }
@ -112,7 +112,7 @@ bool FunctionPass::Analyse()
void FunctionPass::AnalysisWorker(uint Start, uint End, std::vector<FunctionDef>* Blocks) void FunctionPass::AnalysisWorker(uint Start, uint End, std::vector<FunctionDef>* Blocks)
{ {
// Step 1: Use any defined functions in the PE function table // Step 1: Use any defined functions in the PE function table
//FindFunctionWorkerPrepass(Start, End, Blocks); FindFunctionWorkerPrepass(Start, End, Blocks);
// Step 2: for each block that contains a CALL flag, // Step 2: for each block that contains a CALL flag,
// add it to a local function start array // add it to a local function start array
@ -218,7 +218,7 @@ void FunctionPass::FindFunctionWorker(std::vector<FunctionDef>* Blocks)
auto ResolveFunctionEnd = [this](FunctionDef * Function, BasicBlock * LastBlock) auto ResolveFunctionEnd = [this](FunctionDef * Function, BasicBlock * LastBlock)
{ {
assert(Function->VirtualStart != 0); assert(Function->VirtualStart != 0);
Function->VirtualStart = 0x00007FF83B4315D0;
// Find the first basic block of the function // Find the first basic block of the function
BasicBlock* block = FindBBlockInRange(Function->VirtualStart); BasicBlock* block = FindBBlockInRange(Function->VirtualStart);
@ -236,53 +236,65 @@ void FunctionPass::FindFunctionWorker(std::vector<FunctionDef>* Blocks)
// Loop forever until the end is found // Loop forever until the end is found
for(; (uint)block <= (uint)LastBlock; block++) for(; (uint)block <= (uint)LastBlock; block++)
{ {
// Calculate max from just linear instructions // Block is now in use
maximumAddr = max(maximumAddr, block->VirtualEnd); block->SetFlag(BASIC_BLOCK_FLAG_FUNCTION);
// Each block has the potential to increase the // Calculate max from just linear instructions
// maximum function end address. maximumAddr = max(maximumAddr, block->VirtualEnd - 1);
// Find maximum jump target
if(!block->GetFlag(BASIC_BLOCK_FLAG_CALL) && !block->GetFlag(BASIC_BLOCK_FLAG_INDIRECT)) if(!block->GetFlag(BASIC_BLOCK_FLAG_CALL) && !block->GetFlag(BASIC_BLOCK_FLAG_INDIRECT))
{ {
// Here's a problem: Compilers add tail-call elimination with a jump. if(block->Target != 0)
// Solve this by creating a maximum jump limit: +/- 128 bytes from the end. {
if(abs((__int64)(block->VirtualEnd - block->Target)) <= 128) // Here's a problem: Compilers add tail-call elimination with a jump.
maximumAddr = max(maximumAddr, block->Target); // Solve this by creating a maximum jump limit: +/- 128 bytes from the end.
if(abs((__int64)(block->VirtualEnd - block->Target)) <= 512)
maximumAddr = max(maximumAddr, block->Target);
}
} }
// Does this node contain the maximum address? // Sanity check
if(block->VirtualStart > maximumAddr) assert(maximumAddr >= block->VirtualStart);
__debugbreak();
if(maximumAddr >= block->VirtualStart && maximumAddr <= block->VirtualEnd) // Does this node contain the maximum address?
if(maximumAddr >= block->VirtualStart && maximumAddr < block->VirtualEnd)
{ {
// It does! But does it end with a return statement? // It does! There's 4 possibilities next:
//
// 1. Return
// 2. Tail-call elimination
// 3. Optimized loop
// 4. Function continues to next block
//
// 1.
if(block->GetFlag(BASIC_BLOCK_FLAG_RET)) if(block->GetFlag(BASIC_BLOCK_FLAG_RET))
{ {
__test: __endfunc:
Function->VirtualEnd = block->VirtualEnd; Function->VirtualEnd = block->VirtualEnd;
Function->BBlockEnd = FindBBlockIndex(block); Function->BBlockEnd = FindBBlockIndex(block);
break; break;
} }
else
{
// It doesn't end with a return. There's 2 possibilities:
// tail-call elimination or an optimized loop.
if(abs((__int64)(block->VirtualEnd - block->Target)) > 128)
{
dprintf("Test: 0x%p\n", block->VirtualEnd);
}
goto __test; if(block->Target != 0)
{
// NOTE: Both must be an absolute jump
if(block->GetFlag(BASIC_BLOCK_FLAG_ABSJMP))
{
// 2.
if(abs((__int64)(block->VirtualEnd - block->Target)) > 128)
goto __endfunc;
// 3.
if(block->Target >= Function->VirtualStart && block->Target < block->VirtualEnd)
goto __endfunc;
}
} }
// 4. Just continue
} }
} }
dprintf("test - 0x%p 0x%p\n", Function->VirtualStart, Function->VirtualEnd);
// Set the flag for blocks that have been scanned
for(uint i = Function->BBlockStart; i < Function->BBlockEnd; i++)
m_MainBlocks[i].SetFlag(BASIC_BLOCK_FLAG_FUNCTION);
return true; return true;
}; };