_ads: functions now claim the instructions they explore

This commit is contained in:
Lephenixnoir 2022-04-06 12:15:34 +01:00
parent 8a2c67d83f
commit ee1c36db4e
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
3 changed files with 58 additions and 6 deletions

View File

@ -45,6 +45,7 @@
#define FXOS_PASSES_CFG_H
#include <fxos/disassembly.h>
#include <set>
namespace FxOS {
@ -54,9 +55,20 @@ public:
CfgPass(Disassembly &disasm);
bool analyzeInstruction(uint32_t pc, Instruction &inst) override;
/* Explore a new function at the specified address. This is a wrapper
around [analyzeFunction()] that creates the function. */
/* Explore a new function at the specified address. This method creates the
function if it doesn't exist yet, explores its CFG, and generates claims
over relevant parts of the binary. */
bool exploreFunction(uint32_t pc);
/* Access the set of claims generated by the last call to
exploreFunctions(). */
std::set<Claim> resultClaims();
private:
/* Last explored function */
uint32_t m_lastFunction;
/* Set of instructions in a function, used to generate new claims */
std::set<uint32_t> m_claimedInstructions;
};
} /* namespace FxOS */

View File

@ -13,7 +13,7 @@
namespace FxOS {
CfgPass::CfgPass(Disassembly &disasm):
InstructionPass(disasm)
InstructionPass(disasm), m_claimedInstructions {}
{
this->setAllowDiscovery(true);
}
@ -27,6 +27,8 @@ bool CfgPass::analyzeInstruction(uint32_t pc, Instruction &i)
return false;
}
m_claimedInstructions.insert(pc);
/* Compute the jump target for jump instructions. This is easy because
they are all trivially computable. (...If they are not we dub them
"terminal" to avoid the computation!) */
@ -93,6 +95,9 @@ bool CfgPass::analyzeInstruction(uint32_t pc, Instruction &i)
bool CfgPass::exploreFunction(uint32_t pc)
{
m_lastFunction = pc;
m_claimedInstructions.clear();
if(!m_disasm.hasFunctionAt(pc)) {
// TODO: Have proper function creation methods in Disassembly
Function func = { .address=pc, .callTargets={} };
@ -102,4 +107,34 @@ bool CfgPass::exploreFunction(uint32_t pc)
return this->analyzeFunction(pc);
}
std::set<Claim> CfgPass::resultClaims()
{
Claim base;
base.address = 0xffffffff;
base.size = 0;
base.type = Claim::Function;
base.owner = m_lastFunction;
std::set<Claim> set;
Claim c = base;
for(uint32_t pc: m_claimedInstructions) {
if(pc == c.address + c.size) {
c.size += 2;
}
else {
if(c.size > 0)
set.insert(c);
c = base;
c.address = pc;
c.size = 2;
}
}
if(c.size > 0)
set.insert(c);
return set;
}
} /* namespace FxOS */

View File

@ -246,9 +246,11 @@ static void ad_disassemble_all(VirtualSpace &space,
errors++;
if(!force) return;
}
else successes++;
/* TODO: Get subfunction addresses here */
else {
for(Claim const &c: cfg_pass.resultClaims())
space.disasm.addExclusiveClaim(c);
successes++;
}
}
timer.stop();
printf("\n");
@ -283,6 +285,9 @@ static void ad_disassemble_all(VirtualSpace &space,
printf("Successfully analyzed %d functions (%d errors)\n",
successes, errors);
/* TODO: Get subfunction addresses by abstract interpretation and keep
going recursively */
}
static std::vector<uint32_t> parse_ad(Session &session, Parser &parser)