summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter LaFosse <peter@vector35.com>2022-01-18 09:48:47 -0500
committerPeter LaFosse <peter@vector35.com>2022-01-19 10:53:46 -0500
commit6f5fd10c589cd7bf525d91a60a0dc66bc4f93e25 (patch)
treecb5d1f10dbc65bd5bd96e5b7eb6551190f8783d7
parent12b55e3265ea0538b911be910b8300af807c4695 (diff)
Many type check fixes
-rw-r--r--python/architecture.py36
-rw-r--r--python/basicblock.py148
-rw-r--r--python/binaryview.py46
-rw-r--r--python/databuffer.py11
-rw-r--r--python/demangle.py2
-rw-r--r--python/filemetadata.py2
-rw-r--r--python/function.py221
-rw-r--r--python/highlevelil.py30
-rw-r--r--python/lineardisassembly.py67
-rw-r--r--python/log.py2
-rw-r--r--python/lowlevelil.py123
-rw-r--r--python/mediumlevelil.py120
-rw-r--r--python/platform.py18
-rw-r--r--python/types.py26
-rw-r--r--python/variable.py15
15 files changed, 362 insertions, 505 deletions
diff --git a/python/architecture.py b/python/architecture.py
index 3201615b..fd9e28f1 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -509,10 +509,10 @@ class Architecture(metaclass=_ArchitectureMetaClass):
count = ctypes.c_ulonglong()
regs = core.BNGetFullWidthArchitectureRegisters(self.handle, count)
assert regs is not None, "core.BNGetFullWidthArchitectureRegisters returned None"
- result = []
+ result:List[RegisterName] = []
try:
for i in range(0, count.value):
- result.append(core.BNGetArchitectureRegisterName(self.handle, regs[i]))
+ result.append(RegisterName(core.BNGetArchitectureRegisterName(self.handle, regs[i])))
finally:
core.BNFreeRegisterList(regs)
return result
@@ -529,7 +529,7 @@ class Architecture(metaclass=_ArchitectureMetaClass):
obj = callingconvention.CallingConvention(handle=core.BNNewCallingConventionReference(cc[i]))
result[obj.name] = obj
finally:
- core.BNFreeCallingConventionList(cc, count)
+ core.BNFreeCallingConventionList(cc, count.value)
return result
@property
@@ -1173,10 +1173,10 @@ class Architecture(metaclass=_ArchitectureMetaClass):
buf = ctypes.cast(buf_raw, ctypes.c_void_p)
if buf.value not in self._pending_type_lists:
raise ValueError("freeing type list that wasn't allocated")
- types = self._pending_type_lists[buf.value][1]
+ _types = self._pending_type_lists[buf.value][1]
count = self._pending_type_lists[buf.value][2]
for i in range(0, count):
- core.BNFreeType(types[i].type)
+ core.BNFreeType(_types[i].type)
del self._pending_type_lists[buf.value]
except (ValueError, KeyError):
log_error(traceback.format_exc())
@@ -1425,7 +1425,7 @@ class Architecture(metaclass=_ArchitectureMetaClass):
result = core.BNGetArchitectureRegisterStackForRegister(self.handle, _reg)
if result == 0xffffffff:
return None
- return self.get_reg_stack_name(result)
+ return self.get_reg_stack_name(RegisterStackIndex(result))
def get_flag_name(self, flag:FlagIndex) -> FlagName:
"""
@@ -1465,7 +1465,7 @@ class Architecture(metaclass=_ArchitectureMetaClass):
def get_flag_index(self, flag:FlagType) -> FlagIndex:
if isinstance(flag, str):
- return self._flags[flag]
+ return self._flags[FlagName(flag)]
elif isinstance(flag, lowlevelil.ILFlag):
return flag.index
elif isinstance(flag, int):
@@ -1487,7 +1487,7 @@ class Architecture(metaclass=_ArchitectureMetaClass):
"""
``get_semantic_flag_class_name`` gets the name of a semantic flag class from the index.
- :param int _index: class_index
+ :param int class_index: class_index
:return: the name of the semantic flag class
:rtype: str
"""
@@ -1497,7 +1497,7 @@ class Architecture(metaclass=_ArchitectureMetaClass):
def get_semantic_flag_group_index(self, sem_group:SemanticGroupType) -> SemanticGroupIndex:
if isinstance(sem_group, str):
- return self._semantic_flag_groups[sem_group]
+ return self._semantic_flag_groups[SemanticGroupName(sem_group)]
elif isinstance(sem_group, lowlevelil.ILSemanticFlagGroup):
return sem_group.index
return sem_group
@@ -1609,6 +1609,7 @@ class Architecture(metaclass=_ArchitectureMetaClass):
:param LowLevelILOperation op:
:param int size:
:param str write_type:
+ :param FlagType flag:
:param operands: a list of either items that are either string register names or constant integer values
:type operands: list(str) or list(int)
:param LowLevelILFunction il:
@@ -1695,9 +1696,9 @@ class Architecture(metaclass=_ArchitectureMetaClass):
count = ctypes.c_ulonglong()
regs = core.BNGetModifiedArchitectureRegistersOnWrite(self.handle, reg, count)
assert regs is not None, "core.BNGetModifiedArchitectureRegistersOnWrite is not None"
- result = []
+ result:List[RegisterName] = []
for i in range(0, count.value):
- result.append(core.BNGetArchitectureRegisterName(self.handle, regs[i]))
+ result.append(RegisterName(core.BNGetArchitectureRegisterName(self.handle, regs[i])))
core.BNFreeRegisterList(regs)
return result
@@ -1865,10 +1866,10 @@ class Architecture(metaclass=_ArchitectureMetaClass):
:rtype: str
:Example:
- >>> bytes = arch.always_branch(arch.assemble("je 10"), 0)
- >>> arch.get_instruction_text(bytes, 0)
+ >>> data = arch.always_branch(arch.assemble("je 10"), 0)
+ >>> arch.get_instruction_text(data, 0)
(['nop', ' '], 1)
- >>> arch.get_instruction_text(bytes[1:], 0)
+ >>> arch.get_instruction_text(data[1:], 0)
(['jmp', ' ', '0x9'], 5)
>>>
"""
@@ -1940,7 +1941,7 @@ class Architecture(metaclass=_ArchitectureMetaClass):
:param str type_name: the BinaryView type name of the constant to be retrieved
:param str const_name: the constant name to retrieved
- :param int value: optional default value if the type_name is not present. default value is zero.
+ :param int default_value: optional default value if the type_name is not present. default value is zero.
:return: The BinaryView type constant or the default_value if not found
:rtype: int
:Example:
@@ -2527,8 +2528,8 @@ class CoreArchitecture(Architecture):
:rtype: str
:Example:
- >>> bytes = arch.always_branch(arch.assemble("je 10"), 0)
- >>> arch.get_instruction_text(bytes, 0)
+ >>> data = arch.always_branch(arch.assemble("je 10"), 0)
+ >>> arch.get_instruction_text(data, 0)
(['nop', ' '], 1)
>>> arch.get_instruction_text(bytes[1:], 0)
(['jmp', ' ', '0x9'], 5)
@@ -2576,6 +2577,7 @@ class CoreArchitecture(Architecture):
:param str data: bytes for the instruction to be converted
:param int addr: the virtual address of the instruction to be patched
+ :param int value: the value to return
:return: string containing len(data) which always branches to the same location as the provided instruction
:rtype: str
:Example:
diff --git a/python/basicblock.py b/python/basicblock.py
index 0fa16d12..c73fd604 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -130,7 +130,7 @@ class BasicBlock:
return self.arch.get_instruction_text(data, start)
def __contains__(self, i:int):
- return i >= self.start and i < self.end
+ return self.start <= i < self.end
def _buildStartCache(self) -> None:
if self._instStarts is None:
@@ -220,46 +220,39 @@ class BasicBlock:
"""Basic block index in list of blocks for the function (read-only)"""
return core.BNGetBasicBlockIndex(self.handle)
- @property
- def outgoing_edges(self) -> List[BasicBlockEdge]:
- """List of basic block outgoing edges (read-only)"""
- if self.view is None:
- raise Exception("Attempting to call BasicBlock.outgoing_edges when BinaryView is None")
- count = ctypes.c_ulonglong(0)
- edges = core.BNGetBasicBlockOutgoingEdges(self.handle, count)
- assert edges is not None, "core.BNGetBasicBlockOutgoingEdges returned None"
- result = []
+
+ def _make_edges(self, edges, count:int, direction:bool) -> List[BasicBlockEdge]:
+ assert edges is not None, "Got empty edges list from core"
+ assert self.view is not None, "Attempting to get BasicBlock edges when BinaryView is None"
+ result:List[BasicBlockEdge] = []
try:
- for i in range(0, count.value):
+ for i in range(0, count):
branch_type = BranchType(edges[i].type)
handle = core.BNNewBasicBlockReference(edges[i].target)
assert handle is not None
target = self._create_instance(handle, self.view)
- result.append(BasicBlockEdge(branch_type, self, target, edges[i].backEdge, edges[i].fallThrough))
+ if direction:
+ sink, source = target, self
+ else:
+ sink, source = self, target
+ result.append(BasicBlockEdge(branch_type, sink, source, edges[i].backEdge, edges[i].fallThrough))
return result
finally:
- core.BNFreeBasicBlockEdgeList(edges, count.value)
+ core.BNFreeBasicBlockEdgeList(edges, count)
+
+
+ @property
+ def outgoing_edges(self) -> List[BasicBlockEdge]:
+ """List of basic block outgoing edges (read-only)"""
+ count = ctypes.c_ulonglong(0)
+ return self._make_edges(core.BNGetBasicBlockOutgoingEdges(self.handle, count), count.value, False)
@property
def incoming_edges(self) -> List[BasicBlockEdge]:
"""List of basic block incoming edges (read-only)"""
count = ctypes.c_ulonglong(0)
- if self.view is None:
- raise Exception("Attempting to buildStartCache when BinaryView for BasicBlock is None")
+ return self._make_edges(core.BNGetBasicBlockIncomingEdges(self.handle, count), count.value, True)
- edges = core.BNGetBasicBlockIncomingEdges(self.handle, count)
- assert edges is not None, "core.BNGetBasicBlockIncomingEdges returned None"
- result = []
- try:
- for i in range(0, count.value):
- branch_type = BranchType(edges[i].type)
- handle = core.BNNewBasicBlockReference(edges[i].target)
- assert handle is not None
- target = self._create_instance(handle, self.view)
- result.append(BasicBlockEdge(branch_type, target, self, edges[i].backEdge, edges[i].fallThrough))
- return result
- finally:
- core.BNFreeBasicBlockEdgeList(edges, count.value)
@property
def has_undetermined_outgoing_edges(self) -> bool:
@@ -281,23 +274,26 @@ class BasicBlock:
"""Whether basic block has any invalid instructions (read-only)"""
return core.BNBasicBlockHasInvalidInstructions(self.handle)
- @property
- def dominators(self) -> List['BasicBlock']:
- """List of dominators for this basic block (read-only)"""
- if self.view is None:
- raise Exception("Attempting to call BasicBlock.dominators when BinaryView is None")
- count = ctypes.c_ulonglong()
- blocks = core.BNGetBasicBlockDominators(self.handle, count, False)
- assert blocks is not None, "core.BNGetBasicBlockDominators returned None"
- result = []
+ def _make_blocks(self, blocks, count:int) -> List['BasicBlock']:
+ assert blocks is not None, "core returned empty block list"
+ result:List['BasicBlock'] = []
try:
- for i in range(0, count.value):
+ for i in range(0, count):
handle = core.BNNewBasicBlockReference(blocks[i])
assert handle is not None
result.append(self._create_instance(handle, self.view))
return result
finally:
- core.BNFreeBasicBlockList(blocks, count.value)
+ core.BNFreeBasicBlockList(blocks, count)
+
+ @property
+ def dominators(self) -> List['BasicBlock']:
+ """List of dominators for this basic block (read-only)"""
+ if self.view is None:
+ raise Exception("Attempting to call BasicBlock.dominators when BinaryView is None")
+ count = ctypes.c_ulonglong()
+ return self._make_blocks(core.BNGetBasicBlockDominators(self.handle, count, False), count.value)
+
@property
def post_dominators(self) -> List['BasicBlock']:
@@ -305,17 +301,7 @@ class BasicBlock:
if self.view is None:
raise Exception("Attempting to call BasicBlock.post_dominators when BinaryView is None")
count = ctypes.c_ulonglong()
- blocks = core.BNGetBasicBlockDominators(self.handle, count, True)
- assert blocks is not None, "core.BNGetBasicBlockDominators returned None"
- result = []
- try:
- for i in range(0, count.value):
- handle = core.BNNewBasicBlockReference(blocks[i])
- assert handle is not None, "core.BNNewBasicBlockReference returned None"
- result.append(self._create_instance(handle, self.view))
- return result
- finally:
- core.BNFreeBasicBlockList(blocks, count.value)
+ return self._make_blocks(core.BNGetBasicBlockDominators(self.handle, count, True), count.value)
@property
def strict_dominators(self) -> List['BasicBlock']:
@@ -323,17 +309,7 @@ class BasicBlock:
if self.view is None:
raise Exception("Attempting to call BasicBlock.strict_dominators when BinaryView is None")
count = ctypes.c_ulonglong()
- blocks = core.BNGetBasicBlockStrictDominators(self.handle, count, False)
- assert blocks is not None, "core.BNGetBasicBlockStrictDominators returned None"
- result = []
- try:
- for i in range(0, count.value):
- handle = core.BNNewBasicBlockReference(blocks[i])
- assert handle is not None
- result.append(self._create_instance(handle, self.view))
- return result
- finally:
- core.BNFreeBasicBlockList(blocks, count.value)
+ return self._make_blocks(core.BNGetBasicBlockStrictDominators(self.handle, count, False), count.value)
@property
def immediate_dominator(self) -> Optional['BasicBlock']:
@@ -364,17 +340,7 @@ class BasicBlock:
raise Exception("Attempting to call BasicBlock.dominator_tree_children when BinaryView is None")
count = ctypes.c_ulonglong()
- blocks = core.BNGetBasicBlockDominatorTreeChildren(self.handle, count, False)
- assert blocks is not None, "core.BNGetBasicBlockDominatorTreeChildren returned None"
- result = []
- try:
- for i in range(0, count.value):
- handle = core.BNNewBasicBlockReference(blocks[i])
- assert handle is not None
- result.append(self._create_instance(handle, self.view))
- return result
- finally:
- core.BNFreeBasicBlockList(blocks, count.value)
+ return self._make_blocks(core.BNGetBasicBlockDominatorTreeChildren(self.handle, count, False), count.value)
@property
def post_dominator_tree_children(self) -> List['BasicBlock']:
@@ -383,17 +349,7 @@ class BasicBlock:
raise Exception("Attempting to call BasicBlock.post_dominator_tree_children when BinaryView is None")
count = ctypes.c_ulonglong()
- blocks = core.BNGetBasicBlockDominatorTreeChildren(self.handle, count, True)
- assert blocks is not None, "core.BNGetBasicBlockDominatorTreeChildren returned None"
- result = []
- try:
- for i in range(0, count.value):
- handle = core.BNNewBasicBlockReference(blocks[i])
- assert handle is not None
- result.append(self._create_instance(handle, self.view))
- return result
- finally:
- core.BNFreeBasicBlockList(blocks, count.value)
+ return self._make_blocks(core.BNGetBasicBlockDominatorTreeChildren(self.handle, count, True), count.value)
@property
def dominance_frontier(self) -> List['BasicBlock']:
@@ -402,17 +358,7 @@ class BasicBlock:
raise Exception("Attempting to call BasicBlock.dominance_frontier when BinaryView is None")
count = ctypes.c_ulonglong()
- blocks = core.BNGetBasicBlockDominanceFrontier(self.handle, count, False)
- assert blocks is not None, "core.BNGetBasicBlockDominanceFrontier returned None"
- result = []
- try:
- for i in range(0, count.value):
- handle = core.BNNewBasicBlockReference(blocks[i])
- assert handle is not None
- result.append(self._create_instance(handle, self.view))
- return result
- finally:
- core.BNFreeBasicBlockList(blocks, count.value)
+ return self._make_blocks(core.BNGetBasicBlockDominanceFrontier(self.handle, count, False), count.value)
@property
def post_dominance_frontier(self) -> List['BasicBlock']:
@@ -420,17 +366,7 @@ class BasicBlock:
if self.view is None:
raise Exception("Attempting to call BasicBlock.post_dominance_frontier when BinaryView is None")
count = ctypes.c_ulonglong()
- blocks = core.BNGetBasicBlockDominanceFrontier(self.handle, count, True)
- assert blocks is not None, "core.BNGetBasicBlockDominanceFrontier returned None"
- result = []
- try:
- for i in range(0, count.value):
- handle = core.BNNewBasicBlockReference(blocks[i])
- assert handle is not None
- result.append(self._create_instance(handle, self.view))
- return result
- finally:
- core.BNFreeBasicBlockList(blocks, count.value)
+ return self._make_blocks(core.BNGetBasicBlockDominanceFrontier(self.handle, count, True), count.value)
@property
def annotations(self) -> List[List['_function.InstructionTextToken']]:
@@ -564,7 +500,7 @@ class BasicBlock:
:param HighlightStandardColor or HighlightColor color: Color value to use for highlighting
:Example:
- >>> current_basic_block.set_user_highlight(HighlightColor(red=0xff, blue=0xff, green=0))
+ >>> current_basic_block.set_user_highlight(_highlight.HighlightColor(red=0xff, blue=0xff, green=0))
>>> current_basic_block.set_user_highlight(HighlightStandardColor.BlueHighlightColor)
"""
if not isinstance(color, HighlightStandardColor) and not isinstance(color, _highlight.HighlightColor):
diff --git a/python/binaryview.py b/python/binaryview.py
index b02f5d1a..e61e573c 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -894,7 +894,7 @@ class BinaryViewType(metaclass=_BinaryViewTypeMetaclass):
return bv
def parse(self, data:'BinaryView') -> Optional['BinaryView']:
- view = core.BNParseBinaryViewOfType(self.handle, data.handle)
+ view = core.BNParseBinaryViewOfType(self, data.handle)
if view is None:
return None
return BinaryView(file_metadata=data.file, handle=view)
@@ -1219,7 +1219,7 @@ class TagType:
@property
def type(self) -> TagTypeType:
"""Type from enums.TagTypeType"""
- return core.BNTagTypeGetType(self.handle)
+ return TagTypeType(core.BNTagTypeGetType(self.handle))
@type.setter
def type(self, value:TagTypeType) -> None:
@@ -2709,7 +2709,7 @@ class BinaryView:
"""
return 0
- def perform_remove(self, addr:int, length:bytes) -> int:
+ def perform_remove(self, addr:int, length:int) -> int:
"""
``perform_remove`` implements a mapping between a virtual address and an absolute file offset, removing
``length`` bytes from the rebased address ``addr``.
@@ -2719,7 +2719,7 @@ class BinaryView:
.. warning:: This method **must not** be called directly.
:param int addr: a virtual address
- :param bytes data: the data to be removed
+ :param int length: the number of bytes to be removed
:return: length of data removed, should return 0 on error
:rtype: int
"""
@@ -3097,8 +3097,7 @@ class BinaryView:
"""
if not (isinstance(data, bytes) or isinstance(data, bytearray) or isinstance(data, str)):
raise TypeError("Must be bytes, bytearray, or str")
- else:
- buf = databuffer.DataBuffer(data)
+ buf = databuffer.DataBuffer(data)
if except_on_relocation and self.range_contains_relocation(addr, addr + len(data)):
raise RelocationWriteException("Attempting to write to a location which has a relocation")
@@ -3585,7 +3584,7 @@ class BinaryView:
finally:
core.BNFreeFunctionList(funcs, count.value)
- def get_functions_by_name(self, name:str, plat:Optional['_platform.Platform']=None, ordered_filter:List[SymbolType]=[]) -> List['_function.Function']:
+ def get_functions_by_name(self, name:str, plat:Optional['_platform.Platform']=None, ordered_filter:Optional[List[SymbolType]]=None) -> List['_function.Function']:
"""``get_functions_by_name`` returns a list of Function objects
function with a Symbol of ``name``.
@@ -3600,10 +3599,11 @@ class BinaryView:
[<func: x86_64@0x1587>]
>>>
"""
- if ordered_filter == []:
+ if ordered_filter is None:
ordered_filter = [SymbolType.FunctionSymbol,
SymbolType.ImportedFunctionSymbol,
SymbolType.LibraryFunctionSymbol]
+
if plat == None:
plat = self.platform
fns = []
@@ -3913,7 +3913,7 @@ class BinaryView:
size = refs[i].size
typeObj = None
if refs[i].incomingType.type:
- typeObj = _types.Type(core.BNNewTypeReference(refs[i].incomingType.type),\
+ typeObj = _types.Type(core.BNNewTypeReference(refs[i].incomingType.type),
confidence = refs[i].incomingType.confidence)
yield _types.TypeFieldReference(func, arch, addr, size, typeObj)
finally:
@@ -4270,7 +4270,7 @@ class BinaryView:
try:
result = []
for i in range(0, count.value):
- typeObj = _types.Type.create(core.BNNewTypeReference(refs[i].type),\
+ typeObj = _types.Type.create(core.BNNewTypeReference(refs[i].type),
confidence = refs[i].confidence)
result.append(typeObj)
return result
@@ -4291,7 +4291,7 @@ class BinaryView:
if not result.type:
raise Exception("BNCreateStructureMemberFromAccess failed to create struct member offsets")
- return _types.Type.create(core.BNNewTypeReference(result.type),\
+ return _types.Type.create(core.BNNewTypeReference(result.type),
confidence = result.confidence)
def get_callers(self, addr:int) -> Generator[ReferenceSource, None, None]:
@@ -4405,7 +4405,7 @@ class BinaryView:
return None
return _types.CoreSymbol(sym)
- def get_symbols_by_name(self, name:str, namespace:'_types.NameSpaceType'=None, ordered_filter:List[SymbolType]=[]) -> List['_types.CoreSymbol']:
+ def get_symbols_by_name(self, name:str, namespace:'_types.NameSpaceType'=None, ordered_filter:Optional[List[SymbolType]]=None) -> List['_types.CoreSymbol']:
"""
``get_symbols_by_name`` retrieves a list of Symbol objects for the given symbol name and ordered filter
@@ -4421,7 +4421,7 @@ class BinaryView:
[<FunctionSymbol: "public: static enum Foobar::foo __cdecl Foobar::testf(enum Foobar::foo)" @ 0x10001100>]
>>>
"""
- if ordered_filter == []:
+ if ordered_filter is None:
ordered_filter = [SymbolType.FunctionSymbol,
SymbolType.ImportedFunctionSymbol,
SymbolType.LibraryFunctionSymbol,
@@ -4429,6 +4429,7 @@ class BinaryView:
SymbolType.ImportedDataSymbol,
SymbolType.ImportAddressSymbol,
SymbolType.ExternalSymbol]
+
_namespace = _types.NameSpace.get_core_struct(namespace)
count = ctypes.c_ulonglong(0)
syms = core.BNGetSymbolsByName(self.handle, name, count, _namespace)
@@ -4704,7 +4705,7 @@ class BinaryView:
``create_tag`` creates a new Tag object but does not add it anywhere.
Use :py:meth:`create_user_data_tag` to create and add in one step.
- :param TagType type: The Tag Type for this Tag
+ :param TagType tag_type: The Tag Type for this Tag
:param str data: Additional data for the Tag
:param bool user: Whether or not a user tag
:return: The created Tag
@@ -6456,7 +6457,7 @@ class BinaryView:
raise TypeError("settings parameter is not DisassemblySettings type")
result = ctypes.c_ulonglong()
- if not core.BNFindNextText(self.handle, start, text, result, settings.handle, flags,\
+ if not core.BNFindNextText(self.handle, start, text, result, settings.handle, flags,
graph_type):
return None
return result.value
@@ -6480,7 +6481,7 @@ class BinaryView:
raise TypeError("settings parameter is not DisassemblySettings type")
result = ctypes.c_ulonglong()
- if not core.BNFindNextConstant(self.handle, start, constant, result, settings.handle,\
+ if not core.BNFindNextConstant(self.handle, start, constant, result, settings.handle,
graph_type):
return None
return result.value
@@ -6803,7 +6804,7 @@ class BinaryView:
"""
core.BNShowHTMLReport(self.handle, title, contents, plaintext)
- def show_graph_report(self, title:int, graph:flowgraph.FlowGraph) -> None:
+ def show_graph_report(self, title:str, graph:flowgraph.FlowGraph) -> None:
"""
``show_graph_report`` displays a :py:Class:`FlowGraph` object `graph` in a new tab with ``title``.
@@ -7119,7 +7120,7 @@ class BinaryView:
result.append(names[i])
return result
finally:
- core.BNFreeStringList(names, count)
+ core.BNFreeStringList(names, count.value)
def get_load_settings(self, type_name:str) -> Optional[settings.Settings]:
"""
@@ -7277,7 +7278,7 @@ class BinaryReader:
:setter: sets the endianness of the reader (BigEndian or LittleEndian)
:type: Endianness
"""
- return core.BNGetBinaryReaderEndianness(self._handle)
+ return Endianness(core.BNGetBinaryReaderEndianness(self._handle))
@endianness.setter
def endianness(self, value:Endianness) -> None:
@@ -7667,11 +7668,11 @@ class BinaryWriter:
def offset(self, value:int) -> None:
core.BNSeekBinaryWriter(self._handle, value)
- def write(self, value, address:Optional[int]=None, except_on_relocation=True) -> bool:
+ def write(self, value:bytes, address:Optional[int]=None, except_on_relocation=True) -> bool:
"""
``write`` writes ``len(value)`` bytes to the internal offset, without regard to endianness.
- :param str value: bytes to be written at current offset
+ :param str bytes: bytes to be written at current offset
:param int address: offset to set the internal offset before writing
:param bool except_on_relocation: (default True) raise exception when write overlaps a relocation
:return: boolean True on success, False on failure.
@@ -7689,7 +7690,8 @@ class BinaryWriter:
if except_on_relocation and self._view.range_contains_relocation(self.offset, self.offset + len(value)):
raise RelocationWriteException("Attempting to write to a location which has a relocation")
- value = value.decode("utf-8")
+ if isinstance(value, str):
+ value = value.decode("utf-8")
buf = ctypes.create_string_buffer(len(value))
ctypes.memmove(buf, value, len(value))
return core.BNWriteData(self._handle, buf, len(value))
diff --git a/python/databuffer.py b/python/databuffer.py
index 9346f660..fea7bb82 100644
--- a/python/databuffer.py
+++ b/python/databuffer.py
@@ -26,7 +26,7 @@ from . import _binaryninjacore as core
DataBufferInputType = Union[str, bytes, 'DataBuffer', int]
class DataBuffer:
- def __init__(self, contents:bytes=b"", handle=None):
+ def __init__(self, contents:Union[str, bytes, 'DataBuffer', int]=b"", handle=None):
if handle is not None:
self.handle = core.handle_of_type(handle, core.BNDataBuffer)
elif isinstance(contents, int):
@@ -36,6 +36,7 @@ class DataBuffer:
elif isinstance(contents, str):
self.handle = core.BNCreateDataBuffer(contents.encode("utf-8"), len(contents.encode("utf-8")))
else:
+ assert isinstance(contents, bytes)
self.handle = core.BNCreateDataBuffer(contents, len(contents))
def __del__(self):
@@ -67,10 +68,10 @@ class DataBuffer:
return bytes(self)[i]
elif i < 0:
if i >= -len(self):
- return core.BNGetDataBufferByte(self.handle, int(len(self) + i))
+ return core.BNGetDataBufferByte(self.handle, int(len(self) + i)).to_bytes(1, "little")
raise IndexError("index out of range")
elif i < len(self):
- return core.BNGetDataBufferByte(self.handle, int(i))
+ return core.BNGetDataBufferByte(self.handle, int(i)).to_bytes(1, "little")
else:
raise IndexError("index out of range")
@@ -139,13 +140,13 @@ class DataBuffer:
return core.BNDataBufferToEscapedString(self.handle)
def unescape(self) -> 'DataBuffer':
- return DataBuffer(handle=core.BNDecodeEscapedString(bytes(self)))
+ return DataBuffer(handle=core.BNDecodeEscapedString(str(self)))
def base64_encode(self) -> str:
return core.BNDataBufferToBase64(self.handle)
def base64_decode(self) -> 'DataBuffer':
- return DataBuffer(handle = core.BNDecodeBase64(bytes(self)))
+ return DataBuffer(handle = core.BNDecodeBase64(str(self)))
def zlib_compress(self) -> Optional['DataBuffer']:
buf = core.BNZlibCompress(self.handle)
diff --git a/python/demangle.py b/python/demangle.py
index 6d8fba27..3f22d294 100644
--- a/python/demangle.py
+++ b/python/demangle.py
@@ -131,7 +131,7 @@ def simplify_name_to_qualified_name(input_name, simplify = True):
:param input_name: String or qualified name to be simplified
:type input_name: Union[str, QualifiedName]
- :param bool simplify_name: (optional) Whether to simplify input string (no effect if given a qualified name; will always simplify)
+ :param bool simplify: (optional) Whether to simplify input string (no effect if given a qualified name; will always simplify)
:return: simplified name (or one-element array containing the input if simplifier fails/cannot simplify)
:rtype: QualifiedName
:Example:
diff --git a/python/filemetadata.py b/python/filemetadata.py
index aea68bb6..c9f9a050 100644
--- a/python/filemetadata.py
+++ b/python/filemetadata.py
@@ -508,5 +508,5 @@ class FileMetadata:
views = []
for i in range(length.value):
views.append(result[i].decode("utf-8"))
- core.BNFreeStringList(result, length)
+ core.BNFreeStringList(result, length.value)
return views
diff --git a/python/function.py b/python/function.py
index d3b9ea88..3fbe90c0 100644
--- a/python/function.py
+++ b/python/function.py
@@ -21,8 +21,8 @@
import ctypes
import inspect
-from typing import Generator, Optional, List, Tuple, Union, Mapping, Any
-from dataclasses import dataclass, field
+from typing import Generator, Optional, List, Tuple, Union, Mapping, Any, Dict
+from dataclasses import dataclass
# Binary Ninja components
from . import _binaryninjacore as core
@@ -285,7 +285,7 @@ class TagList:
address = self._tags[self._n].addr
assert core_tag is not None, "core.BNNewTagReference returned None"
self._n += 1
- return (arch, address, binaryview.Tag(core_tag))
+ return arch, address, binaryview.Tag(core_tag)
def __getitem__(self, i:Union[int, slice]) -> Union[Tuple['architecture.Architecture', int, 'binaryview.Tag'], List[Tuple['architecture.Architecture', int, 'binaryview.Tag']]]:
if isinstance(i, int):
@@ -297,7 +297,7 @@ class TagList:
core_tag = core.BNNewTagReference(self._tags[i].tag)
arch = architecture.CoreArchitecture._from_cache(self._tags[i].arch)
assert core_tag is not None, "core.BNNewTagReference returned None"
- return (arch, self._tags[i].addr, binaryview.Tag(core_tag))
+ return arch, self._tags[i].addr, binaryview.Tag(core_tag)
elif isinstance(i, slice):
result = []
if i.start < 0 or i.start >= len(self) or i.stop < 0 or i.stop >= len(self):
@@ -314,6 +314,15 @@ class TagList:
class Function:
_associated_data = {}
+ """
+ The examples in the following code will use the following variables
+
+ >>> from binaryninja import *
+ >>> bv = binaryninja.binaryview.BinaryViewType.get_view_of_file("/bin/ls")
+ >>> current_function = bv.functions[0]
+ >>> here = current_function.start
+ """
+
def __init__(self, view:Optional['binaryview.BinaryView']=None, handle:Optional[core.BNFunctionHandle]=None):
self._advanced_analysis_requests = 0
@@ -533,7 +542,7 @@ class Function:
count = ctypes.c_ulonglong()
blocks = core.BNGetFunctionBasicBlockList(self.handle, count)
assert blocks is not None, "core.BNGetFunctionBasicBlockList returned None"
- return (count, blocks)
+ return count, blocks
def _instantiate_block(self, handle):
return basicblock.BasicBlock(handle, self.view)
@@ -571,6 +580,7 @@ class Function:
:param TagType type: The Tag Type for this Tag
:param str data: Additional data for the Tag
+ :param bool user: Boolean indicating if this is a user tag or not
:return: The created Tag
:rtype: Tag
:Example:
@@ -1216,7 +1226,7 @@ class Function:
@comment.setter
def comment(self, comment:str) -> None:
"""Sets a comment for the current function"""
- return core.BNSetFunctionComment(self.handle, comment)
+ core.BNSetFunctionComment(self.handle, comment)
@property
def llil_basic_blocks(self) -> Generator['lowlevelil.LowLevelILBasicBlock', None, None]:
@@ -1236,7 +1246,7 @@ class Function:
for block in self.basic_blocks:
start = block.start
for i in block:
- yield (i[0], start)
+ yield i[0], start
start += i[1]
@property
@@ -1435,7 +1445,7 @@ class Function:
from_arch = self.arch
_name = types.QualifiedName(name)._to_core_struct()
- core.BNAddUserTypeFieldReference(self.handle, from_arch.handle, from_addr, _name,\
+ core.BNAddUserTypeFieldReference(self.handle, from_arch.handle, from_addr, _name,
offset, size)
def remove_user_type_field_ref(self, from_addr:int, name:'types.QualifiedNameType', offset:int,
@@ -1463,7 +1473,7 @@ class Function:
from_arch = self.arch
_name = types.QualifiedName(name)._to_core_struct()
- core.BNRemoveUserTypeFieldReference(self.handle, from_arch.handle, from_addr, _name,\
+ core.BNRemoveUserTypeFieldReference(self.handle, from_arch.handle, from_addr, _name,
offset, size)
def get_low_level_il_at(self, addr:int, arch:Optional['architecture.Architecture']=None) -> Optional['lowlevelil.LowLevelILInstruction']:
@@ -1567,7 +1577,7 @@ class Function:
:rtype: variable.RegisterValue
:Example:
- >>> func.get_reg_value_at(0x400dbe, 'rdi')
+ >>> current_function.get_reg_value_at(0x400dbe, 'rdi')
<const 0x2>
"""
if arch is None:
@@ -1580,7 +1590,7 @@ class Function:
return result
@property
- def auto_address_tags(self) -> List['binaryview.Tag']:
+ def auto_address_tags(self) -> List[Tuple['architecture.Architecture', int, 'binaryview.Tag']]:
"""
``auto_address_tags`` gets a list of all auto-defined address Tags in the function.
Tags are returned as a list of (arch, address, Tag) tuples.
@@ -1632,12 +1642,11 @@ class Function:
:rtype: variable.RegisterValue
:Example:
- >>> func.get_reg_value_after(0x400dbe, 'rdi')
+ >>> current_function.get_reg_value_after(0x400dbe, 'rdi')
<undetermined>
"""
if arch is None:
- if self.arch is None:
- raise Exception("Can't call get_reg_value_after for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
reg = arch.get_reg_index(reg)
value = core.BNGetRegisterValueAfterInstruction(self.handle, arch.handle, addr, reg)
@@ -1654,8 +1663,7 @@ class Function:
:rtype: list(Tag)
"""
if arch is None:
- if self.arch is None:
- raise Exception("Can't call get_auto_address_tags_at for function with no architecture specified")
+ assert self.arch is not None, "Can't call get_auto_address_tags_at for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
tags = core.BNGetAutoAddressTags(self.handle, arch.handle, addr, count)
@@ -1678,8 +1686,7 @@ class Function:
:rtype: list(Tag)
"""
if arch is None:
- if self.arch is None:
- raise Exception("Can't call get_user_address_tags_at for function with no architecture specified")
+ assert self.arch is not None, "Can't call get_user_address_tags_at for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
tags = core.BNGetUserAddressTags(self.handle, arch.handle, addr, count)
@@ -1703,9 +1710,8 @@ class Function:
:rtype: list(Tag)
"""
if arch is None:
- if self.arch is None:
- raise Exception("Can't call get_address_tags_of_type for function with no architecture specified")
- arch = self.arch
+ assert self.arch is not None, "Can't call get_address_tags_of_type for function with no architecture specified"
+ arch = self.arch
count = ctypes.c_ulonglong()
tags = core.BNGetAddressTagsOfType(self.handle, arch.handle, addr, tag_type.handle, count)
assert tags is not None, "core.BNGetAddressTagsOfType returned None"
@@ -1728,8 +1734,7 @@ class Function:
:rtype: list(Tag)
"""
if arch is None:
- if self.arch is None:
- raise Exception("Can't call get_auto_address_tags_of_type for function with no architecture specified")
+ assert self.arch is not None, "Can't call get_auto_address_tags_of_type for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
tags = core.BNGetAutoAddressTagsOfType(self.handle, arch.handle, addr, tag_type.handle, count)
@@ -1753,8 +1758,7 @@ class Function:
:rtype: list(Tag)
"""
if arch is None:
- if self.arch is None:
- raise Exception("Can't call get_user_address_tags_of_type for function with no architecture specified")
+ assert self.arch is not None, "Can't get_user_address_tags_of_type for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
tags = core.BNGetUserAddressTagsOfType(self.handle, arch.handle, addr, tag_type.handle, count)
@@ -1778,8 +1782,7 @@ class Function:
:rtype: list((Architecture, int, Tag))
"""
if arch is None:
- if self.arch is None:
- raise Exception("Can't call get_address_tags_in_range for function with no architecture specified")
+ assert self.arch is not None, "Can't call get_address_tags_in_range for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
refs = core.BNGetAddressTagsInRange(self.handle, arch.handle, address_range.start, address_range.end, count)
@@ -1804,8 +1807,7 @@ class Function:
:rtype: list((Architecture, int, Tag))
"""
if arch is None:
- if self.arch is None:
- raise Exception("Can't call get_auto_address_tags_in_range for function with no architecture specified")
+ assert self.arch is not None, "Can't call get_auto_address_tags_in_range for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
refs = core.BNGetAutoAddressTagsInRange(self.handle, arch.handle, address_range.start, address_range.end, count)
@@ -1830,8 +1832,7 @@ class Function:
:rtype: list((Architecture, int, Tag))
"""
if arch is None:
- if self.arch is None:
- raise Exception("Can't call get_user_address_tags_in_range for function with no architecture specified")
+ assert self.arch is not None, "Can't call get_user_address_tags_in_range for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
refs = core.BNGetUserAddressTagsInRange(self.handle, arch.handle, address_range.start, address_range.end, count)
@@ -1862,12 +1863,11 @@ class Function:
:Example:
- >>> func.get_stack_contents_at(0x400fad, -16, 4)
+ >>> current_function.get_stack_contents_at(0x400fad, -16, 4)
<range: 0x8 to 0xffffffff>
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
value = core.BNGetStackContentsAtInstruction(self.handle, arch.handle, addr, offset, size)
result = variable.RegisterValue.from_BNRegisterValue(value, arch)
@@ -1876,8 +1876,7 @@ class Function:
def get_stack_contents_after(self, addr:int, offset:int, size:int,
arch:Optional['architecture.Architecture']=None) -> 'variable.RegisterValue':
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
value = core.BNGetStackContentsAfterInstruction(self.handle, arch.handle, addr, offset, size)
result = variable.RegisterValue.from_BNRegisterValue(value, arch)
@@ -1886,8 +1885,7 @@ class Function:
def get_parameter_at(self, addr:int, func_type:Optional['types.Type'], i:int,
arch:Optional['architecture.Architecture']=None) -> 'variable.RegisterValue':
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
_func_type = None
@@ -1908,8 +1906,7 @@ class Function:
:rtype: None
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
core.BNRemoveUserAddressTagsOfType(self.handle, arch.handle, addr, tag_type.handle)
@@ -1924,8 +1921,7 @@ class Function:
def get_regs_read_by(self, addr:int, arch:Optional['architecture.Architecture']=None) -> List['architecture.RegisterName']:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
regs = core.BNGetRegistersReadByInstruction(self.handle, arch.handle, addr, count)
@@ -1938,8 +1934,7 @@ class Function:
def get_regs_written_by(self, addr:int, arch:Optional['architecture.Architecture']=None) -> List['architecture.RegisterName']:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
regs = core.BNGetRegistersWrittenByInstruction(self.handle, arch.handle, addr, count)
@@ -1960,8 +1955,7 @@ class Function:
:rtype: None
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call remove_auto_address_tag with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
core.BNRemoveAutoAddressTag(self.handle, arch.handle, addr, tag.handle)
@@ -1975,16 +1969,14 @@ class Function:
:rtype: None
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
core.BNRemoveAutoAddressTagsOfType(self.handle, arch.handle, addr, tag_type.handle)
def get_stack_vars_referenced_by(self, addr:int,
arch:Optional['architecture.Architecture']=None) -> List['variable.StackVariableReference']:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
refs = core.BNGetStackVariablesReferencedByInstruction(self.handle, arch.handle, addr, count)
@@ -2037,8 +2029,7 @@ class Function:
def get_lifted_il_at(self, addr:int,
arch:Optional['architecture.Architecture']=None) -> Optional['lowlevelil.LowLevelILInstruction']:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
idx = core.BNGetLiftedILForInstruction(self.handle, arch.handle, addr)
@@ -2062,8 +2053,7 @@ class Function:
[<il: push(rbp)>]
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
instrs = core.BNGetLiftedILInstructionsForAddress(self.handle, arch.handle, addr, count)
@@ -2144,8 +2134,7 @@ class Function:
def get_constants_referenced_by(self, addr:int,
arch:'architecture.Architecture'=None) -> List[variable.ConstantReference]:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call get_constants_referenced_by with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
refs = core.BNGetConstantsReferencedByInstruction(self.handle, arch.handle, addr, count)
@@ -2176,8 +2165,7 @@ class Function:
def get_lifted_il_flag_uses_for_definition(self, i:'lowlevelil.InstructionIndex',
flag:'architecture.FlagType') -> List['lowlevelil.LowLevelILInstruction']:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
flag = self.arch.get_flag_index(flag)
count = ctypes.c_ulonglong()
instrs = core.BNGetLiftedILFlagUsesForDefinition(self.handle, i, flag, count)
@@ -2190,8 +2178,7 @@ class Function:
def get_lifted_il_flag_definitions_for_use(self, i:'lowlevelil.InstructionIndex',
flag:'architecture.FlagType') -> List['lowlevelil.InstructionIndex']:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
flag = self.arch.get_flag_index(flag)
count = ctypes.c_ulonglong()
@@ -2204,9 +2191,8 @@ class Function:
return result
def get_flags_read_by_lifted_il_instruction(self, i:'lowlevelil.InstructionIndex') -> \
- List['architecture.RegisterName']:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ List['architecture.FlagName']:
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
count = ctypes.c_ulonglong()
flags = core.BNGetFlagsReadByLiftedILInstruction(self.handle, i, count)
@@ -2220,8 +2206,7 @@ class Function:
def get_flags_written_by_lifted_il_instruction(self, i:'lowlevelil.InstructionIndex') -> \
List['architecture.FlagName']:
count = ctypes.c_ulonglong()
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
flags = core.BNGetFlagsWrittenByLiftedILInstruction(self.handle, i, count)
assert flags is not None, "core.BNGetFlagsWrittenByLiftedILInstruction returned None"
@@ -2252,8 +2237,7 @@ class Function:
def set_auto_indirect_branches(self, source:int, branches:List[Tuple['architecture.Architecture', int]],
source_arch:Optional['architecture.Architecture']=None) -> None:
if source_arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
source_arch = self.arch
branch_list = (core.BNArchitectureAndAddress * len(branches))()
for i in range(len(branches)):
@@ -2264,8 +2248,7 @@ class Function:
def set_user_indirect_branches(self, source:int, branches:List[Tuple['architecture.Architecture', int]],
source_arch:Optional['architecture.Architecture']=None) -> None:
if source_arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
source_arch = self.arch
branch_list = (core.BNArchitectureAndAddress * len(branches))()
for i in range(len(branches)):
@@ -2275,8 +2258,7 @@ class Function:
def get_indirect_branches_at(self, addr:int, arch:Optional['architecture.Architecture']=None) -> List['variable.IndirectBranchInfo']:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
branches = core.BNGetIndirectBranchesAt(self.handle, arch.handle, addr, count)
@@ -2448,8 +2430,7 @@ class Function:
:param Architecture arch: (optional) Architecture of the instruction or IL line containing the token
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
return IntegerDisplayType(core.BNGetIntegerConstantDisplayType(self.handle, arch.handle, instr_addr, value, operand))
@@ -2463,8 +2444,7 @@ class Function:
:param Architecture arch: (optional) Architecture of the instruction or IL line containing the token
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
if isinstance(display_type, str):
display_type = IntegerDisplayType[display_type]
@@ -2498,8 +2478,7 @@ class Function:
<block: x86_64@0x100000f30-0x100000f50>
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
block = core.BNGetFunctionBasicBlockAtAddress(self.handle, arch.handle, addr)
if not block:
@@ -2514,8 +2493,7 @@ class Function:
<color: #ff00ff>
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
color = core.BNGetInstructionHighlight(self.handle, arch.handle, addr)
if color.style == HighlightColorStyle.StandardHighlightColor:
@@ -2538,8 +2516,7 @@ class Function:
:param Architecture arch: (optional) Architecture of the instruction if different from self.arch
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
if not isinstance(color, HighlightStandardColor) and not isinstance(color, _highlight.HighlightColor):
raise ValueError("Specified color is not one of HighlightStandardColor, _highlight.HighlightColor")
@@ -2562,8 +2539,7 @@ class Function:
>>> current_function.set_user_instr_highlight(here, highlight.HighlightColor(red=0xff, blue=0xff, green=0))
"""
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
if not isinstance(color, HighlightStandardColor) and not isinstance(color, _highlight.HighlightColor):
raise ValueError("Specified color is not one of HighlightStandardColor, highlight.HighlightColor")
@@ -2612,8 +2588,7 @@ class Function:
def get_stack_var_at_frame_offset(self, offset:int, addr:int, arch:Optional['architecture.Architecture']=None) -> \
Optional['variable.Variable']:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
found_var = core.BNVariableNameAndType()
if not core.BNGetStackVariableAtFrameOffset(self.handle, arch.handle, addr, offset, found_var):
@@ -2645,21 +2620,19 @@ class Function:
result = core.BNGetFunctionRegisterValueAtExit(self.handle, self.arch.get_reg_index(reg))
return variable.RegisterValue.from_BNRegisterValue(result, self.arch)
- def set_auto_call_stack_adjustment(self, addr:int, adjust:Union[int, 'types.SizeWithConfidence'],\
+ def set_auto_call_stack_adjustment(self, addr:int, adjust:Union[int, 'types.SizeWithConfidence'],
arch:Optional['architecture.Architecture']=None) -> None:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
if not isinstance(adjust, types.SizeWithConfidence):
adjust = types.SizeWithConfidence(adjust)
core.BNSetAutoCallStackAdjustment(self.handle, arch.handle, addr, adjust.value, adjust.confidence)
- def set_auto_call_reg_stack_adjustment(self, addr:int, adjust:Mapping['architecture.RegisterStackName', int],\
+ def set_auto_call_reg_stack_adjustment(self, addr:int, adjust:Mapping['architecture.RegisterStackName', int],
arch:Optional['architecture.Architecture']=None) -> None:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
adjust_buf = (core.BNRegisterStackAdjustment * len(adjust))()
i = 0
@@ -2676,8 +2649,7 @@ class Function:
def set_auto_call_reg_stack_adjustment_for_reg_stack(self, addr:int, reg_stack:'architecture.RegisterStackType',
adjust, arch:Optional['architecture.Architecture']=None) -> None:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
reg_stack = arch.get_reg_stack_index(reg_stack)
if not isinstance(adjust, types.RegisterStackAdjustmentWithConfidence):
@@ -2690,8 +2662,7 @@ class Function:
if isinstance(adjust_type, str):
(adjust_type, _) = self.view.parse_type_string(adjust_type)
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
if adjust_type is None:
tc = None
@@ -2702,8 +2673,7 @@ class Function:
def set_call_stack_adjustment(self, addr:int, adjust:Union[int, 'types.SizeWithConfidence'],
arch:Optional['architecture.Architecture']=None):
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
if not isinstance(adjust, types.SizeWithConfidence):
adjust = types.SizeWithConfidence(adjust)
@@ -2713,8 +2683,7 @@ class Function:
adjust:Mapping['architecture.RegisterStackName', 'types.RegisterStackAdjustmentWithConfidence'],
arch:Optional['architecture.Architecture']=None) -> None:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
adjust_buf = (core.BNRegisterStackAdjustment * len(adjust))()
i = 0
@@ -2722,7 +2691,7 @@ class Function:
adjust_buf[i].regStack = arch.get_reg_stack_index(reg_stack)
value = adjust[reg_stack]
if not isinstance(value, types.RegisterStackAdjustmentWithConfidence):
- value = types.RegisterStackAdjustmentWithConfidence(value)
+ value = types.RegisterStackAdjustmentWithConfidence(int(value))
adjust_buf[i].adjustment = value.value
adjust_buf[i].confidence = value.confidence
i += 1
@@ -2731,8 +2700,7 @@ class Function:
def set_call_reg_stack_adjustment_for_reg_stack(self, addr:int, reg_stack:'architecture.RegisterStackType',
adjust:Union[int, 'types.RegisterStackAdjustmentWithConfidence'], arch:Optional['architecture.Architecture']=None) -> None:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
reg_stack = arch.get_reg_stack_index(reg_stack)
if not isinstance(adjust, types.RegisterStackAdjustmentWithConfidence):
@@ -2742,8 +2710,7 @@ class Function:
def get_call_type_adjustment(self, addr:int, arch:Optional['architecture.Architecture']=None) -> Optional['types.Type']:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
result = core.BNGetCallTypeAdjustment(self.handle, arch.handle, addr)
if not result.type:
@@ -2753,17 +2720,15 @@ class Function:
def get_call_stack_adjustment(self, addr:int, arch:Optional['architecture.Architecture']=None) -> 'types.SizeWithConfidence':
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
result = core.BNGetCallStackAdjustment(self.handle, arch.handle, addr)
return types.SizeWithConfidence(result.value, confidence = result.confidence)
def get_call_reg_stack_adjustment(self, addr:int, arch:Optional['architecture.Architecture']=None) -> \
- Mapping['architecture.RegisterName', 'types.RegisterStackAdjustmentWithConfidence']:
+ Dict['architecture.RegisterStackName', 'types.RegisterStackAdjustmentWithConfidence']:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
count = ctypes.c_ulonglong()
adjust = core.BNGetCallRegisterStackAdjustment(self.handle, arch.handle, addr, count)
@@ -2775,11 +2740,10 @@ class Function:
core.BNFreeRegisterStackAdjustments(adjust)
return result
- def get_call_reg_stack_adjustment_for_reg_stack(self, addr:int, reg_stack:'architecture.RegisterStackType',\
+ def get_call_reg_stack_adjustment_for_reg_stack(self, addr:int, reg_stack:'architecture.RegisterStackType',
arch:Optional['architecture.Architecture']=None) -> 'types.RegisterStackAdjustmentWithConfidence':
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
reg_stack = arch.get_reg_stack_index(reg_stack)
adjust = core.BNGetCallRegisterStackAdjustmentForRegisterStack(self.handle, arch.handle, addr, reg_stack)
@@ -2788,8 +2752,7 @@ class Function:
def is_call_instruction(self, addr:int, arch:Optional['architecture.Architecture']=None) -> bool:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
return core.BNIsCallInstruction(self.handle, arch.handle, addr)
@@ -2810,10 +2773,10 @@ class Function:
:Example:
- >>> var = current_mlil[0].operands[0]
- >>> def_site = 0x40108d
- >>> value = PossibleValueSet.constant(5)
- >>> current_function.set_user_var_value(var, def_site, value)
+ >>> mlil_var = current_mlil[0].operands[0]
+ >>> def_address = 0x40108d
+ >>> var_value = PossibleValueSet.constant(5)
+ >>> current_function.set_user_var_value(mlil_var, def_address, var_value)
"""
if self.arch is None:
raise Exception("can not set_user_var_value if Function.arch is None")
@@ -2872,7 +2835,6 @@ class Function:
var_values = core.BNGetAllUserVariableValues(self.handle, count)
assert var_values is not None, "core.BNGetAllUserVariableValues returned None"
result = {}
- i = 0
for i in range(count.value):
var_val = var_values[i]
var = variable.Variable.from_BNVariable(self, var_val.var)
@@ -2968,7 +2930,7 @@ class Function:
return result
@property
- def callers(self) -> List[int]:
+ def callers(self) -> List['Function']:
"""
``callers`` returns a list of functions that call this function
Does not point to the actual address where the call occurs, just the start of the function that contains the call.
@@ -3003,8 +2965,8 @@ class Function:
:rtype: list(ILReferenceSource)
:Example:
- >>> var = current_mlil[0].operands[0]
- >>> current_function.get_mlil_var_refs(var)
+ >>> mlil_var = current_mlil[0].operands[0]
+ >>> current_function.get_mlil_var_refs(mlil_var)
"""
count = ctypes.c_ulonglong(0)
refs = core.BNGetMediumLevelILVariableReferences(self.handle, var.to_BNVariable(), count)
@@ -3046,8 +3008,7 @@ class Function:
count = ctypes.c_ulonglong(0)
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
if length is None:
@@ -3083,8 +3044,8 @@ class Function:
:rtype: list(ILReferenceSource)
:Example:
- >>> var = current_hlil[0].operands[0]
- >>> current_function.get_hlil_var_refs(var)
+ >>> mlil_var = current_hlil[0].operands[0]
+ >>> current_function.get_hlil_var_refs(mlil_var)
"""
count = ctypes.c_ulonglong(0)
refs = core.BNGetHighLevelILVariableReferences(self.handle, var.to_BNVariable(), count)
@@ -3149,8 +3110,7 @@ class Function:
def get_instruction_containing_address(self, addr:int, arch:Optional['architecture.Architecture']=None) -> \
Optional[int]:
if arch is None:
- if self.arch is None:
- raise Exception(f"Can't call {_function_name_()} for function with no architecture specified")
+ assert self.arch is not None, f"Can't call {_function_name_()} for function with no architecture specified"
arch = self.arch
start = ctypes.c_ulonglong()
@@ -3281,7 +3241,7 @@ class DisassemblyTextRenderer:
return architecture.CoreArchitecture._from_cache(handle = core.BNGetDisassemblyTextRendererArchitecture(self.handle))
@arch.setter
- def arch(self, arch='architecture.Architecture') -> None:
+ def arch(self, arch:'architecture.Architecture') -> None:
core.BNSetDisassemblyTextRendererArchitecture(self.handle, arch.handle)
@property
@@ -3384,7 +3344,6 @@ class DisassemblyTextRenderer:
line_buf[i].count = len(line.tokens)
line_buf[i].tokens = InstructionTextToken._get_core_struct(line.tokens)
count = ctypes.c_ulonglong()
- lines = ctypes.POINTER(core.BNDisassemblyTextLine)()
lines = core.BNPostProcessDisassemblyTextRendererLines(self.handle, addr, length, line_buf, len(in_lines), count, indent_spaces)
assert lines is not None, "core.BNPostProcessDisassemblyTextRendererLines returned None"
il_function = self.il_function
@@ -3443,7 +3402,7 @@ class DisassemblyTextRenderer:
@staticmethod
def is_integer_token(token:'InstructionTextToken') -> bool:
- return core.BNIsIntegerToken(token)
+ return core.BNIsIntegerToken(token.type)
def add_integer_token(self, tokens:List['InstructionTextToken'], int_token:'InstructionTextToken', addr:int,
arch:Optional['architecture.Architecture']=None) -> None:
diff --git a/python/highlevelil.py b/python/highlevelil.py
index 4298e91f..b757727d 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -20,7 +20,7 @@
import ctypes
import struct
-from typing import Optional, Generator, List, Union, Any, NewType, Tuple, ClassVar, Mapping
+from typing import Optional, Generator, List, Union, NewType, Tuple, ClassVar, Mapping
from dataclasses import dataclass
from enum import Enum
@@ -37,7 +37,6 @@ from . import types
from . import highlight
from . import flowgraph
from . import variable
-from .log import log_info
from .interaction import show_graph_report
from .commonil import (BaseILInstruction, Call, Tailcall, Syscall, Comparison, Signed, UnaryOperation, BinaryOperation,
SSA, Phi, Loop, ControlFlow, Memory, Constant, Arithmetic, DoublePrecision, Terminal,
@@ -490,7 +489,7 @@ class HighLevelILInstruction(BaseILInstruction):
"""SSA form of expression (read-only)"""
assert self.function.ssa_form is not None
return HighLevelILInstruction.create(self.function.ssa_form,
- core.BNGetHighLevelILSSAExprIndex(self.function.handle, self.expr_index), self.as_ast)
+ ExpressionIndex(core.BNGetHighLevelILSSAExprIndex(self.function.handle, self.expr_index)), self.as_ast)
@property
def non_ssa_form(self) -> Optional['HighLevelILInstruction']:
@@ -498,7 +497,7 @@ class HighLevelILInstruction(BaseILInstruction):
if self.function.non_ssa_form is None:
return None
return HighLevelILInstruction.create(self.function.non_ssa_form,
- core.BNGetHighLevelILNonSSAExprIndex(self.function.handle, self.expr_index), self.as_ast)
+ ExpressionIndex(core.BNGetHighLevelILNonSSAExprIndex(self.function.handle, self.expr_index)), self.as_ast)
@property
def medium_level_il(self) -> Optional['mediumlevelil.MediumLevelILInstruction']:
@@ -592,10 +591,12 @@ class HighLevelILInstruction(BaseILInstruction):
return types.Type.create(core.BNNewTypeReference(result.type), platform = platform, confidence = result.confidence)
return None
- def get_possible_values(self, options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
+ def get_possible_values(self, options:Optional[List[DataFlowQueryOption]]=None) -> 'variable.PossibleValueSet':
mlil = self.mlil
if mlil is None:
return variable.PossibleValueSet()
+ if options is None:
+ options = []
return mlil.get_possible_values(options)
@property
@@ -2123,7 +2124,7 @@ class HighLevelILFunction:
raise IndexError("index out of range")
if i < 0:
i = len(self) + i
- return HighLevelILInstruction.create(self, core.BNGetHighLevelILIndexForInstruction(self.handle, i), False,
+ return HighLevelILInstruction.create(self, ExpressionIndex(core.BNGetHighLevelILIndexForInstruction(self.handle, i)), False,
InstructionIndex(i))
def __setitem__(self, i, j):
@@ -2167,7 +2168,7 @@ class HighLevelILFunction:
expr_index = core.BNGetHighLevelILRootExpr(self.handle)
if expr_index >= core.BNGetHighLevelILExprCount(self.handle):
return None
- return HighLevelILInstruction.create(self, expr_index)
+ return HighLevelILInstruction.create(self, ExpressionIndex(expr_index))
@root.setter
def root(self, value:HighLevelILInstruction) -> None:
@@ -2177,7 +2178,7 @@ class HighLevelILFunction:
count = ctypes.c_ulonglong()
blocks = core.BNGetHighLevelILBasicBlockList(self.handle, count)
assert blocks is not None, "core.BNGetHighLevelILBasicBlockList returned None"
- return (count, blocks)
+ return count, blocks
def _instantiate_block(self, handle):
return HighLevelILBasicBlock(handle, self, self.view)
@@ -2249,13 +2250,13 @@ class HighLevelILFunction:
result = core.BNGetHighLevelILSSAVarDefinition(self.handle, var_data, ssa_var.version)
if result >= core.BNGetHighLevelILExprCount(self.handle):
return None
- return HighLevelILInstruction.create(self, result)
+ return HighLevelILInstruction.create(self, ExpressionIndex(result))
def get_ssa_memory_definition(self, version:int) -> Optional[HighLevelILInstruction]:
result = core.BNGetHighLevelILSSAMemoryDefinition(self.handle, version)
if result >= core.BNGetHighLevelILExprCount(self.handle):
return None
- return HighLevelILInstruction.create(self, result)
+ return HighLevelILInstruction.create(self, ExpressionIndex(result))
def get_ssa_var_uses(self, ssa_var:'mediumlevelil.SSAVariable') -> List[HighLevelILInstruction]:
count = ctypes.c_ulonglong()
@@ -2335,7 +2336,8 @@ class HighLevelILFunction:
d:int = 0, e:int = 0, size:int = 0) -> ExpressionIndex:
if isinstance(operation, str):
operation_value = HighLevelILOperation[operation]
- elif isinstance(operation, HighLevelILOperation):
+ else:
+ assert isinstance(operation, HighLevelILOperation)
operation_value = operation.value
return ExpressionIndex(core.BNHighLevelILAddExpr(self.handle, operation_value, size, a, b, c, d, e))
@@ -2450,7 +2452,7 @@ class HighLevelILFunction:
result = core.BNGetMediumLevelILExprIndexFromHighLevelIL(self.handle, expr)
if result >= core.BNGetMediumLevelILExprCount(medium_il.handle):
return None
- return result
+ return mediumlevelil.ExpressionIndex(result)
def get_medium_level_il_expr_indexes(self, expr:ExpressionIndex) -> List['mediumlevelil.ExpressionIndex']:
count = ctypes.c_ulonglong()
@@ -2466,7 +2468,7 @@ class HighLevelILFunction:
result = core.BNGetHighLevelILExprIndexForLabel(self.handle, label_idx)
if result >= core.BNGetHighLevelILExprCount(self.handle):
return None
- return HighLevelILInstruction.create(self, result)
+ return HighLevelILInstruction.create(self, ExpressionIndex(result))
def get_label_uses(self, label_idx:int) -> List[HighLevelILInstruction]:
count = ctypes.c_ulonglong()
@@ -2509,7 +2511,7 @@ class HighLevelILBasicBlock(basicblock.BasicBlock):
def __contains__(self, instruction):
if type(instruction) != HighLevelILInstruction or instruction.il_basic_block != self:
return False
- if instruction.instr_index >= self.start and instruction.instr_index <= self.end:
+ if self.start <= instruction.instr_index <= self.end:
return True
else:
return False
diff --git a/python/lineardisassembly.py b/python/lineardisassembly.py
index 9c3040c9..f87e8b33 100644
--- a/python/lineardisassembly.py
+++ b/python/lineardisassembly.py
@@ -246,27 +246,7 @@ class LinearViewObject:
next_obj = next_obj.handle
count = ctypes.c_ulonglong(0)
- lines = core.BNGetLinearViewObjectLines(self.handle, prev_obj, next_obj, count)
- assert lines is not None, "core.BNGetLinearViewObjectLines returned None"
-
- result = []
- for i in range(0, count.value):
- func = None
- block = None
- if lines[i].function:
- func = _function.Function(None, core.BNNewFunctionReference(lines[i].function))
- if lines[i].block:
- core_block = core.BNNewBasicBlockReference(lines[i].block)
- assert core_block is not None, "core.BNNewBasicBlockReference returned None"
- block = basicblock.BasicBlock(core_block, None)
- color = highlight.HighlightColor._from_core_struct(lines[i].contents.highlight)
- addr = lines[i].contents.addr
- tokens = _function.InstructionTextToken._from_core_struct(lines[i].contents.tokens, lines[i].contents.count)
- contents = _function.DisassemblyTextLine(tokens, addr, color = color)
- result.append(LinearDisassemblyLine(lines[i].type, func, block, contents))
-
- core.BNFreeLinearDisassemblyLines(lines, count.value)
- return result
+ return LinearViewCursor._make_lines(core.BNGetLinearViewObjectLines(self.handle, prev_obj, next_obj, count), count.value)
def ordering_index_for_child(self, child):
return core.BNGetLinearViewObjectOrderingIndexForChild(self.handle, child.handle)
@@ -570,30 +550,33 @@ class LinearViewCursor:
def next(self):
return core.BNLinearViewCursorNext(self.handle)
+ @staticmethod
+ def _make_lines(lines, count:int) -> List['LinearDisassemblyLine']:
+ assert lines is not None, "core returned None for LinearDisassembly lines"
+ try:
+ result = []
+ for i in range(0, count):
+ func = None
+ block = None
+ if lines[i].function:
+ func = _function.Function(None, core.BNNewFunctionReference(lines[i].function))
+ if lines[i].block:
+ core_block = core.BNNewBasicBlockReference(lines[i].block)
+ assert core_block is not None, "core.BNNewBasicBlockReference returned None"
+ block = basicblock.BasicBlock(core_block, None)
+ color = highlight.HighlightColor._from_core_struct(lines[i].contents.highlight)
+ addr = lines[i].contents.addr
+ tokens = _function.InstructionTextToken._from_core_struct(lines[i].contents.tokens, lines[i].contents.count)
+ contents = _function.DisassemblyTextLine(tokens, addr, color = color)
+ result.append(LinearDisassemblyLine(lines[i].type, func, block, contents))
+ return result
+ finally:
+ core.BNFreeLinearDisassemblyLines(lines, count)
+
@property
def lines(self):
count = ctypes.c_ulonglong(0)
- lines = core.BNGetLinearViewCursorLines(self.handle, count)
- assert lines is not None, "core.BNGetLinearViewCursorLines returned None"
-
- result = []
- for i in range(0, count.value):
- func = None
- block = None
- if lines[i].function:
- func = _function.Function(None, core.BNNewFunctionReference(lines[i].function))
- if lines[i].block:
- core_block = core.BNNewBasicBlockReference(lines[i].block)
- assert core_block is not None, "core.BNNewBasicBlockReference returned None"
- block = basicblock.BasicBlock(core_block, None)
- color = highlight.HighlightColor._from_core_struct(lines[i].contents.highlight)
- addr = lines[i].contents.addr
- tokens = _function.InstructionTextToken._from_core_struct(lines[i].contents.tokens, lines[i].contents.count)
- contents = _function.DisassemblyTextLine(tokens, addr, color = color)
- result.append(LinearDisassemblyLine(lines[i].type, func, block, contents))
-
- core.BNFreeLinearDisassemblyLines(lines, count.value)
- return result
+ return LinearViewCursor._make_lines(core.BNGetLinearViewCursorLines(self.handle, count), count.value)
def duplicate(self):
return LinearViewCursor(None, handle = core.BNDuplicateLinearViewCursor(self.handle))
diff --git a/python/log.py b/python/log.py
index c4b74e5c..21e3bae2 100644
--- a/python/log.py
+++ b/python/log.py
@@ -140,7 +140,7 @@ def log_to_stdout(min_level=LogLevel.InfoLog):
"""
``log_to_stdout`` redirects minimum log level to standard out.
- :param enums.LogLevel log_level: minimum level to log to
+ :param enums.LogLevel min_level: minimum level to log to
:rtype: None
:Example:
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index fc3ccb7f..5a326020 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -20,7 +20,7 @@
import ctypes
import struct
-from typing import Generator, List, Optional, Mapping, Union, Tuple, NewType, ClassVar
+from typing import Generator, List, Optional, Dict, Union, Tuple, NewType, ClassVar
from dataclasses import dataclass
# Binary Ninja components
@@ -55,10 +55,10 @@ LowLevelILOperandType = Union[
'ILIntrinsic',
'ILRegisterStack',
int,
- Mapping[int, int],
+ Dict[int, int],
float,
'LowLevelILInstruction',
- Mapping['architecture.RegisterStackName', int],
+ Dict['architecture.RegisterStackName', int],
'SSAFlag',
'SSARegister',
'SSARegisterStack',
@@ -312,7 +312,7 @@ class LowLevelILInstruction(BaseILInstruction):
expr_index:ExpressionIndex
instr:CoreLowLevelILInstruction
instr_index:Optional[InstructionIndex]
- ILOperations:ClassVar[Mapping[LowLevelILOperation, List[Tuple[str,str]]]] = {
+ ILOperations:ClassVar[Dict[LowLevelILOperation, List[Tuple[str,str]]]] = {
LowLevelILOperation.LLIL_NOP: [],
LowLevelILOperation.LLIL_SET_REG: [("dest", "reg"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_SPLIT: [("hi", "reg"), ("lo", "reg"), ("src", "expr")],
@@ -556,7 +556,7 @@ class LowLevelILInstruction(BaseILInstruction):
ssa_func = self.function.ssa_form
assert ssa_func is not None
return LowLevelILInstruction.create(ssa_func,
- core.BNGetLowLevelILSSAExprIndex(self.function.handle, self.expr_index),
+ ExpressionIndex(core.BNGetLowLevelILSSAExprIndex(self.function.handle, self.expr_index)),
core.BNGetLowLevelILSSAInstructionIndex(self.function.handle, self.instr_index) if self.instr_index is not None else None)
@property
@@ -565,7 +565,7 @@ class LowLevelILInstruction(BaseILInstruction):
non_ssa_function = self.function.non_ssa_form
assert non_ssa_function is not None
return LowLevelILInstruction.create(non_ssa_function,
- core.BNGetLowLevelILNonSSAExprIndex(self.function.handle, self.expr_index),
+ ExpressionIndex(core.BNGetLowLevelILNonSSAExprIndex(self.function.handle, self.expr_index)),
core.BNGetLowLevelILNonSSAInstructionIndex(self.function.handle, self.instr_index) if self.instr_index is not None else None)
@property
@@ -666,13 +666,20 @@ class LowLevelILInstruction(BaseILInstruction):
result.append(LowLevelILOperationAndSize(self.instr.operation, self.instr.size))
return result
- def get_possible_values(self, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet:
- option_array = (ctypes.c_int * len(options))()
+ @staticmethod
+ def _make_options_array(options:Optional[List[DataFlowQueryOption]]):
+ if options is None:
+ options = []
idx = 0
+ option_array = (ctypes.c_int * len(options))()
for option in options:
option_array[idx] = option
idx += 1
- value = core.BNGetLowLevelILPossibleExprValues(self.function.handle, self.expr_index, option_array, len(options))
+ return option_array, len(options)
+
+ def get_possible_values(self, options:Optional[List[DataFlowQueryOption]]=None) -> variable.PossibleValueSet:
+ option_array, option_size = LowLevelILInstruction._make_options_array(options)
+ value = core.BNGetLowLevelILPossibleExprValues(self.function.handle, self.expr_index, option_array, option_size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -691,32 +698,24 @@ class LowLevelILInstruction(BaseILInstruction):
value = core.BNGetLowLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index)
return variable.RegisterValue.from_BNRegisterValue(value, self.function.arch)
- def get_possible_reg_values(self, reg:'architecture.RegisterType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
+ def get_possible_reg_values(self, reg:'architecture.RegisterType', options:List[DataFlowQueryOption]=None) -> 'variable.PossibleValueSet':
if self.function.arch is None:
raise Exception("Can not call get_possible_reg_values on function with Architecture set to None")
reg = self.function.arch.get_reg_index(reg)
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index,
- option_array, len(options))
+ option_array, option_size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
- def get_possible_reg_values_after(self, reg:'architecture.RegisterType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
+ def get_possible_reg_values_after(self, reg:'architecture.RegisterType', options:Optional[List[DataFlowQueryOption]]=None) -> 'variable.PossibleValueSet':
if self.function.arch is None:
raise Exception("Can not call get_possible_reg_values_after on function with Architecture set to None")
reg = self.function.arch.get_reg_index(reg)
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index,
- option_array, len(options))
+ option_array, option_size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -737,32 +736,24 @@ class LowLevelILInstruction(BaseILInstruction):
result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch)
return result
- def get_possible_flag_values(self, flag:'architecture.FlagType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
+ def get_possible_flag_values(self, flag:'architecture.FlagType', options:Optional[List[DataFlowQueryOption]]=None) -> 'variable.PossibleValueSet':
if self.function.arch is None:
raise Exception("Can not call get_possible_flag_values on function with Architecture set to None")
flag = self.function.arch.get_flag_index(flag)
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index,
- option_array, len(options))
+ option_array, option_size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
- def get_possible_flag_values_after(self, flag:'architecture.FlagType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
+ def get_possible_flag_values_after(self, flag:'architecture.FlagType', options:Optional[List[DataFlowQueryOption]]=None) -> 'variable.PossibleValueSet':
if self.function.arch is None:
raise Exception("Can not call get_possible_flag_values_after on function with Architecture set to None")
flag = self.function.arch.get_flag_index(flag)
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index,
- option_array, len(options))
+ option_array, option_size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -777,26 +768,18 @@ class LowLevelILInstruction(BaseILInstruction):
result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch)
return result
- def get_possible_stack_contents(self, offset:int, size:int, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet:
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ def get_possible_stack_contents(self, offset:int, size:int, options:Optional[List[DataFlowQueryOption]]=None) -> variable.PossibleValueSet:
+ option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index,
- option_array, len(options))
+ option_array, option_size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
- def get_possible_stack_contents_after(self, offset:int, size:int, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet:
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ def get_possible_stack_contents_after(self, offset:int, size:int, options:Optional[List[DataFlowQueryOption]]=None) -> variable.PossibleValueSet:
+ option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index,
- option_array, len(options))
+ option_array, option_size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -820,12 +803,12 @@ class LowLevelILInstruction(BaseILInstruction):
def _get_int(self, operand_index:int) -> int:
return (self.instr.operands[operand_index] & ((1 << 63) - 1)) - (self.instr.operands[operand_index] & (1 << 63))
- def _get_target_map(self, operand_index:int) -> Mapping[int, int]:
+ def _get_target_map(self, operand_index:int) -> Dict[int, int]:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
try:
- value:Mapping[int, int] = {}
+ value:Dict[int, int] = {}
for j in range(count.value // 2):
key = operand_list[j * 2]
target = operand_list[(j * 2) + 1]
@@ -845,11 +828,11 @@ class LowLevelILInstruction(BaseILInstruction):
def _get_expr(self, operand_index:int) -> 'LowLevelILInstruction':
return LowLevelILInstruction.create(self.function, self.instr.operands[operand_index], self.instr_index)
- def _get_reg_stack_adjust(self, operand_index:int) -> Mapping['architecture.RegisterStackName', int]:
+ def _get_reg_stack_adjust(self, operand_index:int) -> Dict['architecture.RegisterStackName', int]:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
- result:Mapping['architecture.RegisterStackName', int] = {}
+ result:Dict['architecture.RegisterStackName', int] = {}
try:
for j in range(count.value // 2):
reg_stack = operand_list[j * 2]
@@ -1050,22 +1033,22 @@ class LowLevelILConstantBase(LowLevelILInstruction, Constant):
def __bool__(self):
return self.constant != 0
- def __eq__(self, other):
+ def __eq__(self, other:'LowLevelILConstantBase'):
return self.constant == other.constant
- def __ne__(self, other):
+ def __ne__(self, other:'LowLevelILConstantBase'):
return self.constant != other.constant
- def __lt__(self, other):
+ def __lt__(self, other:'LowLevelILConstantBase'):
return self.constant < other.constant
- def __gt__(self, other):
+ def __gt__(self, other:'LowLevelILConstantBase'):
return self.constant > other.constant
- def __le__(self, other):
+ def __le__(self, other:'LowLevelILConstantBase'):
return self.constant <= other.constant
- def __ge__(self, other):
+ def __ge__(self, other:'LowLevelILConstantBase'):
return self.constant >= other.constant
@property
@@ -1911,7 +1894,7 @@ class LowLevelILJumpTo(LowLevelILInstruction):
return self._get_expr(0)
@property
- def targets(self) -> Mapping[int, int]:
+ def targets(self) -> Dict[int, int]:
return self._get_target_map(1)
@property
@@ -2220,7 +2203,7 @@ class LowLevelILCallStackAdjust(LowLevelILInstruction, Call):
return self._get_int(1)
@property
- def reg_stack_adjustments(self) -> Mapping['architecture.RegisterStackName', int]:
+ def reg_stack_adjustments(self) -> Dict['architecture.RegisterStackName', int]:
return self._get_reg_stack_adjust(2)
@property
@@ -2503,7 +2486,7 @@ class LowLevelILStoreSsa(LowLevelILInstruction, Store, SSA):
return [self.dest, self.dest_memory, self.src_memory, self.src]
-ILInstruction:Mapping[LowLevelILOperation, LowLevelILInstruction] = { # type: ignore
+ILInstruction:Dict[LowLevelILOperation, LowLevelILInstruction] = { # type: ignore
LowLevelILOperation.LLIL_NOP: LowLevelILNop, # [],
LowLevelILOperation.LLIL_SET_REG: LowLevelILSetReg, # [("dest", "reg"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_SPLIT: LowLevelILSetRegSplit, # [("hi", "reg"), ("lo", "reg"), ("src", "expr")],
@@ -2754,7 +2737,7 @@ class LowLevelILFunction:
raise IndexError("index out of range")
if i < 0:
i = len(self) + i
- return LowLevelILInstruction.create(self, core.BNGetLowLevelILIndexForInstruction(self.handle, i), i)
+ return LowLevelILInstruction.create(self, ExpressionIndex(core.BNGetLowLevelILIndexForInstruction(self.handle, i)), i)
def __setitem__(self, i, j):
raise IndexError("instruction modification not implemented")
@@ -3210,14 +3193,14 @@ class LowLevelILFunction:
"""
return self.expr(LowLevelILOperation.LLIL_LOAD, addr, size=size)
- def store(self, size:int, addr:ExpressionIndex, value:ExpressionIndex, flags=None) -> ExpressionIndex:
+ def store(self, size:int, addr:ExpressionIndex, value:ExpressionIndex, flags:Optional['architecture.FlagName']=None) -> ExpressionIndex:
"""
``store`` Writes ``size`` bytes to expression ``addr`` read from expression ``value``
:param int size: number of bytes to write
:param ExpressionIndex addr: the expression to write to
:param ExpressionIndex value: the expression to be written
- :param str flags: which flags are set by this operation
+ :param FlagName flags: which flags are set by this operation
:return: The expression ``[addr].size = value``
:rtype: ExpressionIndex
"""
@@ -3884,11 +3867,11 @@ class LowLevelILFunction:
class_index = self.arch.get_semantic_flag_class_index(sem_class)
return self.expr(LowLevelILOperation.LLIL_FLAG_COND, cond, architecture.SemanticClassIndex(class_index))
- def flag_group(self, sem_group) -> ExpressionIndex:
+ def flag_group(self, sem_group:'architecture.SemanticGroupName') -> ExpressionIndex:
"""
``flag_group`` returns a flag_group expression for the given semantic flag group
- :param str sem_group: Semantic flag group to access
+ :param SemanticGroupName sem_group: Semantic flag group to access
:return: A flag_group expression
:rtype: ExpressionIndex
"""
@@ -4414,7 +4397,7 @@ class LowLevelILFunction:
"""
core.BNLowLevelILMarkLabel(self.handle, label.handle)
- def add_label_map(self, labels:Mapping[int, LowLevelILLabel]) -> ExpressionIndex:
+ def add_label_map(self, labels:Dict[int, LowLevelILLabel]) -> ExpressionIndex:
"""
``add_label_map`` returns a label list expression for the given list of LowLevelILLabel objects.
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 9381a5d3..5c960383 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -338,7 +338,7 @@ class MediumLevelILInstruction(BaseILInstruction):
ssa_func = self.function.ssa_form
assert ssa_func is not None
return MediumLevelILInstruction.create(ssa_func,
- core.BNGetMediumLevelILSSAExprIndex(self.function.handle, self.expr_index))
+ ExpressionIndex(core.BNGetMediumLevelILSSAExprIndex(self.function.handle, self.expr_index)))
@property
def non_ssa_form(self) -> 'MediumLevelILInstruction':
@@ -346,7 +346,7 @@ class MediumLevelILInstruction(BaseILInstruction):
non_ssa_func = self.function.non_ssa_form
assert non_ssa_func is not None
return MediumLevelILInstruction.create(non_ssa_func,
- core.BNGetMediumLevelILNonSSAExprIndex(self.function.handle, self.expr_index))
+ ExpressionIndex(core.BNGetMediumLevelILNonSSAExprIndex(self.function.handle, self.expr_index)))
@property
def value(self) -> variable.RegisterValue:
@@ -493,26 +493,29 @@ class MediumLevelILInstruction(BaseILInstruction):
return types.Type.create(core.BNNewTypeReference(result.type), platform = platform, confidence = result.confidence)
return None
- def get_possible_values(self, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet:
- option_array = (ctypes.c_int * len(options))()
+ @staticmethod
+ def _make_options_array(options:Optional[List[DataFlowQueryOption]]):
+ if options is None:
+ options = []
idx = 0
+ option_array = (ctypes.c_int * len(options))()
for option in options:
option_array[idx] = option
idx += 1
- value = core.BNGetMediumLevelILPossibleExprValues(self.function.handle, self.expr_index, option_array, len(options))
+ return option_array, len(options)
+
+ def get_possible_values(self, options:Optional[List[DataFlowQueryOption]]=None) -> variable.PossibleValueSet:
+ option_array, size = MediumLevelILInstruction._make_options_array(options)
+ value = core.BNGetMediumLevelILPossibleExprValues(self.function.handle, self.expr_index, option_array, size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_ssa_var_possible_values(self, ssa_var:SSAVariable, options:List[DataFlowQueryOption]=[]):
var_data = ssa_var.var.to_BNVariable()
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ option_array, size = MediumLevelILInstruction._make_options_array(options)
value = core.BNGetMediumLevelILPossibleSSAVarValues(self.function.handle, var_data, ssa_var.version,
- self.instr_index, option_array, len(options))
+ self.instr_index, option_array, size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -548,29 +551,21 @@ class MediumLevelILInstruction(BaseILInstruction):
return result
def get_possible_reg_values(self, reg:'architecture.RegisterType',
- options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
+ options:Optional[List[DataFlowQueryOption]]=None) -> 'variable.PossibleValueSet':
+ option_array, size = MediumLevelILInstruction._make_options_array(options)
reg = self.function.arch.get_reg_index(reg)
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
value = core.BNGetMediumLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index,
- option_array, len(options))
+ option_array, size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_possible_reg_values_after(self, reg:'architecture.RegisterType',
- options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
+ options:Optional[List[DataFlowQueryOption]]=None) -> 'variable.PossibleValueSet':
reg = self.function.arch.get_reg_index(reg)
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ option_array, size = MediumLevelILInstruction._make_options_array(options)
value = core.BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index,
- option_array, len(options))
+ option_array, size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -588,29 +583,21 @@ class MediumLevelILInstruction(BaseILInstruction):
return result
def get_possible_flag_values(self, flag:'architecture.FlagType',
- options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
+ options:Optional[List[DataFlowQueryOption]]=None) -> 'variable.PossibleValueSet':
flag = self.function.arch.get_flag_index(flag)
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ option_array, size = MediumLevelILInstruction._make_options_array(options)
value = core.BNGetMediumLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index,
- option_array, len(options))
+ option_array, size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_possible_flag_values_after(self, flag:'architecture.FlagType',
- options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
+ options:Optional[List[DataFlowQueryOption]]=None) -> 'variable.PossibleValueSet':
flag = self.function.arch.get_flag_index(flag)
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ option_array, size = MediumLevelILInstruction._make_options_array(options)
value = core.BNGetMediumLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index,
- option_array, len(options))
+ option_array, size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -626,27 +613,19 @@ class MediumLevelILInstruction(BaseILInstruction):
return result
def get_possible_stack_contents(self, offset:int, size:int,
- options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ options:Optional[List[DataFlowQueryOption]]=None) -> 'variable.PossibleValueSet':
+ option_array, option_size = MediumLevelILInstruction._make_options_array(options)
value = core.BNGetMediumLevelILPossibleStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index,
- option_array, len(options))
+ option_array, option_size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_possible_stack_contents_after(self, offset:int, size:int,
- options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
- option_array = (ctypes.c_int * len(options))()
- idx = 0
- for option in options:
- option_array[idx] = option
- idx += 1
+ options:List[DataFlowQueryOption]=None) -> 'variable.PossibleValueSet':
+ option_array, option_size = MediumLevelILInstruction._make_options_array(options)
value = core.BNGetMediumLevelILPossibleStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index,
- option_array, len(options))
+ option_array, option_size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -723,6 +702,11 @@ class MediumLevelILInstruction(BaseILInstruction):
core.BNMediumLevelILFreeOperandList(operand_list)
def _get_var_list(self, operand_index1:int, operand_index2:int) -> List[variable.Variable]:
+ # We keep this extra parameter around because when this function is called
+ # the subclasses that call this don't use the next operand
+ # without this parameter it looks like this operand is being skipped unintentionally
+ # rather this operand is being skipped intentionally.
+ _ = operand_index2
count = ctypes.c_ulonglong()
operand_list = core.BNMediumLevelILGetOperandList(self.function.handle, self.expr_index, operand_index1, count)
assert operand_list is not None, "core.BNMediumLevelILGetOperandList returned None"
@@ -765,7 +749,7 @@ class MediumLevelILInstruction(BaseILInstruction):
count = ctypes.c_ulonglong()
operand_list = core.BNMediumLevelILGetOperandList(self.function.handle, self.expr_index, operand_index1, count)
assert operand_list is not None, "core.BNMediumLevelILGetOperandList returned None"
- value:Mapping[int, int] = {}
+ value:Dict[int, int] = {}
try:
for j in range(count.value // 2):
key = operand_list[j * 2]
@@ -2333,7 +2317,7 @@ class MediumLevelILTailcallUntypedSsa(MediumLevelILCallBase, Tailcall, SSA):
return self._get_expr(1)
@property
- def params(self) -> MediumLevelILInstruction:
+ def params(self) -> List[SSAVariable]:
inst = self._get_expr(2)
assert isinstance(inst, MediumLevelILCallParamSsa), "MediumLevelILTailcallUntypedSsa return bad type for 'params'"
return inst.src
@@ -2645,7 +2629,7 @@ class MediumLevelILFunction:
raise IndexError("index out of range")
if i < 0:
i = len(self) + i
- return MediumLevelILInstruction.create(self, core.BNGetMediumLevelILIndexForInstruction(self.handle, i), i)
+ return MediumLevelILInstruction.create(self, ExpressionIndex(core.BNGetMediumLevelILIndexForInstruction(self.handle, i)), i)
def __setitem__(self, i, j):
raise IndexError("instruction modification not implemented")
@@ -2684,7 +2668,7 @@ class MediumLevelILFunction:
count = ctypes.c_ulonglong()
blocks = core.BNGetMediumLevelILBasicBlockList(self.handle, count)
assert blocks is not None, "core.BNGetMediumLevelILBasicBlockList returned None"
- return (count, blocks)
+ return count, blocks
def _instantiate_block(self, handle):
return MediumLevelILBasicBlock(handle, self, self.view)
@@ -2842,10 +2826,10 @@ class MediumLevelILFunction:
core.BNFinalizeMediumLevelILFunction(self.handle)
def get_ssa_instruction_index(self, instr:InstructionIndex) -> InstructionIndex:
- return core.BNGetMediumLevelILSSAInstructionIndex(self.handle, instr)
+ return InstructionIndex(core.BNGetMediumLevelILSSAInstructionIndex(self.handle, instr))
def get_non_ssa_instruction_index(self, instr:InstructionIndex) -> InstructionIndex:
- return core.BNGetMediumLevelILNonSSAInstructionIndex(self.handle, instr)
+ return InstructionIndex(core.BNGetMediumLevelILNonSSAInstructionIndex(self.handle, instr))
def get_ssa_var_definition(self, ssa_var:SSAVariable) -> Optional[MediumLevelILInstruction]:
var_data = ssa_var.var.to_BNVariable()
@@ -2932,7 +2916,7 @@ class MediumLevelILFunction:
result = core.BNGetLowLevelILInstructionIndex(self.handle, instr)
if result >= core.BNGetLowLevelILInstructionCount(low_il.handle):
return None
- return result
+ return lowlevelil.InstructionIndex(result)
def get_low_level_il_expr_index(self, expr:ExpressionIndex) -> Optional['lowlevelil.ExpressionIndex']:
low_il = self.low_level_il
@@ -2944,15 +2928,15 @@ class MediumLevelILFunction:
result = core.BNGetLowLevelILExprIndex(self.handle, expr)
if result >= core.BNGetLowLevelILExprCount(low_il.handle):
return None
- return result
+ return lowlevelil.ExpressionIndex(result)
def get_low_level_il_expr_indexes(self, expr:ExpressionIndex) -> List['lowlevelil.ExpressionIndex']:
count = ctypes.c_ulonglong()
exprs = core.BNGetLowLevelILExprIndexes(self.handle, expr, count)
assert exprs is not None, "core.BNGetLowLevelILExprIndexes returned None"
- result = []
+ result:List['lowlevelil.ExpressionIndex'] = []
for i in range(0, count.value):
- result.append(exprs[i])
+ result.append(lowlevelil.ExpressionIndex(exprs[i]))
core.BNFreeILInstructionList(exprs)
return result
@@ -2963,7 +2947,7 @@ class MediumLevelILFunction:
result = core.BNGetHighLevelILInstructionIndex(self.handle, instr)
if result >= core.BNGetHighLevelILInstructionCount(high_il.handle):
return None
- return result
+ return highlevelil.InstructionIndex(result)
def get_high_level_il_expr_index(self, expr:ExpressionIndex) -> Optional['highlevelil.ExpressionIndex']:
high_il = self.high_level_il
@@ -2972,15 +2956,15 @@ class MediumLevelILFunction:
result = core.BNGetHighLevelILExprIndex(self.handle, expr)
if result >= core.BNGetHighLevelILExprCount(high_il.handle):
return None
- return result
+ return highlevelil.ExpressionIndex(result)
def get_high_level_il_expr_indexes(self, expr:ExpressionIndex) -> List['highlevelil.ExpressionIndex']:
count = ctypes.c_ulonglong()
exprs = core.BNGetHighLevelILExprIndexes(self.handle, expr, count)
assert exprs is not None, "core.BNGetHighLevelILExprIndexes returned None"
- result = []
+ result:List['highlevelil.ExpressionIndex'] = []
for i in range(0, count.value):
- result.append(exprs[i])
+ result.append(highlevelil.ExpressionIndex(exprs[i]))
core.BNFreeILInstructionList(exprs)
return result
@@ -3117,7 +3101,7 @@ class MediumLevelILBasicBlock(basicblock.BasicBlock):
def __contains__(self, instruction):
if type(instruction) != MediumLevelILInstruction or instruction.il_basic_block != self:
return False
- if instruction.instr_index >= self.start and instruction.instr_index <= self.end:
+ if self.start <= instruction.instr_index <= self.end:
return True
else:
return False
diff --git a/python/platform.py b/python/platform.py
index 84125456..050aa21e 100644
--- a/python/platform.py
+++ b/python/platform.py
@@ -20,7 +20,7 @@
import os
import ctypes
-from typing import Mapping, Optional, List
+from typing import List, Dict, Optional
# Binary Ninja components
import binaryninja
@@ -390,7 +390,7 @@ class Platform(metaclass=_PlatformMetaClass):
def get_auto_platform_type_id_source(self):
return core.BNGetAutoPlatformTypeIdSource(self.handle)
- def parse_types_from_source(self, source, filename=None, include_dirs=[], auto_type_source=None):
+ def parse_types_from_source(self, source, filename=None, include_dirs:Optional[List[str]]=None, auto_type_source=None):
"""
``parse_types_from_source`` parses the source string and any needed headers searching for them in
the optional list of directories provided in ``include_dirs``.
@@ -414,6 +414,8 @@ class Platform(metaclass=_PlatformMetaClass):
filename = "input"
if not isinstance(source, str):
raise AttributeError("Source must be a string")
+ if include_dirs is None:
+ include_dirs = []
dir_buf = (ctypes.c_char_p * len(include_dirs))()
for i in range(0, len(include_dirs)):
dir_buf[i] = include_dirs[i].encode('charmap')
@@ -426,9 +428,9 @@ class Platform(metaclass=_PlatformMetaClass):
core.free_string(errors)
if not result:
raise SyntaxError(error_str)
- type_dict:Mapping[types.QualifiedName, types.Type] = {}
- variables:Mapping[types.QualifiedName, types.Type] = {}
- functions:Mapping[types.QualifiedName, types.Type] = {}
+ type_dict:Dict[types.QualifiedName, types.Type] = {}
+ variables:Dict[types.QualifiedName, types.Type] = {}
+ functions:Dict[types.QualifiedName, types.Type] = {}
for i in range(0, parse.typeCount):
name = types.QualifiedName._from_core_struct(parse.types[i].name)
type_dict[name] = types.Type.create(core.BNNewTypeReference(parse.types[i].type), platform = self)
@@ -441,7 +443,7 @@ class Platform(metaclass=_PlatformMetaClass):
core.BNFreeTypeParserResult(parse)
return types.TypeParserResult(type_dict, variables, functions)
- def parse_types_from_source_file(self, filename, include_dirs=[], auto_type_source=None):
+ def parse_types_from_source_file(self, filename, include_dirs:Optional[List[str]]=None, auto_type_source=None):
"""
``parse_types_from_source_file`` parses the source file ``filename`` and any needed headers searching for them in
the optional list of directories provided in ``include_dirs``.
@@ -463,7 +465,9 @@ class Platform(metaclass=_PlatformMetaClass):
>>>
"""
if not (isinstance(filename, str) and os.path.isfile(filename) and os.access(filename, os.R_OK)):
- raise AttributeError("File {} doesn't exist or isn't readable".format(filename))
+ raise AttributeError("File {} doesn't exist or isn't readable".format(filename))
+ if include_dirs is None:
+ include_dirs = []
dir_buf = (ctypes.c_char_p * len(include_dirs))()
for i in range(0, len(include_dirs)):
dir_buf[i] = include_dirs[i].encode('charmap')
diff --git a/python/types.py b/python/types.py
index 296380ee..c5086d56 100644
--- a/python/types.py
+++ b/python/types.py
@@ -238,12 +238,12 @@ class CoreSymbol:
@property
def type(self) -> SymbolType:
"""Symbol type (read-only)"""
- return SymbolType(core.BNGetSymbolType(self._handle).value)
+ return SymbolType(core.BNGetSymbolType(self._handle))
@property
def binding(self) -> SymbolBinding:
"""Symbol binding (read-only)"""
- return SymbolBinding(core.BNGetSymbolBinding(self._handle).value)
+ return SymbolBinding(core.BNGetSymbolBinding(self._handle))
@property
def namespace(self) -> 'NameSpace':
@@ -753,7 +753,7 @@ class TypeBuilder:
@property
def type_class(self) -> TypeClass:
- return TypeClass(core.BNGetTypeBuilderClass(self._handle).value)
+ return TypeClass(core.BNGetTypeBuilderClass(self._handle))
@property
def signed(self) -> BoolWithConfidence:
@@ -1100,7 +1100,7 @@ class StructureBuilder(TypeBuilder):
@property
def type(self) -> StructureVariant:
- return StructureVariant(core.BNGetStructureBuilderType(self.builder_handle).value)
+ return StructureVariant(core.BNGetStructureBuilderType(self.builder_handle))
@type.setter
def type(self, value:StructureVariant) -> None:
@@ -1389,7 +1389,7 @@ class NamedTypeReferenceBuilder(TypeBuilder):
@property
def named_type_class(self) -> NamedTypeReferenceClass:
- return NamedTypeReferenceClass(core.BNGetTypeReferenceBuilderClass(self.ntr_builder_handle).value)
+ return NamedTypeReferenceClass(core.BNGetTypeReferenceBuilderClass(self.ntr_builder_handle))
@staticmethod
def named_type(named_type:'NamedTypeReferenceBuilder', width:int=0, align:int=1,
@@ -1462,7 +1462,7 @@ class Type:
def create(cls, handle=core.BNTypeHandle, platform:'_platform.Platform'=None, confidence:int=core.max_confidence) -> 'Type':
assert handle is not None, "Passed a handle which is None"
assert isinstance(handle, core.BNTypeHandle)
- type_class = TypeClass(core.BNGetTypeClass(handle).value)
+ type_class = TypeClass(core.BNGetTypeClass(handle))
return Types[type_class](handle, platform, confidence)
def __del__(self):
@@ -1500,7 +1500,7 @@ class Type:
@property
def type_class(self) -> TypeClass:
"""Type class (read-only)"""
- return TypeClass(core.BNGetTypeClass(self._handle).value)
+ return TypeClass(core.BNGetTypeClass(self._handle))
@property
def width(self) -> int:
@@ -2003,7 +2003,7 @@ class StructureType(Type):
@property
def type(self) -> StructureVariant:
- return StructureVariant(core.BNGetStructureType(self.struct_handle).value)
+ return StructureVariant(core.BNGetStructureType(self.struct_handle))
def with_replaced_structure(self, from_struct, to_struct) -> 'StructureType':
return StructureType(core.BNStructureWithReplacedStructure(self.struct_handle, from_struct.handle, to_struct.handle))
@@ -2099,7 +2099,7 @@ class EnumerationType(IntegerType):
class PointerType(Type):
@property
def ref_type(self) -> ReferenceType:
- return ReferenceType(core.BNTypeGetReferenceType(self._handle).value)
+ return ReferenceType(core.BNTypeGetReferenceType(self._handle))
@classmethod
def create(cls, arch:'architecture.Architecture', type:SomeType, const:BoolWithConfidenceType=False,
@@ -2297,7 +2297,7 @@ class NamedTypeReferenceType(Type):
_guid = str(uuid.uuid4())
if type is None:
- return cls.create(NamedTypeReferenceClass.UnknownNamedTypeClass, _guid, name)
+ return cls.create(NamedTypeReferenceClass.UnknownNamedTypeClass, _guid, name, 0, 0, platform, confidence)
else:
return type.generate_named_type_reference(_guid, name)
@@ -2337,7 +2337,7 @@ class NamedTypeReferenceType(Type):
@property
def named_type_class(self) -> NamedTypeReferenceClass:
- return NamedTypeReferenceClass(core.BNGetTypeReferenceClass(self.ntr_handle).value)
+ return NamedTypeReferenceClass(core.BNGetTypeReferenceClass(self.ntr_handle))
@property
def type_id(self) -> str:
@@ -2476,8 +2476,8 @@ def preprocess_source(source:str, filename:str=None, include_dirs:Optional[List[
core.free_string(output)
core.free_string(errors)
if result:
- return (output_str, error_str)
- return (None, error_str)
+ return output_str, error_str
+ return None, error_str
@dataclass(frozen=True)
diff --git a/python/variable.py b/python/variable.py
index d7e46510..f6470429 100644
--- a/python/variable.py
+++ b/python/variable.py
@@ -21,7 +21,7 @@
import ctypes
from typing import List, Generator, Optional, Union, Set, Mapping
-from dataclasses import dataclass, field
+from dataclasses import dataclass
import binaryninja
from . import _binaryninjacore as core
@@ -38,13 +38,11 @@ FunctionOrILFunction = Union["binaryninja.function.Function",
class LookupTableEntry:
from_values:List[int]
to_value:int
+ type:RegisterValueType = RegisterValueType.LookupTableValue
def __repr__(self):
return f"[{', '.join([f'{i:#x}' for i in self.from_values])}] -> {self.to_value:#x}"
- def type(self):
- return RegisterValueType.LookupTableValue
-
@dataclass(frozen=True)
class RegisterValue:
@@ -463,7 +461,7 @@ class PossibleValueSet:
"""
Create a PossibleValueSet object for a stack frame offset.
- :param int value: Integer value of the offset
+ :param int offset: Integer value of the offset
:rtype: PossibleValueSet
"""
result = PossibleValueSet()
@@ -733,7 +731,6 @@ class Variable(CoreVariable):
raise NotImplementedError("No IL function associated with variable")
version_count = ctypes.c_ulonglong()
- versions = None
if self._il_function.il_form in [FunctionGraphType.MediumLevelILFunctionGraph, FunctionGraphType.MediumLevelILSSAFormFunctionGraph]:
versions = core.BNGetMediumLevelILVariableSSAVersions(self._il_function.handle, self.to_BNVariable(), version_count)
elif self._il_function.il_form in [FunctionGraphType.HighLevelILFunctionGraph, FunctionGraphType.HighLevelILSSAFormFunctionGraph]:
@@ -758,6 +755,10 @@ class Variable(CoreVariable):
def dead_store_elimination(self, value):
core.BNSetFunctionVariableDeadStoreElimination(self._function.handle, self.to_BNVariable(), value)
+ @property
+ def function(self) -> 'binaryninja.function.Function':
+ """returns the source Function object which this variable belongs to"""
+ return self._function
@dataclass(frozen=True)
class ConstantReference:
@@ -836,4 +837,4 @@ class AddressRange:
return f"<{self.start:#x}-{self.end:#x}>"
def __contains__(self, i:int):
- return i >= self.start and i < self.end \ No newline at end of file
+ return self.start <= i < self.end \ No newline at end of file