summaryrefslogtreecommitdiff
path: root/python/types.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/types.py')
-rw-r--r--python/types.py78
1 files changed, 46 insertions, 32 deletions
diff --git a/python/types.py b/python/types.py
index 44583c4d..0da212d3 100644
--- a/python/types.py
+++ b/python/types.py
@@ -435,9 +435,10 @@ class FunctionParameter:
location: Optional['variable.VariableNameAndType'] = None
def __repr__(self):
+ ic = self.type.immutable_copy()
if (self.location is not None) and (self.location.name != self.name):
- return f"{self.type.immutable_copy().get_string_before_name()} {self.name}{self.type.immutable_copy().get_string_after_name()} @ {self.location.name}"
- return f"{self.type.immutable_copy().get_string_before_name()} {self.name}{self.type.immutable_copy().get_string_after_name()}"
+ return f"{ic.get_string_before_name()} {self.name}{ic.get_string_after_name()} @ {self.location.name}"
+ return f"{ic.get_string_before_name()} {self.name}{ic.get_string_after_name()}"
def immutable_copy(self) -> 'FunctionParameter':
return FunctionParameter(self.type.immutable_copy(), self.name, self.location)
@@ -635,18 +636,8 @@ class TypeBuilder:
def __str__(self):
return str(self.immutable_copy())
- @property
- def handle(self) -> core.BNTypeHandle:
- return self.immutable_copy().handle
-
def __hash__(self):
- return hash(ctypes.addressof(self.handle.contents))
-
- def _to_core_struct(self) -> core.BNTypeWithConfidence:
- type_conf = core.BNTypeWithConfidence()
- type_conf.type = self.handle
- type_conf.confidence = self.confidence
- return type_conf
+ return hash(ctypes.addressof(self._handle.contents))
def immutable_copy(self):
Types = {
@@ -865,7 +856,8 @@ class TypeBuilder:
@child.setter
def child(self, value: SomeType) -> None:
- core.BNTypeBuilderSetChildType(self._handle, value.immutable_copy()._to_core_struct())
+ ic = value.immutable_copy()
+ core.BNTypeBuilderSetChildType(self._handle, ic._to_core_struct())
@property
def alternate_name(self) -> Optional[str]:
@@ -1011,7 +1003,8 @@ class PointerBuilder(TypeBuilder):
_const = BoolWithConfidence.get_core_struct(const)
_volatile = BoolWithConfidence.get_core_struct(volatile)
- handle = core.BNCreatePointerTypeBuilderOfWidth(_width, type._to_core_struct(), _const, _volatile, ref_type)
+ ic = type.immutable_copy()
+ handle = core.BNCreatePointerTypeBuilderOfWidth(_width, ic._to_core_struct(), _const, _volatile, ref_type)
assert handle is not None, "BNCreatePointerTypeBuilderOfWidth returned None"
return cls(handle, platform, confidence)
@@ -1132,7 +1125,8 @@ class ArrayBuilder(TypeBuilder):
cls, type: SomeType, element_count: int, platform: Optional['_platform.Platform'] = None,
confidence: int = core.max_confidence
) -> 'ArrayBuilder':
- handle = core.BNCreateArrayTypeBuilder(type._to_core_struct(), element_count)
+ ic = type.immutable_copy()
+ handle = core.BNCreateArrayTypeBuilder(ic._to_core_struct(), element_count)
assert handle is not None, "BNCreateArrayTypeBuilder returned None"
return cls(handle, platform, confidence)
@@ -1160,11 +1154,11 @@ class FunctionBuilder(TypeBuilder):
name_type: 'NameType' = NameType.NoNameType,
pure: Optional[BoolWithConfidence] = None
) -> 'FunctionBuilder':
- param_buf = FunctionBuilder._to_core_struct(params)
+ param_buf, type_list = FunctionBuilder._to_core_struct(params)
if return_type is None:
- ret_conf = Type.void()._to_core_struct()
+ ret_conf = Type.void()
else:
- ret_conf = return_type._to_core_struct()
+ ret_conf = return_type.immutable_copy()
conv_conf = core.BNCallingConventionWithConfidence()
if calling_convention is None:
@@ -1218,7 +1212,7 @@ class FunctionBuilder(TypeBuilder):
if params is None:
params = []
handle = core.BNCreateFunctionTypeBuilder(
- ret_conf, conv_conf, param_buf, len(params), vararg_conf, can_return_conf, stack_adjust_conf,
+ ret_conf._to_core_struct(), conv_conf, param_buf, len(params), vararg_conf, can_return_conf, stack_adjust_conf,
reg_stack_adjust_regs, reg_stack_adjust_values, len(reg_stack_adjust),
return_regs_set, name_type, pure_conf
)
@@ -1315,10 +1309,18 @@ class FunctionBuilder(TypeBuilder):
def _to_core_struct(params: Optional[ParamsType] = None):
if params is None:
params = []
+
+ # type_list is very important as we need to keep a reference to the intermediate type
+ # objects as we're getting their handles if they go out of scope while we're holding
+ # their handles we get a UAF. This is only necessary as we're inside a helper that
+ # has to deal with raw type objects
+ type_list = []
param_buf = (core.BNFunctionParameter * len(params))()
for i, param in enumerate(params):
core_param = param_buf[i]
if isinstance(param, (Type, TypeBuilder)):
+ param = param.immutable_copy()
+ type_list.append(param)
assert param.handle is not None, "Attempting to construct function parameter without properly constructed type"
core_param.name = ""
core_param.type = param.handle
@@ -1326,9 +1328,11 @@ class FunctionBuilder(TypeBuilder):
core_param.defaultLocation = True
elif isinstance(param, FunctionParameter):
assert param.type is not None, "Attempting to construct function parameter without properly constructed type"
+ param_type = param.type.immutable_copy()
+ type_list.append(param_type)
core_param.name = param.name
- core_param.type = param.type.handle
- core_param.typeConfidence = param.type.confidence
+ core_param.type = param_type.handle
+ core_param.typeConfidence = param_type.confidence
if param.location is None:
core_param.defaultLocation = True
else:
@@ -1340,17 +1344,20 @@ class FunctionBuilder(TypeBuilder):
name, _type = param
if not isinstance(name, str) or not isinstance(_type, (Type, TypeBuilder)):
raise ValueError(f"Conversion from unsupported function parameter type {type(param)}")
+ _type = _type.immutable_copy()
+ type_list.append(_type)
core_param.name = name
core_param.type = _type.handle
core_param.typeConfidence = _type.confidence
core_param.defaultLocation = True
else:
raise ValueError(f"Conversion from unsupported function parameter type {type(param)}")
- return param_buf
+ return param_buf, type_list
@parameters.setter
def parameters(self, params: List[FunctionParameter]) -> None:
- core.BNSetFunctionTypeBuilderParameters(self._handle, FunctionBuilder._to_core_struct(params), len(params))
+ ic, type_list = FunctionBuilder._to_core_struct(params)
+ core.BNSetFunctionTypeBuilderParameters(self._handle, ic, len(params))
@property
def children(self) -> List[TypeBuilder]:
@@ -1471,17 +1478,20 @@ class StructureBuilder(TypeBuilder):
for member in members:
if isinstance(member, Tuple):
_type, _name = member
+ ic = _type.immutable_copy()
core.BNAddStructureBuilderMember(
- structure_builder_handle, _type._to_core_struct(), _name, MemberAccess.NoAccess, MemberScope.NoScope
+ structure_builder_handle, ic._to_core_struct(), _name, MemberAccess.NoAccess, MemberScope.NoScope
)
elif isinstance(member, StructureMember):
+ ic = member.type.immutable_copy()
core.BNAddStructureBuilderMemberAtOffset(
- structure_builder_handle, member.type._to_core_struct(), member.name, member.offset, False,
+ structure_builder_handle, ic._to_core_struct(), member.name, member.offset, False,
member.access, member.scope, member.bit_position, member.bit_width
)
elif isinstance(member, (TypeBuilder, Type)):
+ ic = member.immutable_copy()
core.BNAddStructureBuilderMember(
- structure_builder_handle, member._to_core_struct(), "", MemberAccess.NoAccess, MemberScope.NoScope
+ structure_builder_handle, ic._to_core_struct(), "", MemberAccess.NoAccess, MemberScope.NoScope
)
else:
raise ValueError(f"Structure member type {member} not supported")
@@ -1644,8 +1654,9 @@ class StructureBuilder(TypeBuilder):
return None
def replace(self, index: int, type: SomeType, name: str = "", overwrite_existing: bool = True):
+ ic = type.immutable_copy()
core.BNReplaceStructureBuilderMember(
- self.builder_handle, index, type._to_core_struct(), name, overwrite_existing
+ self.builder_handle, index, ic._to_core_struct(), name, overwrite_existing
)
def remove(self, index: int):
@@ -1655,8 +1666,9 @@ class StructureBuilder(TypeBuilder):
self, offset: int, type: SomeType, name: str = "", overwrite_existing: bool = True,
access: MemberAccess = MemberAccess.NoAccess, scope: MemberScope = MemberScope.NoScope, bit_position: int = 0, bit_width: int = 0
):
+ ic = type.immutable_copy()
core.BNAddStructureBuilderMemberAtOffset(
- self.builder_handle, type._to_core_struct(), name, offset, overwrite_existing, access, scope, bit_position,
+ self.builder_handle, ic._to_core_struct(), name, offset, overwrite_existing, access, scope, bit_position,
bit_width
)
@@ -1665,7 +1677,8 @@ class StructureBuilder(TypeBuilder):
scope: MemberScope = MemberScope.NoScope
) -> 'StructureBuilder':
# appends a member at the end of the structure growing the structure
- core.BNAddStructureBuilderMember(self.builder_handle, type._to_core_struct(), name, access, scope)
+ ic = type.immutable_copy()
+ core.BNAddStructureBuilderMember(self.builder_handle, ic._to_core_struct(), name, access, scope)
return self
def add_member_at_offset(
@@ -1673,8 +1686,9 @@ class StructureBuilder(TypeBuilder):
access: MemberAccess = MemberAccess.NoAccess, scope: MemberScope = MemberScope.NoScope, bit_position: int = 0, bit_width: int = 0
) -> 'StructureBuilder':
# Adds structure member to the given offset optionally clearing any members within the range offset-offset+len(type)
+ ic = type.immutable_copy()
core.BNAddStructureBuilderMemberAtOffset(
- self.builder_handle, type._to_core_struct(), name, offset, overwrite_existing, access, scope, bit_position,
+ self.builder_handle, ic._to_core_struct(), name, offset, overwrite_existing, access, scope, bit_position,
bit_width
)
return self
@@ -3116,7 +3130,7 @@ class FunctionType(Type):
ret = VoidType.create()
if params is None:
params = []
- param_buf = FunctionBuilder._to_core_struct(params)
+ param_buf, type_list = FunctionBuilder._to_core_struct(params)
ret_conf = ret._to_core_struct()
conv_conf = core.BNCallingConventionWithConfidence()
if calling_convention is None: