@@ -435,9 +435,10 @@ class FunctionParameter:
435435 location : Optional ['variable.VariableNameAndType' ] = None
436436
437437 def __repr__ (self ):
438+ ic = self .type .immutable_copy ()
438439 if (self .location is not None ) and (self .location .name != self .name ):
439- return f"{ self . type . immutable_copy (). get_string_before_name ()} { self .name } { self . type . immutable_copy () .get_string_after_name ()} @ { self .location .name } "
440- return f"{ self . type . immutable_copy (). get_string_before_name ()} { self .name } { self . type . immutable_copy () .get_string_after_name ()} "
440+ return f"{ ic . get_string_before_name ()} { self .name } { ic .get_string_after_name ()} @ { self .location .name } "
441+ return f"{ ic . get_string_before_name ()} { self .name } { ic .get_string_after_name ()} "
441442
442443 def immutable_copy (self ) -> 'FunctionParameter' :
443444 return FunctionParameter (self .type .immutable_copy (), self .name , self .location )
@@ -602,18 +603,8 @@ def __repr__(self):
602603 def __str__ (self ):
603604 return str (self .immutable_copy ())
604605
605- @property
606- def handle (self ) -> core .BNTypeHandle :
607- return self .immutable_copy ().handle
608-
609606 def __hash__ (self ):
610- return hash (ctypes .addressof (self .handle .contents ))
611-
612- def _to_core_struct (self ) -> core .BNTypeWithConfidence :
613- type_conf = core .BNTypeWithConfidence ()
614- type_conf .type = self .handle
615- type_conf .confidence = self .confidence
616- return type_conf
607+ return hash (ctypes .addressof (self ._handle .contents ))
617608
618609 def immutable_copy (self ):
619610 Types = {
@@ -832,7 +823,8 @@ def child(self) -> 'Type':
832823
833824 @child .setter
834825 def child (self , value : SomeType ) -> None :
835- core .BNTypeBuilderSetChildType (self ._handle , value .immutable_copy ()._to_core_struct ())
826+ ic = value .immutable_copy ()
827+ core .BNTypeBuilderSetChildType (self ._handle , ic ._to_core_struct ())
836828
837829 @property
838830 def alternate_name (self ) -> Optional [str ]:
@@ -978,7 +970,8 @@ def create(
978970
979971 _const = BoolWithConfidence .get_core_struct (const )
980972 _volatile = BoolWithConfidence .get_core_struct (volatile )
981- handle = core .BNCreatePointerTypeBuilderOfWidth (_width , type ._to_core_struct (), _const , _volatile , ref_type )
973+ ic = type .immutable_copy ()
974+ handle = core .BNCreatePointerTypeBuilderOfWidth (_width , ic ._to_core_struct (), _const , _volatile , ref_type )
982975 assert handle is not None , "BNCreatePointerTypeBuilderOfWidth returned None"
983976 return cls (handle , platform , confidence )
984977
@@ -1099,7 +1092,8 @@ def create(
10991092 cls , type : SomeType , element_count : int , platform : Optional ['_platform.Platform' ] = None ,
11001093 confidence : int = core .max_confidence
11011094 ) -> 'ArrayBuilder' :
1102- handle = core .BNCreateArrayTypeBuilder (type ._to_core_struct (), element_count )
1095+ ic = type .immutable_copy ()
1096+ handle = core .BNCreateArrayTypeBuilder (ic ._to_core_struct (), element_count )
11031097 assert handle is not None , "BNCreateArrayTypeBuilder returned None"
11041098 return cls (handle , platform , confidence )
11051099
@@ -1127,11 +1121,11 @@ def create(
11271121 name_type : 'NameType' = NameType .NoNameType ,
11281122 pure : Optional [BoolWithConfidence ] = None
11291123 ) -> 'FunctionBuilder' :
1130- param_buf = FunctionBuilder ._to_core_struct (params )
1124+ param_buf , type_list = FunctionBuilder ._to_core_struct (params )
11311125 if return_type is None :
1132- ret_conf = Type .void (). _to_core_struct ()
1126+ ret_conf = Type .void ()
11331127 else :
1134- ret_conf = return_type ._to_core_struct ()
1128+ ret_conf = return_type .immutable_copy ()
11351129
11361130 conv_conf = core .BNCallingConventionWithConfidence ()
11371131 if calling_convention is None :
@@ -1185,7 +1179,7 @@ def create(
11851179 if params is None :
11861180 params = []
11871181 handle = core .BNCreateFunctionTypeBuilder (
1188- ret_conf , conv_conf , param_buf , len (params ), vararg_conf , can_return_conf , stack_adjust_conf ,
1182+ ret_conf . _to_core_struct () , conv_conf , param_buf , len (params ), vararg_conf , can_return_conf , stack_adjust_conf ,
11891183 reg_stack_adjust_regs , reg_stack_adjust_values , len (reg_stack_adjust ),
11901184 return_regs_set , name_type , pure_conf
11911185 )
@@ -1282,20 +1276,30 @@ def variable_arguments(self) -> BoolWithConfidence:
12821276 def _to_core_struct (params : Optional [ParamsType ] = None ):
12831277 if params is None :
12841278 params = []
1279+
1280+ # type_list is very important as we need to keep a reference to the intermediate type
1281+ # objects as we're getting their handles if they go out of scope while we're holding
1282+ # their handles we get a UAF. This is only necessary as we're inside a helper that
1283+ # has to deal with raw type objects
1284+ type_list = []
12851285 param_buf = (core .BNFunctionParameter * len (params ))()
12861286 for i , param in enumerate (params ):
12871287 core_param = param_buf [i ]
12881288 if isinstance (param , (Type , TypeBuilder )):
1289+ param = param .immutable_copy ()
1290+ type_list .append (param )
12891291 assert param .handle is not None , "Attempting to construct function parameter without properly constructed type"
12901292 core_param .name = ""
12911293 core_param .type = param .handle
12921294 core_param .typeConfidence = param .confidence
12931295 core_param .defaultLocation = True
12941296 elif isinstance (param , FunctionParameter ):
12951297 assert param .type is not None , "Attempting to construct function parameter without properly constructed type"
1298+ param_type = param .type .immutable_copy ()
1299+ type_list .append (param_type )
12961300 core_param .name = param .name
1297- core_param .type = param . type .handle
1298- core_param .typeConfidence = param . type .confidence
1301+ core_param .type = param_type .handle
1302+ core_param .typeConfidence = param_type .confidence
12991303 if param .location is None :
13001304 core_param .defaultLocation = True
13011305 else :
@@ -1307,13 +1311,15 @@ def _to_core_struct(params: Optional[ParamsType] = None):
13071311 name , _type = param
13081312 if not isinstance (name , str ) or not isinstance (_type , (Type , TypeBuilder )):
13091313 raise ValueError (f"Conversion from unsupported function parameter type { type (param )} " )
1314+ _type = _type .immutable_copy ()
1315+ type_list .append (_type )
13101316 core_param .name = name
13111317 core_param .type = _type .handle
13121318 core_param .typeConfidence = _type .confidence
13131319 core_param .defaultLocation = True
13141320 else :
13151321 raise ValueError (f"Conversion from unsupported function parameter type { type (param )} " )
1316- return param_buf
1322+ return param_buf , type_list
13171323
13181324 @parameters .setter
13191325 def parameters (self , params : List [FunctionParameter ]) -> None :
@@ -1438,17 +1444,20 @@ def _add_members_to_builder(structure_builder_handle, members: Optional[MembersT
14381444 for member in members :
14391445 if isinstance (member , Tuple ):
14401446 _type , _name = member
1447+ ic = _type .immutable_copy ()
14411448 core .BNAddStructureBuilderMember (
1442- structure_builder_handle , _type ._to_core_struct (), _name , MemberAccess .NoAccess , MemberScope .NoScope
1449+ structure_builder_handle , ic ._to_core_struct (), _name , MemberAccess .NoAccess , MemberScope .NoScope
14431450 )
14441451 elif isinstance (member , StructureMember ):
1452+ ic = member .type .immutable_copy ()
14451453 core .BNAddStructureBuilderMemberAtOffset (
1446- structure_builder_handle , member . type ._to_core_struct (), member .name , member .offset , False ,
1454+ structure_builder_handle , ic ._to_core_struct (), member .name , member .offset , False ,
14471455 member .access , member .scope , member .bit_position , member .bit_width
14481456 )
14491457 elif isinstance (member , (TypeBuilder , Type )):
1458+ ic = member .immutable_copy ()
14501459 core .BNAddStructureBuilderMember (
1451- structure_builder_handle , member ._to_core_struct (), "" , MemberAccess .NoAccess , MemberScope .NoScope
1460+ structure_builder_handle , ic ._to_core_struct (), "" , MemberAccess .NoAccess , MemberScope .NoScope
14521461 )
14531462 else :
14541463 raise ValueError (f"Structure member type { member } not supported" )
@@ -1611,8 +1620,9 @@ def index_by_offset(self, offset: MemberOffset) -> Optional[MemberIndex]:
16111620 return None
16121621
16131622 def replace (self , index : int , type : SomeType , name : str = "" , overwrite_existing : bool = True ):
1623+ ic = type .immutable_copy ()
16141624 core .BNReplaceStructureBuilderMember (
1615- self .builder_handle , index , type ._to_core_struct (), name , overwrite_existing
1625+ self .builder_handle , index , ic ._to_core_struct (), name , overwrite_existing
16161626 )
16171627
16181628 def remove (self , index : int ):
@@ -1622,8 +1632,9 @@ def insert(
16221632 self , offset : int , type : SomeType , name : str = "" , overwrite_existing : bool = True ,
16231633 access : MemberAccess = MemberAccess .NoAccess , scope : MemberScope = MemberScope .NoScope , bit_position : int = 0 , bit_width : int = 0
16241634 ):
1635+ ic = type .immutable_copy ()
16251636 core .BNAddStructureBuilderMemberAtOffset (
1626- self .builder_handle , type ._to_core_struct (), name , offset , overwrite_existing , access , scope , bit_position ,
1637+ self .builder_handle , ic ._to_core_struct (), name , offset , overwrite_existing , access , scope , bit_position ,
16271638 bit_width
16281639 )
16291640
@@ -1632,16 +1643,18 @@ def append(
16321643 scope : MemberScope = MemberScope .NoScope
16331644 ) -> 'StructureBuilder' :
16341645 # appends a member at the end of the structure growing the structure
1635- core .BNAddStructureBuilderMember (self .builder_handle , type ._to_core_struct (), name , access , scope )
1646+ ic = type .immutable_copy ()
1647+ core .BNAddStructureBuilderMember (self .builder_handle , ic ._to_core_struct (), name , access , scope )
16361648 return self
16371649
16381650 def add_member_at_offset (
16391651 self , name : MemberName , type : SomeType , offset : MemberOffset , overwrite_existing : bool = True ,
16401652 access : MemberAccess = MemberAccess .NoAccess , scope : MemberScope = MemberScope .NoScope , bit_position : int = 0 , bit_width : int = 0
16411653 ) -> 'StructureBuilder' :
16421654 # Adds structure member to the given offset optionally clearing any members within the range offset-offset+len(type)
1655+ ic = type .immutable_copy ()
16431656 core .BNAddStructureBuilderMemberAtOffset (
1644- self .builder_handle , type ._to_core_struct (), name , offset , overwrite_existing , access , scope , bit_position ,
1657+ self .builder_handle , ic ._to_core_struct (), name , offset , overwrite_existing , access , scope , bit_position ,
16451658 bit_width
16461659 )
16471660 return self
@@ -3083,7 +3096,7 @@ def create(
30833096 ret = VoidType .create ()
30843097 if params is None :
30853098 params = []
3086- param_buf = FunctionBuilder ._to_core_struct (params )
3099+ param_buf , type_list = FunctionBuilder ._to_core_struct (params )
30873100 ret_conf = ret ._to_core_struct ()
30883101 conv_conf = core .BNCallingConventionWithConfidence ()
30893102 if calling_convention is None :
0 commit comments