diff options
| author | Rusty Wagner <rusty@vector35.com> | 2017-08-17 22:05:32 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2017-08-17 22:31:55 -0400 |
| commit | 78d90c30df96364cdc8dde1954be7341531cfe07 (patch) | |
| tree | c854bc915a27485b9e8650f3916757f98f7ba00e | |
| parent | 5e25409d02479285d1f16d6cc55df1b267e9ba06 (diff) | |
Adding section semantics to deal with semantically read-only sections inside of writable areas
| -rw-r--r-- | binaryninjaapi.h | 9 | ||||
| -rw-r--r-- | binaryninjacore.h | 19 | ||||
| -rw-r--r-- | binaryview.cpp | 33 | ||||
| -rw-r--r-- | python/binaryview.py | 47 |
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(§ion); 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 |
