summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2017-08-17 22:05:32 -0400
committerRusty Wagner <rusty@vector35.com>2017-08-17 22:31:55 -0400
commit78d90c30df96364cdc8dde1954be7341531cfe07 (patch)
treec854bc915a27485b9e8650f3916757f98f7ba00e
parent5e25409d02479285d1f16d6cc55df1b267e9ba06 (diff)
Adding section semantics to deal with semantically read-only sections inside of writable areas
-rw-r--r--binaryninjaapi.h9
-rw-r--r--binaryninjacore.h19
-rw-r--r--binaryview.cpp33
-rw-r--r--python/binaryview.py47
4 files changed, 83 insertions, 25 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 8213675d..8a09529e 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1030,6 +1030,7 @@ namespace BinaryNinja
std::string linkedSection, infoSection;
uint64_t infoData;
uint64_t align, entrySize;
+ BNSectionSemantics semantics;
};
struct QualifiedNameAndType;
@@ -1159,6 +1160,8 @@ namespace BinaryNinja
bool IsOffsetWritable(uint64_t offset) const;
bool IsOffsetExecutable(uint64_t offset) const;
bool IsOffsetBackedByFile(uint64_t offset) const;
+ bool IsOffsetCodeSemantics(uint64_t offset) const;
+ bool IsOffsetWritableSemantics(uint64_t offset) const;
uint64_t GetNextValidOffset(uint64_t offset) const;
uint64_t GetStart() const;
@@ -1299,11 +1302,13 @@ namespace BinaryNinja
bool GetSegmentAt(uint64_t addr, Segment& result);
bool GetAddressForDataOffset(uint64_t offset, uint64_t& addr);
- void AddAutoSection(const std::string& name, uint64_t start, uint64_t length, const std::string& type = "",
+ void AddAutoSection(const std::string& name, uint64_t start, uint64_t length,
+ BNSectionSemantics semantics = DefaultSectionSemantics, const std::string& type = "",
uint64_t align = 1, uint64_t entrySize = 0, const std::string& linkedSection = "",
const std::string& infoSection = "", uint64_t infoData = 0);
void RemoveAutoSection(const std::string& name);
- void AddUserSection(const std::string& name, uint64_t start, uint64_t length, const std::string& type = "",
+ void AddUserSection(const std::string& name, uint64_t start, uint64_t length,
+ BNSectionSemantics semantics = DefaultSectionSemantics, const std::string& type = "",
uint64_t align = 1, uint64_t entrySize = 0, const std::string& linkedSection = "",
const std::string& infoSection = "", uint64_t infoData = 0);
void RemoveUserSection(const std::string& name);
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 3c8757ed..b69d79f9 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -1504,6 +1504,14 @@ extern "C"
uint32_t flags;
};
+ enum BNSectionSemantics
+ {
+ DefaultSectionSemantics,
+ ReadOnlyCodeSectionSemantics,
+ ReadOnlyDataSectionSemantics,
+ ReadWriteDataSectionSemantics
+ };
+
struct BNSection
{
char* name;
@@ -1513,6 +1521,7 @@ extern "C"
char* infoSection;
uint64_t infoData;
uint64_t align, entrySize;
+ BNSectionSemantics semantics;
};
struct BNAddressRange
@@ -1727,6 +1736,8 @@ extern "C"
BINARYNINJACOREAPI bool BNIsOffsetWritable(BNBinaryView* view, uint64_t offset);
BINARYNINJACOREAPI bool BNIsOffsetExecutable(BNBinaryView* view, uint64_t offset);
BINARYNINJACOREAPI bool BNIsOffsetBackedByFile(BNBinaryView* view, uint64_t offset);
+ BINARYNINJACOREAPI bool BNIsOffsetCodeSemantics(BNBinaryView* view, uint64_t offset);
+ BINARYNINJACOREAPI bool BNIsOffsetWritableSemantics(BNBinaryView* view, uint64_t offset);
BINARYNINJACOREAPI uint64_t BNGetNextValidOffset(BNBinaryView* view, uint64_t offset);
BINARYNINJACOREAPI uint64_t BNGetStartOffset(BNBinaryView* view);
BINARYNINJACOREAPI uint64_t BNGetEndOffset(BNBinaryView* view);
@@ -1777,12 +1788,12 @@ extern "C"
BINARYNINJACOREAPI bool BNGetAddressForDataOffset(BNBinaryView* view, uint64_t offset, uint64_t* addr);
BINARYNINJACOREAPI void BNAddAutoSection(BNBinaryView* view, const char* name, uint64_t start, uint64_t length,
- const char* type, uint64_t align, uint64_t entrySize, const char* linkedSection, const char* infoSection,
- uint64_t infoData);
+ BNSectionSemantics semantics, const char* type, uint64_t align, uint64_t entrySize,
+ const char* linkedSection, const char* infoSection, uint64_t infoData);
BINARYNINJACOREAPI void BNRemoveAutoSection(BNBinaryView* view, const char* name);
BINARYNINJACOREAPI void BNAddUserSection(BNBinaryView* view, const char* name, uint64_t start, uint64_t length,
- const char* type, uint64_t align, uint64_t entrySize, const char* linkedSection, const char* infoSection,
- uint64_t infoData);
+ BNSectionSemantics semantics, const char* type, uint64_t align, uint64_t entrySize,
+ const char* linkedSection, const char* infoSection, uint64_t infoData);
BINARYNINJACOREAPI void BNRemoveUserSection(BNBinaryView* view, const char* name);
BINARYNINJACOREAPI BNSection* BNGetSections(BNBinaryView* view, size_t* count);
BINARYNINJACOREAPI BNSection* BNGetSectionsAt(BNBinaryView* view, uint64_t addr, size_t* count);
diff --git a/binaryview.cpp b/binaryview.cpp
index 23a62aec..2c7da23e 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -758,6 +758,18 @@ bool BinaryView::IsOffsetBackedByFile(uint64_t offset) const
}
+bool BinaryView::IsOffsetCodeSemantics(uint64_t offset) const
+{
+ return BNIsOffsetCodeSemantics(m_object, offset);
+}
+
+
+bool BinaryView::IsOffsetWritableSemantics(uint64_t offset) const
+{
+ return BNIsOffsetWritableSemantics(m_object, offset);
+}
+
+
uint64_t BinaryView::GetNextValidOffset(uint64_t offset) const
{
return BNGetNextValidOffset(m_object, offset);
@@ -1716,11 +1728,12 @@ bool BinaryView::GetAddressForDataOffset(uint64_t offset, uint64_t& addr)
}
-void BinaryView::AddAutoSection(const string& name, uint64_t start, uint64_t length, const string& type,
- uint64_t align, uint64_t entrySize, const string& linkedSection, const string& infoSection, uint64_t infoData)
+void BinaryView::AddAutoSection(const string& name, uint64_t start, uint64_t length, BNSectionSemantics semantics,
+ const string& type, uint64_t align, uint64_t entrySize, const string& linkedSection,
+ const string& infoSection, uint64_t infoData)
{
- BNAddAutoSection(m_object, name.c_str(), start, length, type.c_str(), align, entrySize, linkedSection.c_str(),
- infoSection.c_str(), infoData);
+ BNAddAutoSection(m_object, name.c_str(), start, length, semantics, type.c_str(), align, entrySize,
+ linkedSection.c_str(), infoSection.c_str(), infoData);
}
@@ -1730,11 +1743,12 @@ void BinaryView::RemoveAutoSection(const string& name)
}
-void BinaryView::AddUserSection(const string& name, uint64_t start, uint64_t length, const string& type,
- uint64_t align, uint64_t entrySize, const string& linkedSection, const string& infoSection, uint64_t infoData)
+void BinaryView::AddUserSection(const string& name, uint64_t start, uint64_t length, BNSectionSemantics semantics,
+ const string& type, uint64_t align, uint64_t entrySize, const string& linkedSection,
+ const string& infoSection, uint64_t infoData)
{
- BNAddUserSection(m_object, name.c_str(), start, length, type.c_str(), align, entrySize, linkedSection.c_str(),
- infoSection.c_str(), infoData);
+ BNAddUserSection(m_object, name.c_str(), start, length, semantics, type.c_str(), align, entrySize,
+ linkedSection.c_str(), infoSection.c_str(), infoData);
}
@@ -1762,6 +1776,7 @@ vector<Section> BinaryView::GetSections()
section.infoData = sections[i].infoData;
section.align = sections[i].align;
section.entrySize = sections[i].entrySize;
+ section.semantics = sections[i].semantics;
result.push_back(section);
}
@@ -1788,6 +1803,7 @@ vector<Section> BinaryView::GetSectionsAt(uint64_t addr)
section.infoData = sections[i].infoData;
section.align = sections[i].align;
section.entrySize = sections[i].entrySize;
+ section.semantics = sections[i].semantics;
result.push_back(section);
}
@@ -1811,6 +1827,7 @@ bool BinaryView::GetSectionByName(const string& name, Section& result)
result.infoData = section.infoData;
result.align = section.align;
result.entrySize = section.entrySize;
+ result.semantics = section.semantics;
BNFreeSection(&section);
return true;
diff --git a/python/binaryview.py b/python/binaryview.py
index bdba11af..d977de50 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -27,7 +27,7 @@ import threading
# Binary Ninja components
import _binaryninjacore as core
from enums import (AnalysisState, SymbolType, InstructionTextTokenType,
- Endianness, ModificationStatus, StringType, SegmentFlag)
+ Endianness, ModificationStatus, StringType, SegmentFlag, SectionSemantics)
import function
import startup
import architecture
@@ -422,7 +422,7 @@ class Segment(object):
class Section(object):
- def __init__(self, name, section_type, start, length, linked_section, info_section, info_data, align, entry_size):
+ def __init__(self, name, section_type, start, length, linked_section, info_section, info_data, align, entry_size, semantics):
self.name = name
self.type = section_type
self.start = start
@@ -432,6 +432,7 @@ class Section(object):
self.info_data = info_data
self.align = align
self.entry_size = entry_size
+ self.semantics = SectionSemantics(semantics)
@property
def end(self):
@@ -899,7 +900,8 @@ class BinaryView(object):
for i in xrange(0, count.value):
result[section_list[i].name] = Section(section_list[i].name, section_list[i].type, section_list[i].start,
section_list[i].length, section_list[i].linkedSection, section_list[i].infoSection,
- section_list[i].infoData, section_list[i].align, section_list[i].entrySize)
+ section_list[i].infoData, section_list[i].align, section_list[i].entrySize,
+ section_list[i].semantics)
core.BNFreeSectionList(section_list, count.value)
return result
@@ -1678,6 +1680,28 @@ class BinaryView(object):
"""
return core.BNIsOffsetExecutable(self.handle, addr)
+ def is_offset_code_semantics(self, addr):
+ """
+ ``is_offset_code_semantics`` checks if an virtual address ``addr`` is semantically valid for code.
+
+ :param int addr: a virtual address to be checked
+ :return: true if the virtual address is valid for writing, false if the virtual address is invalid or error
+ :rtype: bool
+ """
+ return core.BNIsOffsetCodeSemantics(self.handle, addr)
+
+ def is_offset_writable_semantics(self, addr):
+ """
+ ``is_offset_writable_semantics`` checks if an virtual address ``addr`` is semantically writable. Some sections
+ may have writable permissions for linking purposes but can be treated as read-only for the purposes of
+ analysis.
+
+ :param int addr: a virtual address to be checked
+ :return: true if the virtual address is valid for writing, false if the virtual address is invalid or error
+ :rtype: bool
+ """
+ return core.BNIsOffsetWritableSemantics(self.handle, addr)
+
def save(self, dest):
"""
``save`` saves the original binary file to the provided destination ``dest`` along with any modifications.
@@ -3218,17 +3242,17 @@ class BinaryView(object):
return None
return address.value
- def add_auto_section(self, name, start, length, type = "", align = 1, entry_size = 1, linked_section = "",
- info_section = "", info_data = 0):
- core.BNAddAutoSection(self.handle, name, start, length, type, align, entry_size, linked_section,
+ def add_auto_section(self, name, start, length, semantics = SectionSemantics.DefaultSectionSemantics,
+ type = "", align = 1, entry_size = 1, linked_section = "", info_section = "", info_data = 0):
+ core.BNAddAutoSection(self.handle, name, start, length, semantics, type, align, entry_size, linked_section,
info_section, info_data)
def remove_auto_section(self, name):
core.BNRemoveAutoSection(self.handle, name)
- def add_user_section(self, name, start, length, type = "", align = 1, entry_size = 1, linked_section = "",
- info_section = "", info_data = 0):
- core.BNAddUserSection(self.handle, name, start, length, type, align, entry_size, linked_section,
+ def add_user_section(self, name, start, length, semantics = SectionSemantics.DefaultSectionSemantics,
+ type = "", align = 1, entry_size = 1, linked_section = "", info_section = "", info_data = 0):
+ core.BNAddUserSection(self.handle, name, start, length, semantics, type, align, entry_size, linked_section,
info_section, info_data)
def remove_user_section(self, name):
@@ -3241,7 +3265,8 @@ class BinaryView(object):
for i in xrange(0, count.value):
result.append(Section(section_list[i].name, section_list[i].type, section_list[i].start,
section_list[i].length, section_list[i].linkedSection, section_list[i].infoSection,
- section_list[i].infoData, section_list[i].align, section_list[i].entrySize))
+ section_list[i].infoData, section_list[i].align, section_list[i].entrySize,
+ section_list[i].semantics))
core.BNFreeSectionList(section_list, count.value)
return result
@@ -3250,7 +3275,7 @@ class BinaryView(object):
if not core.BNGetSectionByName(self.handle, name, section):
return None
result = Section(section.name, section.type, section.start, section.length, section.linkedSection,
- section.infoSection, section.infoData, section.align, section.entrySize)
+ section.infoSection, section.infoData, section.align, section.entrySize, section.semantics)
core.BNFreeSection(section)
return result