summaryrefslogtreecommitdiff
path: root/python/typecontainer.py
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2023-11-06 21:22:51 -0500
committerGlenn Smith <glenn@vector35.com>2023-11-06 21:31:10 -0500
commit9664293566835578211572938174462967719297 (patch)
tree5ce88ae2acb8ffbf5177da95e2332978cbb82910 /python/typecontainer.py
parent6436615567547349434351468012512505109552 (diff)
Type Containers: API Docs
Diffstat (limited to 'python/typecontainer.py')
-rw-r--r--python/typecontainer.py111
1 files changed, 109 insertions, 2 deletions
diff --git a/python/typecontainer.py b/python/typecontainer.py
index 3f371213..b25a69f7 100644
--- a/python/typecontainer.py
+++ b/python/typecontainer.py
@@ -34,7 +34,15 @@ ProgressFuncType = Callable[[int, int], bool]
class TypeContainer:
+ """
+ A ``TypeContainer`` is a generic interface to access various Binary Ninja models
+ that contain types. Types are stored with both a unique id and a unique name.
+ """
def __init__(self, handle: core.BNTypeContainerHandle):
+ """
+ Construct a Type Container, internal use only
+ :param handle: Handle pointer
+ """
binaryninja._init_plugins()
self.handle: core.BNTypeContainerHandle = core.handle_of_type(handle, core.BNTypeContainer)
@@ -47,27 +55,62 @@ class TypeContainer:
@property
def id(self) -> str:
+ """
+ Get an id string for the Type Container. This will be unique within a given
+ analysis session, but may not be globally unique.
+ :return: Identifier string
+ """
return core.BNTypeContainerGetId(self.handle)
@property
def name(self) -> str:
+ """
+ Get a user-friendly name for the Type Container.
+ :return: Display name
+ """
return core.BNTypeContainerGetName(self.handle)
@property
def container_type(self) -> 'enums.TypeContainerType':
+ """
+ Get the type of underlying model the Type Container is accessing.
+ :return: Container type enum
+ """
return core.BNTypeContainerGetType(self.handle)
@property
def mutable(self) -> bool:
+ """
+ Test if the Type Container supports mutable operations (add, rename, delete)
+ :return: True if mutable
+ """
return core.BNTypeContainerIsMutable(self.handle)
@property
def platform(self) -> 'platform.Platform':
+ """
+ Get the Platform object associated with this Type Container. All Type Containers
+ have exactly one associated Platform (as opposed to, e.g. Type Libraries).
+ :return: Associated Platform object
+ """
handle = core.BNTypeContainerGetPlatform(self.handle)
assert handle is not None
return platform.Platform(handle=handle)
def add_types(self, types: Mapping['ty_.QualifiedNameType', 'ty_.Type'], progress_func: Optional[ProgressFuncType] = None) -> Optional[Mapping['ty_.QualifiedName', str]]:
+ """
+ Add or update types to a Type Container. If the Type Container already contains
+ a type with the same name as a type being added, the existing type will be
+ replaced with the definition given to this function, and references will be
+ updated in the source model.
+
+ An optional progress callback is included because adding many types can be a slow operation.
+
+ :param types: Dict from name -> definition of new types to add
+ :param progress_func: Optional function to call for progress updates
+ :return: Dict from name -> id of type in Type Container for all added types if successful,
+ None otherwise.
+ """
api_names = (core.BNQualifiedName * len(types))()
api_types = (ctypes.POINTER(core.BNType) * len(types))()
for (i, (key, value)) in enumerate(types.items()):
@@ -101,18 +144,43 @@ class TypeContainer:
return result
def rename_type(self, type_id: str, new_name: 'ty_.QualifiedNameType') -> bool:
+ """
+ Rename a type in the Type Container. All references to this type will be updated
+ (by id) to use the new name.
+ :param type_id: Id of type to update
+ :param new_name: New name for the type
+ :return: True if successful
+ """
return core.BNTypeContainerRenameType(self.handle, type_id, ty_.QualifiedName(new_name)._to_core_struct())
def delete_type(self, type_id: str) -> bool:
+ """
+ Delete a type in the Type Container. Behavior of references to this type is
+ not specified and you may end up with broken references if any still exist.
+ :param type_id: Id of type to delete
+ :return: True if successful
+ """
return core.BNTypeContainerDeleteType(self.handle, type_id)
def get_type_id(self, type_name: 'ty_.QualifiedNameType') -> Optional[str]:
+ """
+ Get the unique id of the type in the Type Container with the given name.
+ If no type with that name exists, returns None.
+ :param type_name: Name of type
+ :return: Type id, if exists, else, None
+ """
result = ctypes.c_char_p()
if not core.BNTypeContainerGetTypeId(self.handle, ty_.QualifiedName(type_name)._to_core_struct(), result):
return None
return core.pyNativeStr(result.value)
def get_type_name(self, type_id: str) -> Optional['ty_.QualifiedName']:
+ """
+ Get the unique name of the type in the Type Container with the given id.
+ If no type with that id exists, returns None.
+ :param type_id: Id of type
+ :return: Type name, if exists, else, None
+ """
api_result = core.BNQualifiedName()
if not core.BNTypeContainerGetTypeName(self.handle, type_id, api_result):
return None
@@ -121,6 +189,12 @@ class TypeContainer:
return result
def get_type_by_id(self, type_id: str) -> Optional['ty_.Type']:
+ """
+ Get the definition of the type in the Type Container with the given id.
+ If no type with that id exists, returns None.
+ :param type_id: Id of type
+ :return: Type object, if exists, else, None
+ """
result = ctypes.POINTER(core.BNType)()
if not core.BNTypeContainerGetTypeById(self.handle, type_id, result):
return None
@@ -128,6 +202,10 @@ class TypeContainer:
@property
def types(self) -> Optional[Mapping[str, Tuple['ty_.QualifiedName', 'ty_.Type']]]:
+ """
+ Get a mapping of all types in a Type Container.
+ :return: All types in a dict of type id -> (type name, type definition)
+ """
result_names = ctypes.POINTER(core.BNQualifiedName)()
result_ids = ctypes.POINTER(ctypes.c_char_p)()
result_types = ctypes.POINTER(ctypes.POINTER(core.BNType))()
@@ -149,6 +227,12 @@ class TypeContainer:
return result
def get_type_by_name(self, type_name: 'ty_.QualifiedNameType') -> Optional['ty_.Type']:
+ """
+ Get the definition of the type in the Type Container with the given name.
+ If no type with that name exists, returns None.
+ :param type_name: Name of type
+ :return: Type object, if exists, else, None
+ """
result = ctypes.POINTER(core.BNType)()
if not core.BNTypeContainerGetTypeByName(self.handle, ty_.QualifiedName(type_name)._to_core_struct(), result):
return None
@@ -156,6 +240,10 @@ class TypeContainer:
@property
def type_ids(self) -> Optional[List[str]]:
+ """
+ Get all type ids in a Type Container.
+ :return: List of all type ids
+ """
result_ids = ctypes.POINTER(ctypes.c_char_p)()
result_count = ctypes.c_size_t(0)
if not core.BNTypeContainerGetTypeIds(self.handle, result_ids, result_count):
@@ -171,6 +259,10 @@ class TypeContainer:
@property
def type_names(self) -> Optional[List['ty_.QualifiedName']]:
+ """
+ Get all type names in a Type Container.
+ :return: List of all type names
+ """
result_names = ctypes.POINTER(core.BNQualifiedName)()
result_count = ctypes.c_size_t(0)
if not core.BNTypeContainerGetTypeNames(self.handle, result_names, result_count):
@@ -186,6 +278,10 @@ class TypeContainer:
@property
def type_names_and_ids(self) -> Optional[Mapping[str, 'ty_.QualifiedName']]:
+ """
+ Get a mapping of all type ids and type names in a Type Container.
+ :return: Dict of type id -> type name
+ """
result_names = ctypes.POINTER(core.BNQualifiedName)()
result_ids = ctypes.POINTER(ctypes.c_char_p)()
result_count = ctypes.c_size_t(0)
@@ -202,10 +298,21 @@ class TypeContainer:
core.BNFreeStringList(result_ids, result_count.value)
return result
- def parse_types_from_source(self, source: str, file_name: str, platform: 'platform.Platform',
+ def parse_types_from_source(self, source: str, file_name: str,
options: Optional[List[str]] = None, include_dirs: Optional[List[str]] = None,
auto_type_source: str = ""
) -> Tuple[Optional['typeparser.TypeParserResult'], List['typeparser.TypeParserError']]:
+ """
+ Parse an entire block of source into types, variables, and functions, with
+ knowledge of the types in the Type Container.
+
+ :param source: Source code to parse
+ :param file_name: Name of the file containing the source (optional: exists on disk)
+ :param options: Optional string arguments to pass as options, e.g. command line arguments
+ :param include_dirs: Optional list of directories to include in the header search path
+ :param auto_type_source: Optional source of types if used for automatically generated types
+ :return: A tuple of (result, errors) where the result is None if there was a fatal error
+ """
if options is None:
options = []
if include_dirs is None:
@@ -224,7 +331,7 @@ class TypeContainer:
error_count = ctypes.c_size_t()
success = core.BNTypeContainerParseTypesFromSource(
- self.handle, source, file_name, platform.handle,
+ self.handle, source, file_name,
options_cpp, len(options),
include_dirs_cpp, len(include_dirs), auto_type_source,
result_cpp, errors_cpp, error_count