_ads: functions now claim the instructions they explore
This commit is contained in:
parent
8a2c67d83f
commit
ee1c36db4e
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
11
shell/a.cpp
11
shell/a.cpp
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue