Skip to content

Commit c7ab5d5

Browse files
committed
Expose SectionMap API
1 parent 1daa515 commit c7ab5d5

File tree

8 files changed

+324
-70
lines changed

8 files changed

+324
-70
lines changed

binaryninjaapi.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5307,6 +5307,19 @@ namespace BinaryNinja {
53075307
bool AutoDefined() const;
53085308
};
53095309

5310+
class SectionMap : public CoreRefCountObject<BNSectionMap, BNNewSectionMapReference, BNFreeSectionMap>
5311+
{
5312+
public:
5313+
SectionMap(BNSectionMap* map);
5314+
std::vector<Ref<Section>> GetSections() const;
5315+
std::vector<Ref<Section>> GetSectionsAt(uint64_t offset) const;
5316+
Ref<Section> GetSectionByName(const std::string& name) const;
5317+
bool IsOffsetCodeSemantics(uint64_t offset) const;
5318+
bool IsOffsetExternSemantics(uint64_t offset) const;
5319+
bool IsOffsetWritableSemantics(uint64_t offset) const;
5320+
bool IsOffsetReadOnlySemantics(uint64_t offset) const;
5321+
};
5322+
53105323
struct RegisterValue
53115324
{
53125325
BNRegisterValueType state;
@@ -7913,6 +7926,8 @@ namespace BinaryNinja {
79137926
*/
79147927
Ref<Section> GetSectionByName(const std::string& name);
79157928

7929+
Ref<SectionMap> GetSectionMap();
7930+
79167931
/*! Create unique names for all items in the input list, modifying them if they are not unique
79177932

79187933
\code{.cpp}

binaryninjacore.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ extern "C"
314314
typedef struct BNConstantRenderer BNConstantRenderer;
315315
typedef struct BNStringRecognizer BNStringRecognizer;
316316
typedef struct BNCustomStringType BNCustomStringType;
317+
typedef struct BNSectionMap BNSectionMap;
317318

318319
typedef struct BNRemoteFileSearchMatch
319320
{
@@ -4591,6 +4592,7 @@ extern "C"
45914592
BINARYNINJACOREAPI void BNFreeSectionList(BNSection** sections, size_t count);
45924593
BINARYNINJACOREAPI BNSection* BNGetSectionByName(BNBinaryView* view, const char* name);
45934594
BINARYNINJACOREAPI char** BNGetUniqueSectionNames(BNBinaryView* view, const char** names, size_t count);
4595+
BINARYNINJACOREAPI BNSectionMap* BNGetSectionMap(BNBinaryView* view);
45944596

45954597
BINARYNINJACOREAPI BNAddressRange* BNGetAllocatedRanges(BNBinaryView* view, size_t* count);
45964598
BINARYNINJACOREAPI BNAddressRange* BNGetMappedAddressRanges(BNBinaryView* view, size_t* count);
@@ -8861,6 +8863,16 @@ extern "C"
88618863
BINARYNINJACOREAPI bool BNStringRecognizerRecognizeImport(BNStringRecognizer* recognizer, BNHighLevelILFunction* il,
88628864
size_t exprIndex, BNType* type, int64_t val, BNDerivedString* out);
88638865

8866+
BINARYNINJACOREAPI bool BNSectionMapIsOffsetCodeSemantics(BNSectionMap* map, uint64_t offset);
8867+
BINARYNINJACOREAPI bool BNSectionMapIsOffsetExternSemantics(BNSectionMap* map, uint64_t offset);
8868+
BINARYNINJACOREAPI bool BNSectionMapIsOffsetWritableSemantics(BNSectionMap* map, uint64_t offset);
8869+
BINARYNINJACOREAPI bool BNSectionMapIsOffsetReadOnlySemantics(BNSectionMap* map, uint64_t offset);
8870+
BINARYNINJACOREAPI BNSection** BNSectionMapGetSections(BNSectionMap* map, size_t* count);
8871+
BINARYNINJACOREAPI BNSection** BNSectionMapGetSectionsAt(BNSectionMap* map, uint64_t addr, size_t* count);
8872+
BINARYNINJACOREAPI BNSection* BNSectionMapGetSectionByName(BNSectionMap* map, const char* name);
8873+
BINARYNINJACOREAPI BNSectionMap* BNNewSectionMapReference(BNSectionMap* map);
8874+
BINARYNINJACOREAPI void BNFreeSectionMap(BNSectionMap* map);
8875+
88648876
#ifdef __cplusplus
88658877
}
88668878
#endif

binaryview.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,71 @@ bool Section::AutoDefined() const
13381338
}
13391339

13401340

1341+
SectionMap::SectionMap(BNSectionMap *map)
1342+
{
1343+
m_object = map;
1344+
}
1345+
1346+
1347+
std::vector<Ref<Section>> SectionMap::GetSections() const
1348+
{
1349+
size_t count;
1350+
BNSection** sections = BNSectionMapGetSections(m_object, &count);
1351+
vector<Ref<Section>> result;
1352+
result.reserve(count);
1353+
for (size_t i = 0; i < count; i++)
1354+
result.push_back(new Section(BNNewSectionReference(sections[i])));
1355+
BNFreeSectionList(sections, count);
1356+
return result;
1357+
}
1358+
1359+
1360+
std::vector<Ref<Section>> SectionMap::GetSectionsAt(uint64_t offset) const
1361+
{
1362+
size_t count;
1363+
BNSection** sections = BNSectionMapGetSectionsAt(m_object, offset, &count);
1364+
vector<Ref<Section>> result;
1365+
result.reserve(count);
1366+
for (size_t i = 0; i < count; i++)
1367+
result.push_back(new Section(BNNewSectionReference(sections[i])));
1368+
BNFreeSectionList(sections, count);
1369+
return result;
1370+
}
1371+
1372+
1373+
Ref<Section> SectionMap::GetSectionByName(const std::string& name) const
1374+
{
1375+
BNSection* section = BNSectionMapGetSectionByName(m_object, name.c_str());
1376+
if (section)
1377+
return new Section(section);
1378+
return nullptr;
1379+
}
1380+
1381+
1382+
bool SectionMap::IsOffsetCodeSemantics(uint64_t offset) const
1383+
{
1384+
return BNSectionMapIsOffsetCodeSemantics(m_object, offset);
1385+
}
1386+
1387+
1388+
bool SectionMap::IsOffsetExternSemantics(uint64_t offset) const
1389+
{
1390+
return BNSectionMapIsOffsetExternSemantics(m_object, offset);
1391+
}
1392+
1393+
1394+
bool SectionMap::IsOffsetWritableSemantics(uint64_t offset) const
1395+
{
1396+
return BNSectionMapIsOffsetWritableSemantics(m_object, offset);
1397+
}
1398+
1399+
1400+
bool SectionMap::IsOffsetReadOnlySemantics(uint64_t offset) const
1401+
{
1402+
return BNSectionMapIsOffsetReadOnlySemantics(m_object, offset);
1403+
}
1404+
1405+
13411406
BinaryView::BinaryView(const std::string& typeName, FileMetadata* file, BinaryView* parentView)
13421407
{
13431408
BNCustomBinaryView view;
@@ -5343,6 +5408,12 @@ Ref<Section> BinaryView::GetSectionByName(const string& name)
53435408
}
53445409

53455410

5411+
Ref<SectionMap> BinaryView::GetSectionMap()
5412+
{
5413+
return new SectionMap(BNGetSectionMap(m_object));
5414+
}
5415+
5416+
53465417
vector<string> BinaryView::GetUniqueSectionNames(const vector<string>& names)
53475418
{
53485419
const char** incomingNames = new const char*[names.size()];

defaultabb.cpp

Lines changed: 6 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -9,44 +9,6 @@
99
using namespace std;
1010
using namespace BinaryNinja;
1111

12-
// TODO: Decomposed from BinaryView::IsOffsetCodeSemantics BinaryView::IsOffsetExternSemantics
13-
// TODO: When the better sections model is merged, remove this
14-
static bool IsOffsetCodeSemanticsFast(BinaryView* data, const vector<Section*>& readOnlySections, const vector<Section*>& dataExternSections, uint64_t offset)
15-
{
16-
if (!data->IsOffsetBackedByFile(offset))
17-
return false;
18-
19-
for (const auto& i : readOnlySections)
20-
{
21-
if ((offset >= i->GetStart()) && (offset < i->GetEnd()))
22-
return true;
23-
}
24-
for (const auto& i : dataExternSections)
25-
{
26-
if ((offset >= i->GetStart()) && (offset < i->GetEnd()))
27-
return false;
28-
}
29-
30-
return data->IsOffsetExecutable(offset);
31-
}
32-
33-
34-
static bool IsOffsetExternSemanticsFast(BinaryView* data, const vector<Section*>& externSections, uint64_t offset)
35-
{
36-
if (data->IsOffsetBackedByFile(offset))
37-
return false;
38-
if (data->IsOffsetExecutable(offset))
39-
return false;
40-
41-
for (const auto& i : externSections)
42-
{
43-
if ((offset >= i->GetStart()) && (offset < i->GetEnd()))
44-
return true;
45-
}
46-
47-
return false;
48-
}
49-
5012

5113
static bool GetNextFunctionAfterAddress(Ref<BinaryView> data, Ref<Platform> platform, uint64_t address, Ref<Function>& nextFunc)
5214
{
@@ -59,6 +21,7 @@ static bool GetNextFunctionAfterAddress(Ref<BinaryView> data, Ref<Platform> plat
5921
void Architecture::DefaultAnalyzeBasicBlocks(Function* function, BasicBlockAnalysisContext& context)
6022
{
6123
auto data = function->GetView();
24+
auto sectionMap = data->GetSectionMap();
6225
queue<ArchAndAddr> blocksToProcess;
6326
map<ArchAndAddr, Ref<BasicBlock>> instrBlocks;
6427
set<ArchAndAddr> seenBlocks;
@@ -93,31 +56,6 @@ void Architecture::DefaultAnalyzeBasicBlocks(Function* function, BasicBlockAnaly
9356
return (strRef.length >= byteLimit);
9457
};
9558

96-
// TODO: Decomposed from BinaryView::IsOffsetCodeSemantics BinaryView::IsOffsetExternSemantics
97-
// TODO: When the better sections model is merged, remove this
98-
auto sections = data->GetSections();
99-
vector<Section*> externSections, readOnlySections, dataExternSections;
100-
externSections.reserve(sections.size());
101-
readOnlySections.reserve(sections.size());
102-
dataExternSections.reserve(sections.size());
103-
for (auto& section: sections)
104-
{
105-
if (section->GetSemantics() == ExternalSectionSemantics)
106-
{
107-
externSections.push_back(section);
108-
}
109-
if (section->GetSemantics() == ReadOnlyCodeSectionSemantics)
110-
{
111-
readOnlySections.push_back(section);
112-
}
113-
if ((section->GetSemantics() == ReadOnlyDataSectionSemantics) ||
114-
(section->GetSemantics() == ReadWriteDataSectionSemantics) ||
115-
(section->GetSemantics() == ExternalSectionSemantics))
116-
{
117-
dataExternSections.push_back(section);
118-
}
119-
}
120-
12159
// Start by processing the entry point of the function
12260
Ref<Platform> funcPlatform = function->GetPlatform();
12361
auto start = function->GetStart();
@@ -136,7 +74,7 @@ void Architecture::DefaultAnalyzeBasicBlocks(Function* function, BasicBlockAnaly
13674
// Extract the bounds of the section containing this
13775
// function, to avoid calling into the BinaryView on
13876
// every instruction.
139-
for (auto& sec : data->GetSectionsAt(start))
77+
for (auto& sec : sectionMap->GetSectionsAt(start))
14078
{
14179
if (sec->GetSemantics() == ReadOnlyDataSectionSemantics)
14280
continue;
@@ -295,7 +233,7 @@ void Architecture::DefaultAnalyzeBasicBlocks(Function* function, BasicBlockAnaly
295233
uint64_t instrEnd = location.address + info.length - 1;
296234
bool slowPath = !fastValidate || (instrEnd < fastStartAddr) || (instrEnd > fastEndAddr);
297235
if (slowPath &&
298-
((!IsOffsetCodeSemanticsFast(data, readOnlySections, dataExternSections, instrEnd) && IsOffsetCodeSemanticsFast(data, readOnlySections, dataExternSections,location.address)) ||
236+
((!sectionMap->IsOffsetCodeSemantics(instrEnd) && sectionMap->IsOffsetCodeSemantics(location.address)) ||
299237
(!data->IsOffsetBackedByFile(instrEnd) && data->IsOffsetBackedByFile(location.address))))
300238
{
301239
string text = fmt::format("Instruction at {:#x} straddles a non-code section", location.address);
@@ -410,7 +348,7 @@ void Architecture::DefaultAnalyzeBasicBlocks(Function* function, BasicBlockAnaly
410348
// Normal branch, resume disassembly at targets
411349
endsBlock = true;
412350
// Target of a call instruction, add the function to the analysis
413-
if (IsOffsetExternSemanticsFast(data, externSections, info.branchTarget[i]))
351+
if (sectionMap->IsOffsetExternSemantics(info.branchTarget[i]))
414352
{
415353
// Deal with direct pointers into the extern section
416354
DataVariable dataVar;
@@ -487,7 +425,7 @@ void Architecture::DefaultAnalyzeBasicBlocks(Function* function, BasicBlockAnaly
487425

488426
case CallDestination:
489427
// Target of a call instruction, add the function to the analysis
490-
if (IsOffsetExternSemanticsFast(data, externSections, info.branchTarget[i]))
428+
if (sectionMap->IsOffsetExternSemantics(info.branchTarget[i]))
491429
{
492430
// Deal with direct pointers into the extern section
493431
DataVariable dataVar;
@@ -514,8 +452,7 @@ void Architecture::DefaultAnalyzeBasicBlocks(Function* function, BasicBlockAnaly
514452
{
515453
target = ArchAndAddr(info.branchArch[i] ? new CoreArchitecture(info.branchArch[i]) : location.arch, info.branchTarget[i]);
516454

517-
if (!fastPath && !IsOffsetCodeSemanticsFast(data, readOnlySections, dataExternSections, target.address) &&
518-
IsOffsetCodeSemanticsFast(data, readOnlySections, dataExternSections, location.address))
455+
if (!fastPath && !sectionMap->IsOffsetCodeSemantics(target.address) && sectionMap->IsOffsetCodeSemantics(location.address))
519456
{
520457
string message = fmt::format("Non-code call target {:#x}", target.address);
521458
function->CreateAutoAddressTag(target.arch, location.address, "Non-code Branch", message, true);

0 commit comments

Comments
 (0)