summaryrefslogtreecommitdiff
path: root/python/types.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/types.py')
-rw-r--r--python/types.py395
1 files changed, 285 insertions, 110 deletions
diff --git a/python/types.py b/python/types.py
index ed4360d6..720f8568 100644
--- a/python/types.py
+++ b/python/types.py
@@ -320,12 +320,16 @@ class FunctionParameter(object):
class Type(object):
def __init__(self, handle, platform = None, confidence = max_confidence):
- self.handle = handle
+ self._handle = handle
+ self._mutable = isinstance(handle.contents, core.BNTypeBuilder)
self._confidence = confidence
self._platform = platform
def __del__(self):
- core.BNFreeType(self.handle)
+ if self._mutable:
+ core.BNFreeTypeBuilder(self._handle)
+ else:
+ core.BNFreeType(self._handle)
def __eq__(self, value):
if not isinstance(value, Type):
@@ -338,51 +342,101 @@ class Type(object):
return core.BNTypesNotEqual(self.handle, value.handle)
@property
+ def handle(self):
+ if self._mutable:
+ # First use of a mutable Type makes it immutable
+ finalized = core.BNFinalizeTypeBuilder(self._handle)
+ core.BNFreeTypeBuilder(self._handle)
+ self._handle = finalized
+ self._mutable = False
+ return self._handle
+
+ @property
def type_class(self):
"""Type class (read-only)"""
- return TypeClass(core.BNGetTypeClass(self.handle))
+ if self._mutable:
+ return TypeClass(core.BNGetTypeBuilderClass(self._handle))
+ return TypeClass(core.BNGetTypeClass(self._handle))
@property
def width(self):
"""Type width (read-only)"""
- return core.BNGetTypeWidth(self.handle)
+ if self._mutable:
+ return core.BNGetTypeBuilderWidth(self._handle)
+ return core.BNGetTypeWidth(self._handle)
@property
def alignment(self):
"""Type alignment (read-only)"""
- return core.BNGetTypeAlignment(self.handle)
+ if self._mutable:
+ return core.BNGetTypeBuilderAlignment(self._handle)
+ return core.BNGetTypeAlignment(self._handle)
@property
def signed(self):
"""Wether type is signed (read-only)"""
- result = core.BNIsTypeSigned(self.handle)
+ if self._mutable:
+ result = core.BNIsTypeBuilderSigned(self._handle)
+ else:
+ result = core.BNIsTypeSigned(self._handle)
return BoolWithConfidence(result.value, confidence = result.confidence)
@property
def const(self):
"""Whether type is const (read/write)"""
- result = core.BNIsTypeConst(self.handle)
+ if self._mutable:
+ result = core.BNIsTypeBuilderConst(self._handle)
+ else:
+ result = core.BNIsTypeConst(self._handle)
return BoolWithConfidence(result.value, confidence = result.confidence)
@const.setter
def const(self, value):
+ if not self._mutable:
+ raise AttributeError("Finalized Type object is immutable, use mutable_copy()")
+ bc = core.BNBoolWithConfidence()
+ bc.value = bool(value)
+ if hasattr(value, 'confidence'):
+ bc.confidence = value.confidence
+ else:
+ bc.confidence = max_confidence
+ core.BNTypeBuilderSetConst(self._handle, bc)
+
+ @property
+ def volatile(self):
+ """Whether type is volatile (read/write)"""
+ if self._mutable:
+ result = core.BNIsTypeBuilderVolatile(self._handle)
+ else:
+ result = core.BNIsTypeVolatile(self._handle)
+ return BoolWithConfidence(result.value, confidence = result.confidence)
+
+ @volatile.setter
+ def volatile(self, value):
+ if not self._mutable:
+ raise AttributeError("Finalized Type object is immutable, use mutable_copy()")
bc = core.BNBoolWithConfidence()
bc.value = bool(value)
if hasattr(value, 'confidence'):
bc.confidence = value.confidence
else:
bc.confidence = max_confidence
- core.BNTypeSetConst(self.handle, bc)
+ core.BNTypeBuilderSetVolatile(self._handle, bc)
@property
- def modified(self):
- """Whether type is modified (read-only)"""
- return core.BNIsTypeFloatingPoint(self.handle)
+ def floating_point(self):
+ """Whether type is floating point (read-only)"""
+ if self._mutable:
+ return core.BNIsTypeBuilderFloatingPoint(self._handle)
+ return core.BNIsTypeFloatingPoint(self._handle)
@property
def target(self):
"""Target (read-only)"""
- result = core.BNGetChildType(self.handle)
+ if self._mutable:
+ result = core.BNGetTypeBuilderChildType(self._handle)
+ else:
+ result = core.BNGetChildType(self._handle)
if not result.type:
return None
return Type(result.type, platform = self._platform, confidence = result.confidence)
@@ -390,7 +444,10 @@ class Type(object):
@property
def element_type(self):
"""Target (read-only)"""
- result = core.BNGetChildType(self.handle)
+ if self._mutable:
+ result = core.BNGetTypeBuilderChildType(self._handle)
+ else:
+ result = core.BNGetChildType(self._handle)
if not result.type:
return None
return Type(result.type, platform = self._platform, confidence = result.confidence)
@@ -398,7 +455,10 @@ class Type(object):
@property
def return_value(self):
"""Return value (read-only)"""
- result = core.BNGetChildType(self.handle)
+ if self._mutable:
+ result = core.BNGetTypeBuilderChildType(self._handle)
+ else:
+ result = core.BNGetChildType(self._handle)
if not result.type:
return None
return Type(result.type, platform = self._platform, confidence = result.confidence)
@@ -406,7 +466,10 @@ class Type(object):
@property
def calling_convention(self):
"""Calling convention (read-only)"""
- result = core.BNGetTypeCallingConvention(self.handle)
+ if self._mutable:
+ result = core.BNGetTypeBuilderCallingConvention(self._handle)
+ else:
+ result = core.BNGetTypeCallingConvention(self._handle)
if not result.convention:
return None
return binaryninja.callingconvention.CallingConvention(None, handle = result.convention, confidence = result.confidence)
@@ -415,7 +478,10 @@ class Type(object):
def parameters(self):
"""Type parameters list (read-only)"""
count = ctypes.c_ulonglong()
- params = core.BNGetTypeParameters(self.handle, count)
+ if self._mutable:
+ params = core.BNGetTypeBuilderParameters(self._handle, count)
+ else:
+ params = core.BNGetTypeParameters(self._handle, count)
result = []
for i in range(0, count.value):
param_type = Type(core.BNNewTypeReference(params[i].type), platform = self._platform, confidence = params[i].typeConfidence)
@@ -436,19 +502,28 @@ class Type(object):
@property
def has_variable_arguments(self):
"""Whether type has variable arguments (read-only)"""
- result = core.BNTypeHasVariableArguments(self.handle)
+ if self._mutable:
+ result = core.BNTypeBuilderHasVariableArguments(self._handle)
+ else:
+ result = core.BNTypeHasVariableArguments(self._handle)
return BoolWithConfidence(result.value, confidence = result.confidence)
@property
def can_return(self):
"""Whether type can return (read-only)"""
- result = core.BNFunctionTypeCanReturn(self.handle)
+ if self._mutable:
+ result = core.BNFunctionTypeBuilderCanReturn(self._handle)
+ else:
+ result = core.BNFunctionTypeCanReturn(self._handle)
return BoolWithConfidence(result.value, confidence = result.confidence)
@property
def structure(self):
"""Structure of the type (read-only)"""
- result = core.BNGetTypeStructure(self.handle)
+ if self._mutable:
+ result = core.BNGetTypeBuilderStructure(self._handle)
+ else:
+ result = core.BNGetTypeStructure(self._handle)
if result is None:
return None
return Structure(result)
@@ -456,7 +531,10 @@ class Type(object):
@property
def enumeration(self):
"""Type enumeration (read-only)"""
- result = core.BNGetTypeEnumeration(self.handle)
+ if self._mutable:
+ result = core.BNGetTypeBuilderEnumeration(self._handle)
+ else:
+ result = core.BNGetTypeEnumeration(self._handle)
if result is None:
return None
return Enumeration(result)
@@ -464,7 +542,10 @@ class Type(object):
@property
def named_type_reference(self):
"""Reference to a named type (read-only)"""
- result = core.BNGetTypeNamedTypeReference(self.handle)
+ if self._mutable:
+ result = core.BNGetTypeBuilderNamedTypeReference(self._handle)
+ else:
+ result = core.BNGetTypeNamedTypeReference(self._handle)
if result is None:
return None
return NamedTypeReference(handle = result)
@@ -472,17 +553,24 @@ class Type(object):
@property
def count(self):
"""Type count (read-only)"""
- return core.BNGetTypeElementCount(self.handle)
+ if self._mutable:
+ return core.BNGetTypeBuilderElementCount(self._handle)
+ return core.BNGetTypeElementCount(self._handle)
@property
def offset(self):
"""Offset into structure (read-only)"""
- return core.BNGetTypeOffset(self.handle)
+ if self._mutable:
+ return core.BNGetTypeBuilderOffset(self._handle)
+ return core.BNGetTypeOffset(self._handle)
@property
def stack_adjustment(self):
"""Stack adjustment for function (read-only)"""
- result = core.BNGetTypeStackAdjustment(self.handle)
+ if self._mutable:
+ result = core.BNGetTypeBuilderStackAdjustment(self._handle)
+ else:
+ result = core.BNGetTypeStackAdjustment(self._handle)
return SizeWithConfidence(result.value, confidence = result.confidence)
def __len__(self):
@@ -492,7 +580,9 @@ class Type(object):
platform = None
if self._platform is not None:
platform = self._platform.handle
- return core.BNGetTypeString(self.handle, platform)
+ if self._mutable:
+ return core.BNGetTypeBuilderString(self._handle, platform)
+ return core.BNGetTypeString(self._handle, platform)
def __repr__(self):
if self._confidence < max_confidence:
@@ -503,13 +593,17 @@ class Type(object):
platform = None
if self._platform is not None:
platform = self._platform.handle
- return core.BNGetTypeStringBeforeName(self.handle, platform)
+ if self._mutable:
+ return core.BNGetTypeBuilderStringBeforeName(self._handle, platform)
+ return core.BNGetTypeStringBeforeName(self._handle, platform)
def get_string_after_name(self):
platform = None
if self._platform is not None:
platform = self._platform.handle
- return core.BNGetTypeStringAfterName(self.handle, platform)
+ if self._mutable:
+ return core.BNGetTypeBuilderStringAfterName(self._handle, platform)
+ return core.BNGetTypeStringAfterName(self._handle, platform)
@property
def tokens(self):
@@ -521,7 +615,10 @@ class Type(object):
platform = None
if self._platform is not None:
platform = self._platform.handle
- tokens = core.BNGetTypeTokens(self.handle, platform, base_confidence, count)
+ if self._mutable:
+ tokens = core.BNGetTypeBuilderTokens(self._handle, platform, base_confidence, count)
+ else:
+ tokens = core.BNGetTypeTokens(self._handle, platform, base_confidence, count)
result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value)
core.BNFreeInstructionText(tokens, count.value)
return result
@@ -531,7 +628,10 @@ class Type(object):
platform = None
if self._platform is not None:
platform = self._platform.handle
- tokens = core.BNGetTypeTokensBeforeName(self.handle, platform, base_confidence, count)
+ if self._mutable:
+ tokens = core.BNGetTypeBuilderTokensBeforeName(self._handle, platform, base_confidence, count)
+ else:
+ tokens = core.BNGetTypeTokensBeforeName(self._handle, platform, base_confidence, count)
result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value)
core.BNFreeInstructionText(tokens, count.value)
return result
@@ -541,18 +641,21 @@ class Type(object):
platform = None
if self._platform is not None:
platform = self._platform.handle
- tokens = core.BNGetTypeTokensAfterName(self.handle, platform, base_confidence, count)
+ if self._mutable:
+ tokens = core.BNGetTypeBuilderTokensAfterName(self._handle, platform, base_confidence, count)
+ else:
+ tokens = core.BNGetTypeTokensAfterName(self._handle, platform, base_confidence, count)
result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value)
core.BNFreeInstructionText(tokens, count.value)
return result
@classmethod
def void(cls):
- return Type(core.BNCreateVoidType())
+ return Type(core.BNCreateVoidTypeBuilder())
@classmethod
def bool(self):
- return Type(core.BNCreateBoolType())
+ return Type(core.BNCreateBoolTypeBuilder())
@classmethod
def char(self):
@@ -576,7 +679,7 @@ class Type(object):
sign_conf.value = sign.value
sign_conf.confidence = sign.confidence
- return Type(core.BNCreateIntegerType(width, sign_conf, altname))
+ return Type(core.BNCreateIntegerTypeBuilder(width, sign_conf, altname))
@classmethod
def float(self, width, altname=""):
@@ -586,40 +689,40 @@ class Type(object):
:param int width: width of the floating point number in bytes
:param str altname: alternate name for type
"""
- return Type(core.BNCreateFloatType(width, altname))
+ return Type(core.BNCreateFloatTypeBuilder(width, altname))
@classmethod
def structure_type(self, structure_type):
- return Type(core.BNCreateStructureType(structure_type.handle))
+ return Type(core.BNCreateStructureTypeBuilder(structure_type.handle))
@classmethod
def named_type(self, named_type, width = 0, align = 1):
- return Type(core.BNCreateNamedTypeReference(named_type.handle, width, align))
+ return Type(core.BNCreateNamedTypeReferenceBuilder(named_type.handle, width, align))
@classmethod
def named_type_from_type_and_id(self, type_id, name, t):
name = QualifiedName(name)._get_core_struct()
if t is not None:
t = t.handle
- return Type(core.BNCreateNamedTypeReferenceFromTypeAndId(type_id, name, t))
+ return Type(core.BNCreateNamedTypeReferenceBuilderFromTypeAndId(type_id, name, t))
@classmethod
def named_type_from_type(self, name, t):
name = QualifiedName(name)._get_core_struct()
if t is not None:
t = t.handle
- return Type(core.BNCreateNamedTypeReferenceFromTypeAndId("", name, t))
+ return Type(core.BNCreateNamedTypeReferenceBuilderFromTypeAndId("", name, t))
@classmethod
def named_type_from_registered_type(self, view, name):
name = QualifiedName(name)._get_core_struct()
- return Type(core.BNCreateNamedTypeReferenceFromType(view.handle, name))
+ return Type(core.BNCreateNamedTypeReferenceBuilderFromType(view.handle, name))
@classmethod
def enumeration_type(self, arch, e, width=None, sign=False):
if width is None:
width = arch.default_int_size
- return Type(core.BNCreateEnumerationType(arch.handle, e.handle, width, sign))
+ return Type(core.BNCreateEnumerationTypeBuilder(arch.handle, e.handle, width, sign))
@classmethod
def pointer(self, arch, t, const=None, volatile=None, ref_type=None):
@@ -648,14 +751,14 @@ class Type(object):
volatile_conf.value = volatile.value
volatile_conf.confidence = volatile.confidence
- return Type(core.BNCreatePointerType(arch.handle, type_conf, const_conf, volatile_conf, ref_type))
+ return Type(core.BNCreatePointerTypeBuilder(arch.handle, type_conf, const_conf, volatile_conf, ref_type))
@classmethod
def array(self, t, count):
type_conf = core.BNTypeWithConfidence()
type_conf.type = t.handle
type_conf.confidence = t.confidence
- return Type(core.BNCreateArrayType(type_conf, count))
+ return Type(core.BNCreateArrayTypeBuilder(type_conf, count))
@classmethod
def function(self, ret, params, calling_convention=None, variable_arguments=None, stack_adjust=None):
@@ -722,7 +825,7 @@ class Type(object):
stack_adjust_conf.value = stack_adjust.value
stack_adjust_conf.confidence = stack_adjust.confidence
- return Type(core.BNCreateFunctionType(ret_conf, conv_conf, param_buf, len(params),
+ return Type(core.BNCreateFunctionTypeBuilder(ret_conf, conv_conf, param_buf, len(params),
vararg_conf, stack_adjust_conf))
@classmethod
@@ -742,12 +845,6 @@ class Type(object):
def with_confidence(self, confidence):
return Type(handle = core.BNNewTypeReference(self.handle), platform = self._platform, confidence = confidence)
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
@property
def confidence(self):
""" """
@@ -766,6 +863,20 @@ class Type(object):
def platform(self, value):
self._platform = value
+ def mutable_copy(self):
+ if self._mutable:
+ return Type(core.BNDuplicateTypeBuilder(self._handle), confidence = self._confidence)
+ return Type(core.BNCreateTypeBuilderFromType(self._handle), confidence = self._confidence)
+
+ def with_replaced_structure(self, from_struct, to_struct):
+ return Type(handle = core.BNTypeWithReplacedStructure(self.handle, from_struct.handle, to_struct.handle))
+
+ def with_replaced_enumeration(self, from_enum, to_enum):
+ return Type(handle = core.BNTypeWithReplacedEnumeration(self.handle, from_enum.handle, to_enum.handle))
+
+ def with_replaced_named_type_reference(self, from_ref, to_ref):
+ return Type(handle = core.BNTypeWithReplacedNamedTypeReference(self.handle, from_ref.handle, to_ref.handle))
+
class BoolWithConfidence(object):
def __init__(self, value, confidence = max_confidence):
@@ -942,13 +1053,9 @@ class ReferenceTypeWithConfidence(object):
class NamedTypeReference(object):
def __init__(self, type_class = NamedTypeReferenceClass.UnknownNamedTypeClass, type_id = None, name = None, handle = None):
if handle is None:
- self.handle = core.BNCreateNamedType()
- core.BNSetTypeReferenceClass(self.handle, type_class)
- if type_id is not None:
- core.BNSetTypeReferenceId(self.handle, type_id)
if name is not None:
name = QualifiedName(name)._get_core_struct()
- core.BNSetTypeReferenceName(self.handle, name)
+ self.handle = core.BNCreateNamedType(type_class, type_id, name)
else:
self.handle = handle
@@ -969,18 +1076,10 @@ class NamedTypeReference(object):
def type_class(self):
return NamedTypeReferenceClass(core.BNGetTypeReferenceClass(self.handle))
- @type_class.setter
- def type_class(self, value):
- core.BNSetTypeReferenceClass(self.handle, value)
-
@property
def type_id(self):
return core.BNGetTypeReferenceId(self.handle)
- @type_id.setter
- def type_id(self, value):
- core.BNSetTypeReferenceId(self.handle, value)
-
@property
def name(self):
name = core.BNGetTypeReferenceName(self.handle)
@@ -988,11 +1087,6 @@ class NamedTypeReference(object):
core.BNFreeQualifiedName(name)
return result
- @name.setter
- def name(self, value):
- value = QualifiedName(value)._get_core_struct()
- core.BNSetTypeReferenceName(self.handle, value)
-
def __repr__(self):
if self.type_class == NamedTypeReferenceClass.TypedefNamedTypeClass:
return "<named type: typedef %s>" % str(self.name)
@@ -1058,26 +1152,34 @@ class StructureMember(object):
class Structure(object):
def __init__(self, handle=None):
if handle is None:
- self.handle = core.BNCreateStructure()
+ self._handle = core.BNCreateStructureBuilder()
+ self._mutable = True
else:
- self.handle = handle
+ self._handle = handle
+ self._mutable = isinstance(handle.contents, core.BNStructureBuilder)
def __del__(self):
- core.BNFreeStructure(self.handle)
+ if self._mutable:
+ core.BNFreeStructureBuilder(self._handle)
+ else:
+ core.BNFreeStructure(self._handle)
def __eq__(self, value):
if not isinstance(value, Structure):
return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ return ctypes.addressof(self._handle.contents) == ctypes.addressof(value._handle.contents)
def __ne__(self, value):
if not isinstance(value, Structure):
return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ return ctypes.addressof(self._handle.contents) != ctypes.addressof(value._handle.contents)
def __getitem__(self, name):
try:
- member = core.BNGetStructureMemberByName(self.handle, name)
+ if self._mutable:
+ member = core.BNGetStructureBuilderMemberByName(self._handle, name)
+ else:
+ member = core.BNGetStructureMemberByName(self._handle, name)
return StructureMember(Type(core.BNNewTypeReference(member.contents.type), confidence=member.contents.typeConfidence),
member.contents.name, member.contents.offset)
finally:
@@ -1085,17 +1187,33 @@ class Structure(object):
def member_at_offset(self, offset):
try:
- member = core.BNGetStructureMemberAtOffset(self.handle, offset)
+ if self._mutable:
+ member = core.BNGetStructureBuilderMemberAtOffset(self._handle, offset, None)
+ else:
+ member = core.BNGetStructureMemberAtOffset(self._handle, offset, None)
return StructureMember(Type(core.BNNewTypeReference(member.contents.type), confidence=member.contents.typeConfidence),
member.contents.name, member.contents.offset)
finally:
core.BNFreeStructureMember(member)
@property
+ def handle(self):
+ if self._mutable:
+ # First use of a mutable Structure makes it immutable
+ finalized = core.BNFinalizeStructureBuilder(self._handle)
+ core.BNFreeStructureBuilder(self._handle)
+ self._handle = finalized
+ self._mutable = False
+ return self._handle
+
+ @property
def members(self):
"""Structure member list (read-only)"""
count = ctypes.c_ulonglong()
- members = core.BNGetStructureMembers(self.handle, count)
+ if self._mutable:
+ members = core.BNGetStructureBuilderMembers(self._handle, count)
+ else:
+ members = core.BNGetStructureMembers(self._handle, count)
try:
result = []
for i in range(0, count.value):
@@ -1108,70 +1226,104 @@ class Structure(object):
@property
def width(self):
"""Structure width"""
- return core.BNGetStructureWidth(self.handle)
+ if self._mutable:
+ return core.BNGetStructureBuilderWidth(self._handle)
+ return core.BNGetStructureWidth(self._handle)
@width.setter
def width(self, new_width):
- core.BNSetStructureWidth(self.handle, new_width)
+ if not self._mutable:
+ raise AttributeError("Finalized Structure object is immutable, use mutable_copy()")
+ core.BNSetStructureBuilderWidth(self._handle, new_width)
@property
def alignment(self):
"""Structure alignment"""
- return core.BNGetStructureAlignment(self.handle)
+ if self._mutable:
+ return core.BNGetStructureBuilderAlignment(self._handle)
+ return core.BNGetStructureAlignment(self._handle)
@alignment.setter
def alignment(self, align):
- core.BNSetStructureAlignment(self.handle, align)
+ if not self._mutable:
+ raise AttributeError("Finalized Structure object is immutable, use mutable_copy()")
+ core.BNSetStructureBuilderAlignment(self._handle, align)
@property
def packed(self):
- return core.BNIsStructurePacked(self.handle)
+ if self._mutable:
+ return core.BNIsStructureBuilderPacked(self._handle)
+ return core.BNIsStructurePacked(self._handle)
@packed.setter
def packed(self, value):
- core.BNSetStructurePacked(self.handle, value)
+ if not self._mutable:
+ raise AttributeError("Finalized Structure object is immutable, use mutable_copy()")
+ core.BNSetStructureBuilderPacked(self._handle, value)
@property
def union(self):
- return core.BNIsStructureUnion(self.handle)
+ if self._mutable:
+ return core.BNIsStructureBuilderUnion(self._handle)
+ return core.BNIsStructureUnion(self._handle)
@property
def type(self):
- return StructureType(core.BNGetStructureType(self.handle))
+ if self._mutable:
+ return StructureType(core.BNGetStructureBuilderType(self._handle))
+ return StructureType(core.BNGetStructureType(self._handle))
@type.setter
def type(self, value):
- core.BNSetStructureType(self.handle, value)
-
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
+ if not self._mutable:
+ raise AttributeError("Finalized Structure object is immutable, use mutable_copy()")
+ core.BNSetStructureBuilderType(self._handle, value)
def __repr__(self):
return "<struct: size %#x>" % self.width
def append(self, t, name = ""):
+ if not self._mutable:
+ raise AttributeError("Finalized Structure object is immutable, use mutable_copy()")
tc = core.BNTypeWithConfidence()
tc.type = t.handle
tc.confidence = t.confidence
- core.BNAddStructureMember(self.handle, tc, name)
+ core.BNAddStructureBuilderMember(self._handle, tc, name)
def insert(self, offset, t, name = ""):
+ if not self._mutable:
+ raise AttributeError("Finalized Structure object is immutable, use mutable_copy()")
tc = core.BNTypeWithConfidence()
tc.type = t.handle
tc.confidence = t.confidence
- core.BNAddStructureMemberAtOffset(self.handle, tc, name, offset)
+ core.BNAddStructureBuilderMemberAtOffset(self._handle, tc, name, offset)
def remove(self, i):
- core.BNRemoveStructureMember(self.handle, i)
+ if not self._mutable:
+ raise AttributeError("Finalized Structure object is immutable, use mutable_copy()")
+ core.BNRemoveStructureBuilderMember(self._handle, i)
def replace(self, i, t, name = ""):
+ if not self._mutable:
+ raise AttributeError("Finalized Structure object is immutable, use mutable_copy()")
tc = core.BNTypeWithConfidence()
tc.type = t.handle
tc.confidence = t.confidence
- core.BNReplaceStructureMember(self.handle, i, tc, name)
+ core.BNReplaceStructureBuilderMember(self._handle, i, tc, name)
+
+ def mutable_copy(self):
+ if self._mutable:
+ return Structure(core.BNDuplicateStructureBuilder(self._handle))
+ return Structure(core.BNCreateStructureBuilderFromStructure(self._handle))
+
+ def with_replaced_structure(self, from_struct, to_struct):
+ return Structure(core.BNStructureWithReplacedStructure(self.handle, from_struct.handle, to_struct.handle))
+
+ def with_replaced_enumeration(self, from_enum, to_enum):
+ return Structure(core.BNStructureWithReplacedEnumeration(self.handle, from_enum.handle, to_enum.handle))
+
+ def with_replaced_named_type_reference(self, from_ref, to_ref):
+ return Structure(core.BNStructureWithReplacedNamedTypeReference(self.handle, from_ref.handle, to_ref.handle))
class EnumerationMember(object):
@@ -1214,54 +1366,77 @@ class EnumerationMember(object):
class Enumeration(object):
def __init__(self, handle=None):
if handle is None:
- self.handle = core.BNCreateEnumeration()
+ self._handle = core.BNCreateEnumerationBuilder()
+ self._mutable = True
else:
- self.handle = handle
+ self._handle = handle
+ self._mutable = isinstance(handle.contents, core.BNEnumerationBuilder)
def __del__(self):
- core.BNFreeEnumeration(self.handle)
+ if self._mutable:
+ core.BNFreeEnumerationBuilder(self._handle)
+ else:
+ core.BNFreeEnumeration(self._handle)
def __eq__(self, value):
if not isinstance(value, Enumeration):
return False
- return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents)
+ return ctypes.addressof(self._handle.contents) == ctypes.addressof(value._handle.contents)
def __ne__(self, value):
if not isinstance(value, Enumeration):
return True
- return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents)
+ return ctypes.addressof(self._handle.contents) != ctypes.addressof(value._handle.contents)
+
+ @property
+ def handle(self):
+ if self._mutable:
+ # First use of a mutable Enumeration makes it immutable
+ finalized = core.BNFinalizeEnumerationBuilder(self._handle)
+ core.BNFreeEnumerationBuilder(self._handle)
+ self._handle = finalized
+ self._mutable = False
+ return self._handle
@property
def members(self):
"""Enumeration member list (read-only)"""
count = ctypes.c_ulonglong()
- members = core.BNGetEnumerationMembers(self.handle, count)
+ if self._mutable:
+ members = core.BNGetEnumerationBuilderMembers(self._handle, count)
+ else:
+ members = core.BNGetEnumerationMembers(self._handle, count)
result = []
for i in range(0, count.value):
result.append(EnumerationMember(members[i].name, members[i].value, members[i].isDefault))
core.BNFreeEnumerationMemberList(members, count.value)
return result
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
def __repr__(self):
return "<enum: %s>" % repr(self.members)
def append(self, name, value = None):
+ if not self._mutable:
+ raise AttributeError("Finalized Enumeration object is immutable, use mutable_copy()")
if value is None:
- core.BNAddEnumerationMember(self.handle, name)
+ core.BNAddEnumerationBuilderMember(self._handle, name)
else:
- core.BNAddEnumerationMemberWithValue(self.handle, name, value)
+ core.BNAddEnumerationBuilderMemberWithValue(self._handle, name, value)
def remove(self, i):
- core.BNRemoveEnumerationMember(self.handle, i)
+ if not self._mutable:
+ raise AttributeError("Finalized Enumeration object is immutable, use mutable_copy()")
+ core.BNRemoveEnumerationBuilderMember(self._handle, i)
def replace(self, i, name, value):
- core.BNReplaceEnumerationMember(self.handle, i, name, value)
+ if not self._mutable:
+ raise AttributeError("Finalized Enumeration object is immutable, use mutable_copy()")
+ core.BNReplaceEnumerationBuilderMember(self._handle, i, name, value)
+
+ def mutable_copy(self):
+ if self._mutable:
+ return Enumeration(core.BNDuplicateEnumerationBuilder(self._handle))
+ return Enumeration(core.BNCreateEnumerationBuilderFromEnumeration(self._handle))
class TypeParserResult(object):