summaryrefslogtreecommitdiff
path: root/python/binaryview.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/binaryview.py')
-rw-r--r--python/binaryview.py311
1 files changed, 242 insertions, 69 deletions
diff --git a/python/binaryview.py b/python/binaryview.py
index 9fea3fa7..4239a9e8 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -471,32 +471,74 @@ class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
class Segment(object):
- def __init__(self, start, length, data_offset, data_length, flags, auto_defined):
- self.start = start
- self.length = length
- self.data_offset = data_offset
- self.data_length = data_length
- self.flags = flags
- self.auto_defined = auto_defined
+ def __init__(self, handle):
+ self.handle = handle
+
+ @property
+ def start(self):
+ return core.BNSegmentGetStart(self.handle)
+
+ @property
+ def end(self):
+ return core.BNSegmentGetEnd(self.handle)
@property
def executable(self):
- return (self.flags & SegmentFlag.SegmentExecutable) != 0
+ return (core.BNSegmentGetFlags(self.handle) & SegmentFlag.SegmentExecutable) != 0
@property
def writable(self):
- return (self.flags & SegmentFlag.SegmentWritable) != 0
+ return (core.BNSegmentGetFlags(self.handle) & SegmentFlag.SegmentWritable) != 0
@property
def readable(self):
- return (self.flags & SegmentFlag.SegmentReadable) != 0
+ return (core.BNSegmentGetFlags(self.handle) & SegmentFlag.SegmentReadable) != 0
@property
def end(self):
- return self.start + self.length
+ return core.BNSegmentGetEnd(self.handle)
+
+ @property
+ def data_length(self):
+ return core.BNSegmentGetDataLength(self.handle)
+
+ @property
+ def data_offset(self):
+ return core.BNSegmentGetDataOffset(self.handle)
+
+ @property
+ def data_end(self):
+ return core.BNSegmentGetDataEnd(self.handle)
+
+ @property
+ def reloction_count(self):
+ return core.BNSegmentGetRelocationsCount(self.handle)
+
+ @property
+ def relocation_ranges(self):
+ """List of relocation range tuples (read-only)"""
+
+ count = ctypes.c_ulonglong()
+ ranges = core.BNSegmentGetRelocationRanges(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append((ranges[i].start, ranges[i].end))
+ core.BNFreeRelocationRanges(ranges, count)
+ return result
+
+ def relocation_ranges_at(self, addr):
+ """List of relocation range tuples (read-only)"""
+
+ count = ctypes.c_ulonglong()
+ ranges = core.BNSegmentGetRelocationRangesAtAddress(self.handle, addr, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append((ranges[i].start, ranges[i].end))
+ core.BNFreeRelocationRanges(ranges, count)
+ return result
def __len__(self):
- return self.length
+ return core.BNSegmentGetLength(self.handle)
def __repr__(self):
return "<segment: %#x-%#x, %s%s%s>" % (self.start, self.end,
@@ -506,25 +548,55 @@ class Segment(object):
class Section(object):
- def __init__(self, name, section_type, start, length, linked_section, info_section, info_data, align, entry_size, semantics, auto_defined):
- self.name = name
- self.type = section_type
- self.start = start
- self.length = length
- self.linked_section = linked_section
- self.info_section = info_section
- self.info_data = info_data
- self.align = align
- self.entry_size = entry_size
- self.semantics = SectionSemantics(semantics)
- self.auto_defined = auto_defined
+ def __init__(self, handle):
+ self.handle = core.handle_of_type(handle, core.BNSection)
+
+ @property
+ def name(self):
+ return core.BNSectionGetName(self.handle)
+
+ @property
+ def type(self):
+ return core.BNSectionGetType(self.handle)
+
+ @property
+ def start(self):
+ return core.BNSectionGetStart(self.handle)
+
+ @property
+ def linked_section(self):
+ return core.BNSectionLinkedSection(self.handle)
+
+ @property
+ def info_section(self):
+ return core.BNSectionInfoSection(self.handle)
+
+ @property
+ def info_data(self):
+ return core.BNSectionInfoData(self.handle)
+
+ @property
+ def align(self):
+ return core.BNSectionAlign(self.handle)
+
+ @property
+ def entry_size(self):
+ return core.BNSectionEntrySize(self.handle)
+
+ @property
+ def semantics(self):
+ return SectionSemantics(core.BNSectionGetSemantics(self.handle))
+
+ @property
+ def auto_defined(self):
+ return core.BNSectionAutoDefined(self.handle)
@property
def end(self):
- return self.start + self.length
+ return self.start + len(self)
def __len__(self):
- return self.length
+ return core.BNSectionGetLength(self.handle)
def __repr__(self):
return "<section %s: %#x-%#x>" % (self.name, self.start, self.end)
@@ -945,15 +1017,44 @@ class BinaryView(object):
def symbols(self):
"""Dict of symbols (read-only)"""
count = ctypes.c_ulonglong(0)
- syms = core.BNGetSymbols(self.handle, count)
+ syms = core.BNGetSymbols(self.handle, count, None)
result = {}
for i in range(0, count.value):
sym = types.Symbol(None, None, None, handle=core.BNNewSymbolReference(syms[i]))
- result[sym.raw_name] = sym
+ if sym.raw_name in result:
+ result[sym.raw_name] = [result[sym.raw_name], sym]
+ else:
+ result[sym.raw_name] = sym
core.BNFreeSymbolList(syms, count.value)
return result
@property
+ def internal_namespace(self):
+ """Internal namespace for the current BinaryView"""
+ ns = core.BNGetInternalNameSpace(self.handle)
+ result = types.NameSpace._from_core_struct(ns)
+ core.BNFreeNameSpace(ns)
+ return result
+
+ @property
+ def external_namespace(self):
+ """External namespace for the current BinaryView"""
+ ns = core.BNGetExternalNameSpace(self.handle)
+ result = types.NameSpace._from_core_struct(ns)
+ core.BNFreeNameSpace(ns)
+ return result
+
+ @property
+ def namespaces(self):
+ count = ctypes.c_ulonglong(0)
+ nameSpaceList = core.BNGetNameSpaces(self.handle, count)
+ result = []
+ for i in range(count.value):
+ result.append(types.NameSpace._from_core_struct(nameSpaceList[i]))
+ core.BNFreeNameSpaceList(nameSpaceList, count.value);
+ return result
+
+ @property
def view_type(self):
"""View type (read-only)"""
return core.BNGetViewType(self.handle)
@@ -1041,9 +1142,8 @@ class BinaryView(object):
segment_list = core.BNGetSegments(self.handle, count)
result = []
for i in range(0, count.value):
- result.append(Segment(segment_list[i].start, segment_list[i].length,
- segment_list[i].dataOffset, segment_list[i].dataLength, segment_list[i].flags, segment_list[i].autoDefined))
- core.BNFreeSegmentList(segment_list)
+ result.append(Segment(core.BNNewSegmentReference(segment_list[i])))
+ core.BNFreeSegmentList(segment_list, count.value)
return result
@property
@@ -1053,10 +1153,7 @@ class BinaryView(object):
section_list = core.BNGetSections(self.handle, count)
result = {}
for i in range(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].semantics, section_list[i].autoDefined)
+ result[core.BNSectionGetName(section_list[i])] = Section(section_list[i])
core.BNFreeSectionList(section_list, count.value)
return result
@@ -1106,6 +1203,29 @@ class BinaryView(object):
core.BNSetMaxFunctionSizeForAnalysis(self.handle, size)
@property
+ def relocation_ranges(self):
+ """List of relocation range tuples (read-only)"""
+
+ count = ctypes.c_ulonglong()
+ ranges = core.BNGetRelocationRanges(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append((ranges[i].start, ranges[i].end))
+ core.BNFreeRelocationRanges(ranges, count)
+ return result
+
+ def relocation_ranges_at(self, addr):
+ """List of relocation range tuples for a given address"""
+
+ count = ctypes.c_ulonglong()
+ ranges = core.BNGetRelocationRangesAtAddress(self.handle, addr, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append((ranges[i].start, ranges[i].end))
+ core.BNFreeRelocationRanges(ranges, count)
+ return result
+
+ @property
def new_auto_function_analysis_suppressed(self):
"""Whether or not automatically discovered functions will be analyzed"""
return core.BNGetNewAutoFunctionAnalysisSuppressed(self.handle)
@@ -1910,6 +2030,16 @@ class BinaryView(object):
"""
return core.BNIsOffsetCodeSemantics(self.handle, addr)
+ def is_offset_extern_semantics(self, addr):
+ """
+ ``is_offset_extern_semantics`` checks if an virtual address ``addr`` is semantically valid for external references.
+
+ :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.BNIsOffsetExternSemantics(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
@@ -2313,12 +2443,13 @@ class BinaryView(object):
core.BNFreeCodeReferences(refs, count.value)
return result
- def get_symbol_at(self, addr):
+ def get_symbol_at(self, addr, namespace=None):
"""
``get_symbol_at`` returns the Symbol at the provided virtual address.
:param int addr: virtual address to query for symbol
:return: Symbol for the given virtual address
+ :param NameSpace namespace: the namespace of the symbols to retrieve
:rtype: Symbol
:Example:
@@ -2326,17 +2457,23 @@ class BinaryView(object):
<FunctionSymbol: "_start" @ 0x100001174>
>>>
"""
- sym = core.BNGetSymbolByAddress(self.handle, addr)
+ if isinstance(namespace, str):
+ namespace = types.NameSpace(namespace)
+ if isinstance(namespace, types.NameSpace):
+ namespace = namespace._get_core_struct()
+
+ sym = core.BNGetSymbolByAddress(self.handle, addr, namespace)
if sym is None:
return None
return types.Symbol(None, None, None, handle = sym)
- def get_symbol_by_raw_name(self, name):
+ def get_symbol_by_raw_name(self, name, namespace=None):
"""
``get_symbol_by_raw_name`` retrieves a Symbol object for the given a raw (mangled) name.
:param str name: raw (mangled) name of Symbol to be retrieved
:return: Symbol object corresponding to the provided raw name
+ :param NameSpace namespace: the namespace to search for the given symbol
:rtype: Symbol
:Example:
@@ -2344,17 +2481,22 @@ class BinaryView(object):
<FunctionSymbol: "public: static enum Foobar::foo __cdecl Foobar::testf(enum Foobar::foo)" @ 0x10001100>
>>>
"""
- sym = core.BNGetSymbolByRawName(self.handle, name)
+ if isinstance(namespace, str):
+ namespace = types.NameSpace(namespace)
+ if isinstance(namespace, types.NameSpace):
+ namespace = namespace._get_core_struct()
+ sym = core.BNGetSymbolByRawName(self.handle, name, namespace)
if sym is None:
return None
return types.Symbol(None, None, None, handle = sym)
- def get_symbols_by_name(self, name):
+ def get_symbols_by_name(self, name, namespace=None):
"""
``get_symbols_by_name`` retrieves a list of Symbol objects for the given symbol name.
:param str name: name of Symbol object to be retrieved
:return: Symbol object corresponding to the provided name
+ :param NameSpace namespace: the namespace of the symbol
:rtype: Symbol
:Example:
@@ -2362,15 +2504,19 @@ class BinaryView(object):
[<FunctionSymbol: "public: static enum Foobar::foo __cdecl Foobar::testf(enum Foobar::foo)" @ 0x10001100>]
>>>
"""
+ if isinstance(namespace, str):
+ namespace = types.NameSpace(namespace)
+ if isinstance(namespace, types.NameSpace):
+ namespace = namespace._get_core_struct()
count = ctypes.c_ulonglong(0)
- syms = core.BNGetSymbolsByName(self.handle, name, count)
+ syms = core.BNGetSymbolsByName(self.handle, name, count, namespace)
result = []
for i in range(0, count.value):
result.append(types.Symbol(None, None, None, handle = core.BNNewSymbolReference(syms[i])))
core.BNFreeSymbolList(syms, count.value)
return result
- def get_symbols(self, start = None, length = None):
+ def get_symbols(self, start=None, length=None, namespace=None):
"""
``get_symbols`` retrieves the list of all Symbol objects in the optionally provided range.
@@ -2385,17 +2531,21 @@ class BinaryView(object):
>>>
"""
count = ctypes.c_ulonglong(0)
+ if isinstance(namespace, str):
+ namespace = types.NameSpace(namespace)
+ if isinstance(namespace, types.NameSpace):
+ namespace = namespace._get_core_struct()
if start is None:
- syms = core.BNGetSymbols(self.handle, count)
+ syms = core.BNGetSymbols(self.handle, count, namespace)
else:
- syms = core.BNGetSymbolsInRange(self.handle, start, length, count)
+ syms = core.BNGetSymbolsInRange(self.handle, start, length, count, namespace)
result = []
for i in range(0, count.value):
result.append(types.Symbol(None, None, None, handle = core.BNNewSymbolReference(syms[i])))
core.BNFreeSymbolList(syms, count.value)
return result
- def get_symbols_of_type(self, sym_type, start = None, length = None):
+ def get_symbols_of_type(self, sym_type, start=None, length=None, namespace=None):
"""
``get_symbols_of_type`` retrieves a list of all Symbol objects of the provided symbol type in the optionally
provided range.
@@ -2413,9 +2563,13 @@ class BinaryView(object):
"""
if isinstance(sym_type, str):
sym_type = SymbolType[sym_type]
+ if isinstance(namespace, str):
+ namespace = types.NameSpace(namespace)
+ if isinstance(namespace, types.NameSpace):
+ namespace = namespace._get_core_struct()
count = ctypes.c_ulonglong(0)
if start is None:
- syms = core.BNGetSymbolsOfType(self.handle, sym_type, count)
+ syms = core.BNGetSymbolsOfType(self.handle, sym_type, count, namespace)
else:
syms = core.BNGetSymbolsOfTypeInRange(self.handle, sym_type, start, length, count)
result = []
@@ -2424,18 +2578,24 @@ class BinaryView(object):
core.BNFreeSymbolList(syms, count.value)
return result
- def define_auto_symbol(self, sym):
+ def define_auto_symbol(self, sym, namespace=None):
"""
- ``define_auto_symbol`` adds a symbol to the internal list of automatically discovered Symbol objects.
+ ``define_auto_symbol`` adds a symbol to the internal list of automatically discovered Symbol objects in a given
+ namespace.
.. warning:: If multiple symbols for the same address are defined, only the most recent symbol will ever be used.
:param Symbol sym: the symbol to define
+ :param NameSpace namespace: the namespace of the symbol
:rtype: None
"""
- core.BNDefineAutoSymbol(self.handle, sym.handle)
+ if isinstance(namespace, str):
+ namespace = types.NameSpace(namespace)
+ if isinstance(namespace, types.NameSpace):
+ namespace = namespace._get_core_struct()
+ core.BNDefineAutoSymbol(self.handle, sym.handle, namespace)
- def define_auto_symbol_and_var_or_function(self, sym, sym_type, plat=None):
+ def define_auto_symbol_and_var_or_function(self, sym, sym_type, plat=None, namespace=None):
"""
``define_auto_symbol_and_var_or_function``
@@ -2444,6 +2604,7 @@ class BinaryView(object):
:param Symbol sym: the symbol to define
:param SymbolType sym_type: Type of symbol being defined
:param Platform plat: (optional) platform
+ :param NameSpace namespace: the namespace of the symbol
:rtype: None
"""
if plat is None:
@@ -2452,36 +2613,55 @@ class BinaryView(object):
plat = plat.handle
if sym_type is not None:
sym_type = sym_type.handle
- core.BNDefineAutoSymbolAndVariableOrFunction(self.handle, plat, sym.handle, sym_type)
+ if isinstance(namespace, str):
+ namespace = types.NameSpace(namespace)
+ if isinstance(namespace, types.NameSpace):
+ namespace = namespace._get_core_struct()
+ core.BNDefineAutoSymbolAndVariableOrFunction(self.handle, plat, sym.handle, sym_type, namespace)
- def undefine_auto_symbol(self, sym):
+ def undefine_auto_symbol(self, sym, namespace=None):
"""
``undefine_auto_symbol`` removes a symbol from the internal list of automatically discovered Symbol objects.
:param Symbol sym: the symbol to undefine
+ :param NameSpace namespace: the namespace of the symbol
:rtype: None
"""
- core.BNUndefineAutoSymbol(self.handle, sym.handle)
+ if isinstance(namespace, str):
+ namespace = types.NameSpace(namespace)
+ if isinstance(namespace, types.NameSpace):
+ namespace = namespace._get_core_struct()
+ core.BNUndefineAutoSymbol(self.handle, sym.handle, namespace)
- def define_user_symbol(self, sym):
+ def define_user_symbol(self, sym, namespace=None):
"""
``define_user_symbol`` adds a symbol to the internal list of user added Symbol objects.
.. warning:: If multiple symbols for the same address are defined, only the most recent symbol will ever be used.
:param Symbol sym: the symbol to define
+ :param NameSpace namespace: the namespace of the symbol
:rtype: None
"""
- core.BNDefineUserSymbol(self.handle, sym.handle)
+ if isinstance(namespace, str):
+ namespace = types.NameSpace(namespace)
+ if isinstance(namespace, types.NameSpace):
+ namespace = namespace._get_core_struct()
+ core.BNDefineUserSymbol(self.handle, sym.handle, namespace)
- def undefine_user_symbol(self, sym):
+ def undefine_user_symbol(self, sym, namespace=None):
"""
``undefine_user_symbol`` removes a symbol from the internal list of user added Symbol objects.
:param Symbol sym: the symbol to undefine
+ :param NameSpace namespace: the namespace of the symbol
:rtype: None
"""
- core.BNUndefineUserSymbol(self.handle, sym.handle)
+ if isinstance(namespace, str):
+ namespace = types.NameSpace(namespace)
+ if isinstance(namespace, types.NameSpace):
+ namespace = namespace._get_core_struct()
+ core.BNUndefineUserSymbol(self.handle, sym.handle, namespace)
def define_imported_function(self, import_addr_sym, func):
"""
@@ -3475,12 +3655,10 @@ class BinaryView(object):
core.BNRemoveUserSegment(self.handle, start, length)
def get_segment_at(self, addr):
- segment = core.BNSegment()
- if not core.BNGetSegmentAt(self.handle, addr, segment):
+ seg = core.BNGetSegmentAt(self.handle, addr)
+ if not seg:
return None
- result = Segment(segment.start, segment.length, segment.dataOffset, segment.dataLength,
- segment.flags, segment.autoDefined)
- return result
+ return Segment(seg)
def get_address_for_data_offset(self, offset):
address = ctypes.c_ulonglong()
@@ -3509,10 +3687,7 @@ class BinaryView(object):
section_list = core.BNGetSectionsAt(self.handle, addr, count)
result = []
for i in range(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].semantics, section_list[i].autoDefined))
+ result.append(Section(section_list[i]))
core.BNFreeSectionList(section_list, count.value)
return result
@@ -3520,9 +3695,7 @@ class BinaryView(object):
section = core.BNSection()
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.semantics,
- section.autoDefined)
+ result = Section(section)
core.BNFreeSection(section)
return result