Skip to content

Commit 6a26c69

Browse files
committed
Supply ABB inputs in BNBasicBlockAnalysisContext
1 parent 424774b commit 6a26c69

File tree

5 files changed

+52
-128
lines changed

5 files changed

+52
-128
lines changed

architecture.cpp

Lines changed: 25 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -308,12 +308,12 @@ bool Architecture::GetInstructionLowLevelILCallback(
308308
}
309309

310310

311-
bool Architecture::AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function,
312-
bool incrementalUpdate, BNFunctionAnalysisSkipOverride analysisSkipOverride)
311+
void Architecture::AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function,
312+
BNBasicBlockAnalysisContext* context)
313313
{
314314
CallbackRef<Architecture> arch(ctxt);
315315
Ref<Function> func(new Function(BNNewFunctionReference(function)));
316-
return arch->AnalyzeBasicBlocks(*func, incrementalUpdate, analysisSkipOverride);
316+
arch->AnalyzeBasicBlocks(*func, context);
317317
}
318318

319319

@@ -983,36 +983,20 @@ static bool GetNextFunctionAfterAddress(Ref<BinaryView> data, Ref<Platform> plat
983983
}
984984

985985

986-
bool Architecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate, BNFunctionAnalysisSkipOverride analysisSkipOverride)
986+
void Architecture::AnalyzeBasicBlocks(Function& function, BNBasicBlockAnalysisContext* context)
987987
{
988988
auto data = function.GetView();
989989
queue<ArchAndAddr> blocksToProcess;
990990
map<ArchAndAddr, Ref<BasicBlock>> instrBlocks;
991991
set<ArchAndAddr> seenBlocks;
992-
993-
// TODO - we might just want to create a generic analysis settings object that includes all of these
994-
//bool tailCallTranslation = function.GetSettingsCache()->Get<bool>("core.function.translateTailCalls");
995-
bool tailCallTranslation = true;
996-
//bool disallowBranchToString = owner->IsDisallowBranchToStringEnabled();
997-
bool disallowBranchToString = false;
998-
999-
// TODO: add an API for querying ONLY the indirect branches that are auto-defined
1000-
auto indirectBranches = function.GetAutoIndirectBranches();
1001-
map<ArchAndAddr, set<ArchAndAddr>> autoIndirectBranches;
1002-
for (auto& branchInfo : indirectBranches)
1003-
{
1004-
auto sourceLocation = ArchAndAddr(branchInfo.sourceArch, branchInfo.sourceAddr);
1005-
auto destLocation = ArchAndAddr(branchInfo.destArch, branchInfo.destAddr);
1006-
autoIndirectBranches[sourceLocation].insert(destLocation);
1007-
}
1008-
1009-
map<ArchAndAddr, set<ArchAndAddr>> userIndirectBranches;
1010-
indirectBranches = function.GetUserIndirectBranches();
1011-
for (auto& branchInfo : indirectBranches)
992+
map<ArchAndAddr, set<ArchAndAddr>> indirectBranches;
993+
for (size_t i = 0; i < context->indirectBranchesCount; i++)
1012994
{
1013-
auto sourceLocation = ArchAndAddr(branchInfo.sourceArch, branchInfo.sourceAddr);
1014-
auto destLocation = ArchAndAddr(branchInfo.destArch, branchInfo.destAddr);
1015-
userIndirectBranches[sourceLocation].insert(destLocation);
995+
auto sourceLocation = ArchAndAddr(new CoreArchitecture(context->indirectBranches[i].sourceArch),
996+
context->indirectBranches[i].sourceAddr);
997+
auto destLocation = ArchAndAddr(new CoreArchitecture(context->indirectBranches[i].destArch),
998+
context->indirectBranches[i].destAddr);
999+
indirectBranches[sourceLocation].insert(destLocation);
10161000
}
10171001

10181002
BNStringReference strRef;
@@ -1091,11 +1075,11 @@ bool Architecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate
10911075
}
10921076

10931077
uint64_t totalSize = 0;
1094-
uint64_t maxSize = data->GetMaxFunctionSizeForAnalysis();
1078+
uint64_t maxSize = context->maxFunctionSize;
10951079
while (blocksToProcess.size() != 0)
10961080
{
10971081
if (data->AnalysisIsAborted())
1098-
return true;
1082+
return;
10991083

11001084
// Get the next block to process
11011085
ArchAndAddr location = blocksToProcess.front();
@@ -1120,7 +1104,7 @@ bool Architecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate
11201104
while (true)
11211105
{
11221106
if (data->AnalysisIsAborted())
1123-
return true;
1107+
return;
11241108

11251109
if (!delaySlotCount)
11261110
{
@@ -1298,7 +1282,7 @@ bool Architecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate
12981282
function.AddDirectCodeReference(location, info.branchTarget[i]);
12991283

13001284
auto otherFunc = function.GetCalleeForAnalysis(targetPlatform, target.address, true);
1301-
if (tailCallTranslation && targetPlatform && otherFunc && (otherFunc->GetStart() != function.GetStart()))
1285+
if (context->translateTailCalls && targetPlatform && otherFunc && (otherFunc->GetStart() != function.GetStart()))
13021286
{
13031287
calledFunctions.insert(otherFunc);
13041288
if (info.branchType[i] == UnconditionalBranch)
@@ -1313,7 +1297,7 @@ bool Architecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate
13131297
break;
13141298
}
13151299
}
1316-
else if (disallowBranchToString && data->GetStringAtAddress(location.address, strRef) && targetExceedsByteLimit(strRef))
1300+
else if (context->disallowBranchToString && data->GetStringAtAddress(location.address, strRef) && targetExceedsByteLimit(strRef))
13171301
{
13181302
BNLogInfo("Not adding branch target from 0x%" PRIx64 " to string at 0x%" PRIx64
13191303
" length:%zu",
@@ -1433,15 +1417,8 @@ bool Architecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate
14331417
}
14341418
}
14351419

1436-
indirectBranchIter = userIndirectBranches.find(location);
1437-
endIter = userIndirectBranches.end();
1438-
1439-
if (indirectBranchIter == endIter)
1440-
{
1441-
indirectBranchIter = autoIndirectBranches.find(location);
1442-
endIter = autoIndirectBranches.end();
1443-
}
1444-
1420+
indirectBranchIter = indirectBranches.find(location);
1421+
endIter = indirectBranches.end();
14451422
if (indirectBranchIter != endIter)
14461423
{
14471424
for (auto& branch : indirectBranchIter->second)
@@ -1452,7 +1429,7 @@ bool Architecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate
14521429
targetPlatform = funcPlatform->GetRelatedPlatform(branch.arch);
14531430

14541431
// Normal analysis should not inline indirect targets that are function starts
1455-
if (tailCallTranslation && data->GetAnalysisFunction(targetPlatform, branch.address))
1432+
if (context->translateTailCalls && data->GetAnalysisFunction(targetPlatform, branch.address))
14561433
continue;
14571434

14581435
block->AddPendingOutgoingEdge(IndirectBranch, branch.address, branch.arch);
@@ -1539,10 +1516,10 @@ bool Architecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate
15391516
// We prefer to allow disassembly when function analysis is disabled, but only up to the maximum size.
15401517
// The log message and tag are generated in ProcessAnalysisSkip
15411518
totalSize += info.length;
1542-
if (analysisSkipOverride == NeverSkipFunctionAnalysis)
1519+
if (context->analysisSkipOverride == NeverSkipFunctionAnalysis)
15431520
maxSize = 0;
1544-
else if (!maxSize && (analysisSkipOverride == AlwaysSkipFunctionAnalysis))
1545-
maxSize = data->GetMaxFunctionSizeForAnalysis();
1521+
else if (!maxSize && (context->analysisSkipOverride == AlwaysSkipFunctionAnalysis))
1522+
maxSize = context->maxFunctionSize;
15461523
if (maxSize && (totalSize > maxSize))
15471524
break;
15481525

@@ -1558,7 +1535,7 @@ bool Architecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate
15581535
delayInstructionEndsBlock = endsBlock;
15591536
}
15601537

1561-
if (block->CanExit() && tailCallTranslation && !delaySlotCount && hasNextFunc && (location.address == nextFuncAddr))
1538+
if (block->CanExit() && context->translateTailCalls && !delaySlotCount && hasNextFunc && (location.address == nextFuncAddr))
15621539
{
15631540
// Falling through into another function. Don't consider this a tail call if the current block
15641541
// called the function, as this indicates a get PC construct.
@@ -1587,7 +1564,6 @@ bool Architecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate
15871564

15881565
// Finalize the function basic block list
15891566
function.FinalizeBasicBlocks();
1590-
return true;
15911567
}
15921568

15931569

@@ -2151,10 +2127,9 @@ bool CoreArchitecture::GetInstructionLowLevelIL(const uint8_t* data, uint64_t ad
21512127
}
21522128

21532129

2154-
bool CoreArchitecture::AnalyzeBasicBlocks(Function& function, bool incrementalUpdate,
2155-
BNFunctionAnalysisSkipOverride analysisSkipOverride)
2130+
void CoreArchitecture::AnalyzeBasicBlocks(Function& function, BNBasicBlockAnalysisContext* context)
21562131
{
2157-
return BNArchitectureAnalyzeBasicBlocks(m_object, function.GetObject(), incrementalUpdate, analysisSkipOverride);
2132+
BNArchitectureAnalyzeBasicBlocks(m_object, function.GetObject(), context);
21582133
}
21592134

21602135

binaryninjaapi.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8064,8 +8064,7 @@ namespace BinaryNinja {
80648064
static void FreeInstructionTextCallback(BNInstructionTextToken* tokens, size_t count);
80658065
static bool GetInstructionLowLevelILCallback(
80668066
void* ctxt, const uint8_t* data, uint64_t addr, size_t* len, BNLowLevelILFunction* il);
8067-
static bool AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function, bool incrementalUpdate,
8068-
BNFunctionAnalysisSkipOverride analysisSkipOverride);
8067+
static void AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function, BNBasicBlockAnalysisContext* context);
80698068
static char* GetRegisterNameCallback(void* ctxt, uint32_t reg);
80708069
static char* GetFlagNameCallback(void* ctxt, uint32_t flag);
80718070
static char* GetFlagWriteTypeNameCallback(void* ctxt, uint32_t flags);
@@ -8236,8 +8235,7 @@ namespace BinaryNinja {
82368235
*/
82378236
virtual bool GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il);
82388237

8239-
virtual bool AnalyzeBasicBlocks(Function& function, bool incrementalUpdate,
8240-
BNFunctionAnalysisSkipOverride analysisSkipOverride);
8238+
virtual void AnalyzeBasicBlocks(Function& function, BNBasicBlockAnalysisContext* context);
82418239

82428240
/*! Gets a register name from a register index.
82438241

@@ -8632,8 +8630,7 @@ namespace BinaryNinja {
86328630
const uint8_t* data, uint64_t addr, size_t& len, std::vector<InstructionTextToken>& result) override;
86338631
virtual bool GetInstructionLowLevelIL(
86348632
const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il) override;
8635-
virtual bool AnalyzeBasicBlocks(Function& function, bool incrementalUpdate,
8636-
BNFunctionAnalysisSkipOverride analysisSkipOverride) override;
8633+
virtual void AnalyzeBasicBlocks(Function& function, BNBasicBlockAnalysisContext* context) override;
86378634
virtual std::string GetRegisterName(uint32_t reg) override;
86388635
virtual std::string GetFlagName(uint32_t flag) override;
86398636
virtual std::string GetFlagWriteTypeName(uint32_t flags) override;
@@ -11333,8 +11330,6 @@ namespace BinaryNinja {
1133311330
void SetUserIndirectBranches(
1133411331
Architecture* sourceArch, uint64_t source, const std::vector<ArchAndAddr>& branches);
1133511332

11336-
std::vector<IndirectBranchInfo> GetAutoIndirectBranches();
11337-
std::vector<IndirectBranchInfo> GetUserIndirectBranches();
1133811333
std::vector<IndirectBranchInfo> GetIndirectBranches();
1133911334
std::vector<IndirectBranchInfo> GetIndirectBranchesAt(Architecture* arch, uint64_t addr);
1134011335

binaryninjacore.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ extern "C"
307307
typedef struct BNLineFormatter BNLineFormatter;
308308
typedef struct BNRenderLayer BNRenderLayer;
309309
typedef struct BNStringRef BNStringRef;
310+
typedef struct BNIndirectBranchInfo BNIndirectBranchInfo;
310311

311312
//! Console log levels
312313
typedef enum BNLogLevel
@@ -1849,6 +1850,16 @@ extern "C"
18491850
AlwaysSkipFunctionAnalysis
18501851
} BNFunctionAnalysisSkipOverride;
18511852

1853+
typedef struct BNBasicBlockAnalysisContext
1854+
{
1855+
size_t indirectBranchesCount;
1856+
BNIndirectBranchInfo* indirectBranches;
1857+
BNFunctionAnalysisSkipOverride analysisSkipOverride;
1858+
bool translateTailCalls;
1859+
bool disallowBranchToString;
1860+
uint64_t maxFunctionSize;
1861+
} BNBasicBlockAnalysisContext;
1862+
18521863
typedef struct BNCustomArchitecture
18531864
{
18541865
void* context;
@@ -1867,8 +1878,7 @@ extern "C"
18671878
void (*freeInstructionText)(BNInstructionTextToken* tokens, size_t count);
18681879
bool (*getInstructionLowLevelIL)(
18691880
void* ctxt, const uint8_t* data, uint64_t addr, size_t* len, BNLowLevelILFunction* il);
1870-
bool (*analyzeBasicBlocks)(void* ctxt, BNFunction* function,
1871-
bool incrementalUpdate, BNFunctionAnalysisSkipOverride analysisSkipOverride);
1881+
void (*analyzeBasicBlocks)(void* ctxt, BNFunction* function, BNBasicBlockAnalysisContext* context);
18721882
char* (*getRegisterName)(void* ctxt, uint32_t reg);
18731883
char* (*getFlagName)(void* ctxt, uint32_t flag);
18741884
char* (*getFlagWriteTypeName)(void* ctxt, uint32_t flags);
@@ -4470,8 +4480,8 @@ extern "C"
44704480
BINARYNINJACOREAPI bool BNGetInstructionLowLevelIL(
44714481
BNArchitecture* arch, const uint8_t* data, uint64_t addr, size_t* len, BNLowLevelILFunction* il);
44724482
BINARYNINJACOREAPI void BNFreeInstructionText(BNInstructionTextToken* tokens, size_t count);
4473-
BINARYNINJACOREAPI bool BNArchitectureAnalyzeBasicBlocks(BNArchitecture* arch, BNFunction* function,
4474-
bool incrementalUpdate, BNFunctionAnalysisSkipOverride analysisSkipOverride);
4483+
BINARYNINJACOREAPI void BNArchitectureAnalyzeBasicBlocks(BNArchitecture* arch, BNFunction* function,
4484+
BNBasicBlockAnalysisContext* context);
44754485
BINARYNINJACOREAPI void BNFreeInstructionTextLines(BNInstructionTextLine* lines, size_t count);
44764486
BINARYNINJACOREAPI char* BNGetArchitectureRegisterName(BNArchitecture* arch, uint32_t reg);
44774487
BINARYNINJACOREAPI char* BNGetArchitectureFlagName(BNArchitecture* arch, uint32_t flag);
@@ -5023,8 +5033,6 @@ extern "C"
50235033
BINARYNINJACOREAPI void BNSetUserIndirectBranches(BNFunction* func, BNArchitecture* sourceArch, uint64_t source,
50245034
BNArchitectureAndAddress* branches, size_t count);
50255035

5026-
BINARYNINJACOREAPI BNIndirectBranchInfo* BNGetAutoIndirectBranches(BNFunction* func, size_t* count);
5027-
BINARYNINJACOREAPI BNIndirectBranchInfo* BNGetUserIndirectBranches(BNFunction* func, size_t* count);
50285036
BINARYNINJACOREAPI BNIndirectBranchInfo* BNGetIndirectBranches(BNFunction* func, size_t* count);
50295037
BINARYNINJACOREAPI BNIndirectBranchInfo* BNGetIndirectBranchesAt(
50305038
BNFunction* func, BNArchitecture* arch, uint64_t addr, size_t* count);

function.cpp

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,52 +1755,6 @@ void Function::SetUserIndirectBranches(
17551755
}
17561756

17571757

1758-
std::vector<IndirectBranchInfo> Function::GetAutoIndirectBranches()
1759-
{
1760-
size_t count;
1761-
BNIndirectBranchInfo* branches = BNGetAutoIndirectBranches(m_object, &count);
1762-
1763-
vector<IndirectBranchInfo> result;
1764-
result.reserve(count);
1765-
for (size_t i = 0; i < count; i++)
1766-
{
1767-
IndirectBranchInfo b;
1768-
b.sourceArch = new CoreArchitecture(branches[i].sourceArch);
1769-
b.sourceAddr = branches[i].sourceAddr;
1770-
b.destArch = new CoreArchitecture(branches[i].destArch);
1771-
b.destAddr = branches[i].destAddr;
1772-
b.autoDefined = branches[i].autoDefined;
1773-
result.push_back(b);
1774-
}
1775-
1776-
BNFreeIndirectBranchList(branches);
1777-
return result;
1778-
}
1779-
1780-
1781-
std::vector<IndirectBranchInfo> Function::GetUserIndirectBranches()
1782-
{
1783-
size_t count;
1784-
BNIndirectBranchInfo* branches = BNGetUserIndirectBranches(m_object, &count);
1785-
1786-
vector<IndirectBranchInfo> result;
1787-
result.reserve(count);
1788-
for (size_t i = 0; i < count; i++)
1789-
{
1790-
IndirectBranchInfo b;
1791-
b.sourceArch = new CoreArchitecture(branches[i].sourceArch);
1792-
b.sourceAddr = branches[i].sourceAddr;
1793-
b.destArch = new CoreArchitecture(branches[i].destArch);
1794-
b.destAddr = branches[i].destAddr;
1795-
b.autoDefined = branches[i].autoDefined;
1796-
result.push_back(b);
1797-
}
1798-
1799-
BNFreeIndirectBranchList(branches);
1800-
return result;
1801-
}
1802-
1803-
18041758
vector<IndirectBranchInfo> Function::GetIndirectBranches()
18051759
{
18061760
size_t count;

rust/src/architecture.rs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -467,11 +467,8 @@ pub trait Architecture: 'static + Sized + AsRef<CoreArchitecture> {
467467
fn analyze_basic_blocks(
468468
&self,
469469
_function: &mut Function,
470-
_incremental_update: bool,
471-
_analysis_skip_override: BNFunctionAnalysisSkipOverride,
472-
) -> bool {
473-
false
474-
}
470+
_context: *mut BNBasicBlockAnalysisContext,
471+
) {}
475472

476473
/// Fallback flag value calculation path. This method is invoked when the core is unable to
477474
/// recover flag use semantics, and resorts to emitting instructions that explicitly set each
@@ -1538,19 +1535,15 @@ impl Architecture for CoreArchitecture {
15381535
fn analyze_basic_blocks(
15391536
&self,
15401537
function: &mut Function,
1541-
incremental_update: bool,
1542-
analysis_skip_override: BNFunctionAnalysisSkipOverride,
1543-
) -> bool {
1544-
let success: bool = unsafe {
1538+
context: *mut BNBasicBlockAnalysisContext,
1539+
) {
1540+
unsafe {
15451541
BNArchitectureAnalyzeBasicBlocks(
15461542
self.handle,
15471543
function.handle,
1548-
incremental_update,
1549-
analysis_skip_override,
1550-
)
1544+
context,
1545+
);
15511546
};
1552-
1553-
return success;
15541547
}
15551548

15561549
fn flag_write_llil<'a>(
@@ -2265,15 +2258,14 @@ where
22652258
extern "C" fn cb_analyze_basic_blocks<A>(
22662259
ctxt: *mut c_void,
22672260
function: *mut BNFunction,
2268-
incremental_update: bool,
2269-
analysis_skip_override: BNFunctionAnalysisSkipOverride,
2270-
) -> bool
2261+
context: *mut BNBasicBlockAnalysisContext,
2262+
)
22712263
where
22722264
A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync,
22732265
{
22742266
let custom_arch = unsafe { &*(ctxt as *mut A) };
22752267
let mut function = unsafe { Function::from_raw(function) };
2276-
return custom_arch.analyze_basic_blocks(&mut function, incremental_update, analysis_skip_override);
2268+
custom_arch.analyze_basic_blocks(&mut function, context);
22772269
}
22782270

22792271
extern "C" fn cb_reg_name<A>(ctxt: *mut c_void, reg: u32) -> *mut c_char

0 commit comments

Comments
 (0)