summaryrefslogtreecommitdiff
path: root/python/architecture.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/architecture.py')
-rw-r--r--python/architecture.py689
1 files changed, 655 insertions, 34 deletions
diff --git a/python/architecture.py b/python/architecture.py
index a893c1d4..3ccd2b11 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -120,9 +120,16 @@ class Architecture(object):
global_regs = []
flags = []
flag_write_types = []
+ semantic_flag_classes = []
+ semantic_flag_groups = []
flag_roles = {}
flags_required_for_flag_condition = {}
+ flags_required_for_semantic_flag_group = {}
+ flag_conditions_for_semantic_flag_group = {}
flags_written_by_flag_write_type = {}
+ semantic_class_for_flag_write_type = {}
+ reg_stacks = {}
+ intrinsics = {}
__metaclass__ = _ArchitectureMetaClass
next_address = 0
@@ -165,37 +172,90 @@ class Architecture(object):
core.BNFreeRegisterList(flags)
count = ctypes.c_ulonglong()
- types = core.BNGetAllArchitectureFlagWriteTypes(self.handle, count)
+ write_types = core.BNGetAllArchitectureFlagWriteTypes(self.handle, count)
self._flag_write_types = {}
self._flag_write_types_by_index = {}
self.__dict__["flag_write_types"] = []
for i in xrange(0, count.value):
- name = core.BNGetArchitectureFlagWriteTypeName(self.handle, types[i])
- self._flag_write_types[name] = types[i]
- self._flag_write_types_by_index[types[i]] = name
+ name = core.BNGetArchitectureFlagWriteTypeName(self.handle, write_types[i])
+ self._flag_write_types[name] = write_types[i]
+ self._flag_write_types_by_index[write_types[i]] = name
self.flag_write_types.append(name)
- core.BNFreeRegisterList(types)
+ core.BNFreeRegisterList(write_types)
+
+ count = ctypes.c_ulonglong()
+ sem_classes = core.BNGetAllArchitectureSemanticFlagClasses(self.handle, count)
+ self._semantic_flag_classes = {}
+ self._semantic_flag_classes_by_index = {}
+ self.__dict__["semantic_flag_classes"] = []
+ for i in xrange(0, count.value):
+ name = core.BNGetArchitectureSemanticFlagClassName(self.handle, sem_classes[i])
+ self._semantic_flag_classes[name] = sem_classes[i]
+ self._semantic_flag_classes_by_index[sem_classes[i]] = name
+ self.semantic_flag_classes.append(name)
+ core.BNFreeRegisterList(sem_classes)
+
+ count = ctypes.c_ulonglong()
+ sem_groups = core.BNGetAllArchitectureSemanticFlagGroups(self.handle, count)
+ self._semantic_flag_groups = {}
+ self._semantic_flag_groups_by_index = {}
+ self.__dict__["semantic_flag_groups"] = []
+ for i in xrange(0, count.value):
+ name = core.BNGetArchitectureSemanticFlagGroupName(self.handle, sem_groups[i])
+ self._semantic_flag_groups[name] = sem_groups[i]
+ self._semantic_flag_groups_by_index[sem_groups[i]] = name
+ self.semantic_flag_groups.append(name)
+ core.BNFreeRegisterList(sem_groups)
self._flag_roles = {}
self.__dict__["flag_roles"] = {}
for flag in self.__dict__["flags"]:
- role = FlagRole(core.BNGetArchitectureFlagRole(self.handle, self._flags[flag]))
+ role = FlagRole(core.BNGetArchitectureFlagRole(self.handle, self._flags[flag], 0))
self.__dict__["flag_roles"][flag] = role
self._flag_roles[self._flags[flag]] = role
- self._flags_required_for_flag_condition = {}
self.__dict__["flags_required_for_flag_condition"] = {}
for cond in LowLevelILFlagCondition:
count = ctypes.c_ulonglong()
- flags = core.BNGetArchitectureFlagsRequiredForFlagCondition(self.handle, cond, count)
+ flags = core.BNGetArchitectureFlagsRequiredForFlagCondition(self.handle, cond, 0, count)
+ flag_names = []
+ for i in xrange(0, count.value):
+ flag_names.append(self._flags_by_index[flags[i]])
+ core.BNFreeRegisterList(flags)
+ self.__dict__["flags_required_for_flag_condition"][cond] = flag_names
+
+ self._flags_required_by_semantic_flag_group = {}
+ self.__dict__["flags_required_for_semantic_flag_group"] = {}
+ for group in self.semantic_flag_groups:
+ count = ctypes.c_ulonglong()
+ flags = core.BNGetArchitectureFlagsRequiredForSemanticFlagGroup(self.handle,
+ self._semantic_flag_groups[group], count)
flag_indexes = []
flag_names = []
for i in xrange(0, count.value):
flag_indexes.append(flags[i])
flag_names.append(self._flags_by_index[flags[i]])
core.BNFreeRegisterList(flags)
- self._flags_required_for_flag_condition[cond] = flag_indexes
- self.__dict__["flags_required_for_flag_condition"][cond] = flag_names
+ self._flags_required_by_semantic_flag_group[self._semantic_flag_groups[group]] = flag_indexes
+ self.__dict__["flags_required_for_semantic_flag_group"][cond] = flag_names
+
+ self._flag_conditions_for_semantic_flag_group = {}
+ self.__dict__["flag_conditions_for_semantic_flag_group"] = {}
+ for group in self.semantic_flag_groups:
+ count = ctypes.c_ulonglong()
+ conditions = core.BNGetArchitectureFlagConditionsForSemanticFlagGroup(self.handle,
+ self._semantic_flag_groups[group], count)
+ class_index_cond = {}
+ class_cond = {}
+ for i in xrange(0, count.value):
+ class_index_cond[conditions[i].semanticClass] = conditions[i].condition
+ if conditions[i].semanticClass == 0:
+ class_cond[None] = conditions[i].condition
+ elif conditions[i].semanticClass in self._semantic_flag_classes_by_index:
+ class_cond[self._semantic_flag_classes_by_index[conditions[i].semanticClass]] = conditions[i].condition
+ core.BNFreeFlagConditionsForSemanticFlagGroup(conditions)
+ self._flag_conditions_for_semantic_flag_group[self._semantic_flag_groups[group]] = class_index_cond
+ self.__dict__["flag_conditions_for_semantic_flag_group"][group] = class_cond
self._flags_written_by_flag_write_type = {}
self.__dict__["flags_written_by_flag_write_type"] = {}
@@ -212,12 +272,61 @@ class Architecture(object):
self._flags_written_by_flag_write_type[self._flag_write_types[write_type]] = flag_indexes
self.__dict__["flags_written_by_flag_write_type"][write_type] = flag_names
+ self._semantic_class_for_flag_write_type = {}
+ self.__dict__["semantic_class_for_flag_write_type"] = {}
+ for write_type in self.flag_write_types:
+ sem_class = core.BNGetArchitectureSemanticClassForFlagWriteType(self.handle,
+ self._flag_write_types[write_type])
+ if sem_class == 0:
+ sem_class_name = None
+ else:
+ sem_class_name = self._semantic_flag_classes_by_index[sem_class]
+ self._semantic_class_for_flag_write_type[self._flag_write_types[write_type]] = sem_class
+ self.__dict__["semantic_class_for_flag_write_type"][write_type] = sem_class_name
+
count = ctypes.c_ulonglong()
regs = core.BNGetArchitectureGlobalRegisters(self.handle, count)
self.__dict__["global_regs"] = []
for i in xrange(0, count.value):
self.global_regs.append(core.BNGetArchitectureRegisterName(self.handle, regs[i]))
core.BNFreeRegisterList(regs)
+
+ count = ctypes.c_ulonglong()
+ regs = core.BNGetAllArchitectureRegisterStacks(self.handle, count)
+ self.__dict__["reg_stacks"] = {}
+ for i in xrange(0, count.value):
+ name = core.BNGetArchitectureRegisterStackName(self.handle, regs[i])
+ info = core.BNGetArchitectureRegisterStackInfo(self.handle, regs[i])
+ storage = []
+ for j in xrange(0, info.storageCount):
+ storage.append(core.BNGetArchitectureRegisterName(self.handle, info.firstStorageReg + j))
+ top_rel = []
+ for j in xrange(0, info.topRelativeCount):
+ top_rel.append(core.BNGetArchitectureRegisterName(self.handle, info.firstTopRelativeReg + j))
+ top = core.BNGetArchitectureRegisterName(self.handle, info.stackTopReg)
+ self.reg_stacks[name] = function.RegisterStackInfo(storage, top_rel, top, regs[i])
+ core.BNFreeRegisterList(regs)
+
+ count = ctypes.c_ulonglong()
+ intrinsics = core.BNGetAllArchitectureIntrinsics(self.handle, count)
+ self.__dict__["intrinsics"] = {}
+ for i in xrange(0, count.value):
+ name = core.BNGetArchitectureIntrinsicName(self.handle, intrinsics[i])
+ input_count = ctypes.c_ulonglong()
+ inputs = core.BNGetArchitectureIntrinsicInputs(self.handle, intrinsics[i], input_count)
+ input_list = []
+ for j in xrange(0, input_count.value):
+ input_name = inputs[j].name
+ type_obj = types.Type(core.BNNewTypeReference(inputs[j].type), confidence = inputs[j].typeConfidence)
+ input_list.append(function.IntrinsicInput(type_obj, input_name))
+ core.BNFreeNameAndTypeList(inputs, input_count.value)
+ output_count = ctypes.c_ulonglong()
+ outputs = core.BNGetArchitectureIntrinsicOutputs(self.handle, intrinsics[i], output_count)
+ output_list = []
+ for j in xrange(0, output_count.value):
+ output_list.append(types.Type(core.BNNewTypeReference(outputs[j].type), confidence = outputs[j].confidence))
+ core.BNFreeOutputTypeList(outputs, output_count.value)
+ self.intrinsics[name] = function.IntrinsicInfo(input_list, output_list)
else:
startup._init_plugins()
@@ -243,25 +352,48 @@ class Architecture(object):
self._cb.getRegisterName = self._cb.getRegisterName.__class__(self._get_register_name)
self._cb.getFlagName = self._cb.getFlagName.__class__(self._get_flag_name)
self._cb.getFlagWriteTypeName = self._cb.getFlagWriteTypeName.__class__(self._get_flag_write_type_name)
+ self._cb.getFlagSemanticClassName = self._cb.getFlagSemanticClassName.__class__(self._get_semantic_flag_class_name)
+ self._cb.getFlagSemanticGroupName = self._cb.getFlagSemanticGroupName.__class__(self._get_semantic_flag_group_name)
self._cb.getFullWidthRegisters = self._cb.getFullWidthRegisters.__class__(self._get_full_width_registers)
self._cb.getAllRegisters = self._cb.getAllRegisters.__class__(self._get_all_registers)
self._cb.getAllFlags = self._cb.getAllRegisters.__class__(self._get_all_flags)
self._cb.getAllFlagWriteTypes = self._cb.getAllRegisters.__class__(self._get_all_flag_write_types)
+ self._cb.getAllFlagSemanticClasses = self._cb.getAllFlagSemanticClasses.__class__(self._get_all_semantic_flag_classes)
+ self._cb.getAllFlagSemanticGroups = self._cb.getAllFlagSemanticGroups.__class__(self._get_all_semantic_flag_groups)
self._cb.getFlagRole = self._cb.getFlagRole.__class__(self._get_flag_role)
self._cb.getFlagsRequiredForFlagCondition = self._cb.getFlagsRequiredForFlagCondition.__class__(
self._get_flags_required_for_flag_condition)
+ self._cb.getFlagsRequiredForSemanticFlagGroup = self._cb.getFlagsRequiredForSemanticFlagGroup.__class__(
+ self._get_flags_required_for_semantic_flag_group)
+ self._cb.getFlagConditionsForSemanticFlagGroup = self._cb.getFlagConditionsForSemanticFlagGroup.__class__(
+ self._get_flag_conditions_for_semantic_flag_group)
+ self._cb.freeFlagConditionsForSemanticFlagGroup = self._cb.freeFlagConditionsForSemanticFlagGroup.__class__(
+ self._free_flag_conditions_for_semantic_flag_group)
self._cb.getFlagsWrittenByFlagWriteType = self._cb.getFlagsWrittenByFlagWriteType.__class__(
self._get_flags_written_by_flag_write_type)
+ self._cb.getSemanticClassForFlagWriteType = self._cb.getSemanticClassForFlagWriteType.__class__(
+ self._get_semantic_class_for_flag_write_type)
self._cb.getFlagWriteLowLevelIL = self._cb.getFlagWriteLowLevelIL.__class__(
self._get_flag_write_low_level_il)
self._cb.getFlagConditionLowLevelIL = self._cb.getFlagConditionLowLevelIL.__class__(
self._get_flag_condition_low_level_il)
+ self._cb.getSemanticFlagGroupLowLevelIL = self._cb.getSemanticFlagGroupLowLevelIL.__class__(
+ self._get_semantic_flag_group_low_level_il)
self._cb.freeRegisterList = self._cb.freeRegisterList.__class__(self._free_register_list)
self._cb.getRegisterInfo = self._cb.getRegisterInfo.__class__(self._get_register_info)
self._cb.getStackPointerRegister = self._cb.getStackPointerRegister.__class__(
self._get_stack_pointer_register)
self._cb.getLinkRegister = self._cb.getLinkRegister.__class__(self._get_link_register)
self._cb.getGlobalRegisters = self._cb.getGlobalRegisters.__class__(self._get_global_registers)
+ self._cb.getRegisterStackName = self._cb.getRegisterStackName.__class__(self._get_register_stack_name)
+ self._cb.getAllRegisterStacks = self._cb.getAllRegisterStacks.__class__(self._get_all_register_stacks)
+ self._cb.getRegisterStackInfo = self._cb.getRegisterStackInfo.__class__(self._get_register_stack_info)
+ self._cb.getIntrinsicName = self._cb.getIntrinsicName.__class__(self._get_intrinsic_name)
+ self._cb.getAllIntrinsics = self._cb.getAllIntrinsics.__class__(self._get_all_intrinsics)
+ self._cb.getIntrinsicInputs = self._cb.getIntrinsicInputs.__class__(self._get_intrinsic_inputs)
+ self._cb.freeNameAndTypeList = self._cb.freeNameAndTypeList.__class__(self._free_name_and_type_list)
+ self._cb.getIntrinsicOutputs = self._cb.getIntrinsicOutputs.__class__(self._get_intrinsic_outputs)
+ self._cb.freeTypeList = self._cb.freeTypeList.__class__(self._free_type_list)
self._cb.assemble = self._cb.assemble.__class__(self._assemble)
self._cb.isNeverBranchPatchAvailable = self._cb.isNeverBranchPatchAvailable.__class__(
self._is_never_branch_patch_available)
@@ -283,6 +415,30 @@ class Architecture(object):
self._regs_by_index = {}
self.__dict__["regs"] = self.__class__.regs
reg_index = 0
+
+ # Registers used for storage in register stacks must be sequential, so allocate these in order first
+ self._all_reg_stacks = {}
+ self._reg_stacks_by_index = {}
+ self.__dict__["reg_stacks"] = self.__class__.reg_stacks
+ reg_stack_index = 0
+ for reg_stack in self.reg_stacks:
+ info = self.reg_stacks[reg_stack]
+ for reg in info.storage_regs:
+ self._all_regs[reg] = reg_index
+ self._regs_by_index[reg_index] = reg
+ self.regs[reg].index = reg_index
+ reg_index += 1
+ for reg in info.top_relative_regs:
+ self._all_regs[reg] = reg_index
+ self._regs_by_index[reg_index] = reg
+ self.regs[reg].index = reg_index
+ reg_index += 1
+ if reg_stack not in self._all_reg_stacks:
+ self._all_reg_stacks[reg_stack] = reg_stack_index
+ self._reg_stacks_by_index[reg_stack_index] = reg_stack
+ self.reg_stacks[reg_stack].index = reg_stack_index
+ reg_stack_index += 1
+
for reg in self.regs:
info = self.regs[reg]
if reg not in self._all_regs:
@@ -318,6 +474,26 @@ class Architecture(object):
self._flag_write_types_by_index[write_type_index] = write_type
write_type_index += 1
+ self._semantic_flag_classes = {}
+ self._semantic_flag_classes_by_index = {}
+ self.__dict__["semantic_flag_classes"] = self.__class__.semantic_flag_classes
+ semantic_class_index = 1
+ for sem_class in self.__class__.semantic_flag_classes:
+ if sem_class not in self._semantic_flag_classes:
+ self._semantic_flag_classes[sem_class] = semantic_class_index
+ self._semantic_flag_classes_by_index[semantic_class_index] = sem_class
+ semantic_class_index += 1
+
+ self._semantic_flag_groups = {}
+ self._semantic_flag_groups_by_index = {}
+ self.__dict__["semantic_flag_groups"] = self.__class__.semantic_flag_groups
+ semantic_group_index = 0
+ for sem_group in self.__class__.semantic_flag_groups:
+ if sem_group not in self._semantic_flag_groups:
+ self._semantic_flag_groups[sem_group] = semantic_group_index
+ self._semantic_flag_groups_by_index[semantic_group_index] = sem_group
+ semantic_group_index += 1
+
self._flag_roles = {}
self.__dict__["flag_roles"] = self.__class__.flag_roles
for flag in self.__class__.flag_roles:
@@ -326,13 +502,26 @@ class Architecture(object):
role = FlagRole[role]
self._flag_roles[self._flags[flag]] = role
- self._flags_required_for_flag_condition = {}
self.__dict__["flags_required_for_flag_condition"] = self.__class__.flags_required_for_flag_condition
- for cond in self.__class__.flags_required_for_flag_condition:
+
+ self._flags_required_by_semantic_flag_group = {}
+ self.__dict__["flags_required_for_semantic_flag_group"] = self.__class__.flags_required_for_semantic_flag_group
+ for group in self.__class__.flags_required_for_semantic_flag_group:
flags = []
- for flag in self.__class__.flags_required_for_flag_condition[cond]:
+ for flag in self.__class__.flags_required_for_semantic_flag_group[group]:
flags.append(self._flags[flag])
- self._flags_required_for_flag_condition[cond] = flags
+ self._flags_required_by_semantic_flag_group[self._semantic_flag_groups[group]] = flags
+
+ self._flag_conditions_for_semantic_flag_group = {}
+ self.__dict__["flag_conditions_for_semantic_flag_group"] = self.__class__.flag_conditions_for_semantic_flag_group
+ for group in self.__class__.flag_conditions_for_semantic_flag_group:
+ class_cond = {}
+ for sem_class in self.__class__.flag_conditions_for_semantic_flag_group[group]:
+ if sem_class is None:
+ class_cond[0] = self.__class__.flag_conditions_for_semantic_flag_group[group][sem_class]
+ else:
+ class_cond[self._semantic_flag_classes[sem_class]] = self.__class__.flag_conditions_for_semantic_flag_group[group][sem_class]
+ self._flag_conditions_for_semantic_flag_group[self._semantic_flag_groups[group]] = class_cond
self._flags_written_by_flag_write_type = {}
self.__dict__["flags_written_by_flag_write_type"] = self.__class__.flags_written_by_flag_write_type
@@ -342,10 +531,40 @@ class Architecture(object):
flags.append(self._flags[flag])
self._flags_written_by_flag_write_type[self._flag_write_types[write_type]] = flags
+ self._semantic_class_for_flag_write_type = {}
+ self.__dict__["semantic_class_for_flag_write_type"] = self.__class__.semantic_class_for_flag_write_type
+ for write_type in self.__class__.semantic_class_for_flag_write_type:
+ sem_class = self.__class__.semantic_class_for_flag_write_type[write_type]
+ if sem_class in self._semantic_flag_classes:
+ sem_class_index = self._semantic_flag_classes[sem_class]
+ else:
+ sem_class_index = 0
+ self._semantic_class_for_flag_write_type[self._flag_write_types[write_type]] = sem_class_index
+
self.__dict__["global_regs"] = self.__class__.global_regs
+ self._intrinsics = {}
+ self._intrinsics_by_index = {}
+ self.__dict__["intrinsics"] = self.__class__.intrinsics
+ intrinsic_index = 0
+ for intrinsic in self.__class__.intrinsics.keys():
+ if intrinsic not in self._intrinsics:
+ info = self.__class__.intrinsics[intrinsic]
+ for i in xrange(0, len(info.inputs)):
+ if isinstance(info.inputs[i], types.Type):
+ info.inputs[i] = function.IntrinsicInput(info.inputs[i])
+ elif isinstance(info.inputs[i], tuple):
+ info.inputs[i] = function.IntrinsicInput(info.inputs[i][0], info.inputs[i][1])
+ info.index = intrinsic_index
+ self._intrinsics[intrinsic] = intrinsic_index
+ self._intrinsics_by_index[intrinsic_index] = (intrinsic, info)
+ intrinsic_index += 1
+
self._pending_reg_lists = {}
self._pending_token_lists = {}
+ self._pending_condition_lists = {}
+ self._pending_name_and_type_lists = {}
+ self._pending_type_lists = {}
def __eq__(self, value):
if not isinstance(value, Architecture):
@@ -561,6 +780,24 @@ class Architecture(object):
log.log_error(traceback.format_exc())
return core.BNAllocString("")
+ def _get_semantic_flag_class_name(self, ctxt, sem_class):
+ try:
+ if sem_class in self._semantic_flag_class_by_index:
+ return core.BNAllocString(self._semantic_flag_class_by_index[sem_class])
+ return core.BNAllocString("")
+ except (KeyError, OSError):
+ log.log_error(traceback.format_exc())
+ return core.BNAllocString("")
+
+ def _get_semantic_flag_group_name(self, ctxt, sem_group):
+ try:
+ if sem_group in self._semantic_flag_group_by_index:
+ return core.BNAllocString(self._semantic_flag_group_by_index[sem_group])
+ return core.BNAllocString("")
+ except (KeyError, OSError):
+ log.log_error(traceback.format_exc())
+ return core.BNAllocString("")
+
def _get_full_width_registers(self, ctxt, count):
try:
regs = self._full_width_regs.values()
@@ -608,11 +845,11 @@ class Architecture(object):
def _get_all_flag_write_types(self, ctxt, count):
try:
- types = self._flag_write_types_by_index.keys()
- count[0] = len(types)
- type_buf = (ctypes.c_uint * len(types))()
- for i in xrange(0, len(types)):
- type_buf[i] = types[i]
+ write_types = self._flag_write_types_by_index.keys()
+ count[0] = len(write_types)
+ type_buf = (ctypes.c_uint * len(write_types))()
+ for i in xrange(0, len(write_types)):
+ type_buf[i] = write_types[i]
result = ctypes.cast(type_buf, ctypes.c_void_p)
self._pending_reg_lists[result.value] = (result, type_buf)
return result.value
@@ -621,19 +858,83 @@ class Architecture(object):
count[0] = 0
return None
- def _get_flag_role(self, ctxt, flag):
+ def _get_all_semantic_flag_classes(self, ctxt, count):
+ try:
+ sem_classes = self._semantic_flag_classes_by_index.keys()
+ count[0] = len(sem_classes)
+ class_buf = (ctypes.c_uint * len(sem_classes))()
+ for i in xrange(0, len(sem_classes)):
+ class_buf[i] = sem_classes[i]
+ result = ctypes.cast(class_buf, ctypes.c_void_p)
+ self._pending_reg_lists[result.value] = (result, class_buf)
+ return result.value
+ except KeyError:
+ log.log_error(traceback.format_exc())
+ count[0] = 0
+ return None
+
+ def _get_all_semantic_flag_groups(self, ctxt, count):
try:
- if flag in self._flag_roles:
- return self._flag_roles[flag]
+ sem_groups = self._semantic_flag_groups_by_index.keys()
+ count[0] = len(sem_groups)
+ group_buf = (ctypes.c_uint * len(sem_groups))()
+ for i in xrange(0, len(sem_groups)):
+ group_buf[i] = sem_groups[i]
+ result = ctypes.cast(group_buf, ctypes.c_void_p)
+ self._pending_reg_lists[result.value] = (result, group_buf)
+ return result.value
+ except KeyError:
+ log.log_error(traceback.format_exc())
+ count[0] = 0
+ return None
+
+ def _get_flag_role(self, ctxt, flag, sem_class):
+ try:
+ if sem_class in self._semantic_flag_classes_by_index:
+ sem_class = self._semantic_flag_classes_by_index[sem_class]
+ else:
+ sem_class = None
+ return self.perform_get_flag_role(flag, sem_class)
+ except KeyError:
+ log.log_error(traceback.format_exc())
return FlagRole.SpecialFlagRole
+
+ def perform_get_flag_role(self, flag, sem_class):
+ if flag in self._flag_roles:
+ return self._flag_roles[flag]
+ return FlagRole.SpecialFlagRole
+
+ def _get_flags_required_for_flag_condition(self, ctxt, cond, sem_class, count):
+ try:
+ if sem_class in self._semantic_flag_classes_by_index:
+ sem_class = self._semantic_flag_classes_by_index[sem_class]
+ else:
+ sem_class = None
+ flag_names = self.perform_get_flags_required_for_flag_condition(cond, sem_class)
+ flags = []
+ for name in flag_names:
+ flags.append(self._flags[name])
+ count[0] = len(flags)
+ flag_buf = (ctypes.c_uint * len(flags))()
+ for i in xrange(0, len(flags)):
+ flag_buf[i] = flags[i]
+ result = ctypes.cast(flag_buf, ctypes.c_void_p)
+ self._pending_reg_lists[result.value] = (result, flag_buf)
+ return result.value
except KeyError:
log.log_error(traceback.format_exc())
+ count[0] = 0
return None
- def _get_flags_required_for_flag_condition(self, ctxt, cond, count):
+ def perform_get_flags_required_for_flag_condition(self, cond, sem_class):
+ if cond in self.flags_required_for_flag_condition:
+ return self.flags_required_for_flag_condition[cond]
+ return []
+
+ def _get_flags_required_for_semantic_flag_group(self, ctxt, sem_group, count):
try:
- if cond in self._flags_required_for_flag_condition:
- flags = self._flags_required_for_flag_condition[cond]
+ if sem_group in self._flags_required_by_semantic_flag_group:
+ flags = self._flags_required_by_semantic_flag_group[sem_group]
else:
flags = []
count[0] = len(flags)
@@ -643,11 +944,41 @@ class Architecture(object):
result = ctypes.cast(flag_buf, ctypes.c_void_p)
self._pending_reg_lists[result.value] = (result, flag_buf)
return result.value
- except KeyError:
+ except (KeyError, OSError):
log.log_error(traceback.format_exc())
count[0] = 0
return None
+ def _get_flag_conditions_for_semantic_flag_group(self, ctxt, sem_group, count):
+ try:
+ if sem_group in self._flag_conditions_by_semantic_flag_group:
+ class_cond = self._flag_conditions_by_semantic_flag_group[sem_group]
+ else:
+ class_cond = {}
+ count[0] = len(class_cond)
+ cond_buf = (core.BNFlagConditionForSemanticClass * len(class_cond))()
+ i = 0
+ for class_index in class_cond.keys():
+ cond_buf[i].semanticClass = class_index
+ cond_buf[i].condition = class_cond[class_index]
+ i += 1
+ result = ctypes.cast(cond_buf, ctypes.c_void_p)
+ self._pending_conditions[result.value] = (result, cond_buf)
+ return result.value
+ except (KeyError, OSError):
+ log.log_error(traceback.format_exc())
+ count[0] = 0
+ return None
+
+ def _free_flag_conditions_for_semantic_flag_group(self, ctxt, conditions):
+ try:
+ buf = ctypes.cast(conditions, ctypes.c_void_p)
+ if buf.value not in self._pending_conditions:
+ raise ValueError("freeing condition list that wasn't allocated")
+ del self._pending_conditions[buf.value]
+ except (ValueError, KeyError):
+ log.log_error(traceback.format_exc())
+
def _get_flags_written_by_flag_write_type(self, ctxt, write_type, count):
try:
if write_type in self._flags_written_by_flag_write_type:
@@ -666,6 +997,16 @@ class Architecture(object):
count[0] = 0
return None
+ def _get_semantic_class_for_flag_write_type(self, ctxt, write_type):
+ try:
+ if write_type in self._semantic_class_for_flag_write_type:
+ return self._semantic_class_for_flag_write_type[write_type]
+ else:
+ return 0
+ except (KeyError, OSError):
+ log.log_error(traceback.format_exc())
+ return 0
+
def _get_flag_write_low_level_il(self, ctxt, op, size, write_type, flag, operands, operand_count, il):
try:
write_type_name = None
@@ -686,9 +1027,25 @@ class Architecture(object):
log.log_error(traceback.format_exc())
return False
- def _get_flag_condition_low_level_il(self, ctxt, cond, il):
+ def _get_flag_condition_low_level_il(self, ctxt, cond, sem_class, il):
+ try:
+ if sem_class in self._semantic_flag_classes_by_index:
+ sem_class_name = self._semantic_flag_classes_by_index[sem_class]
+ else:
+ sem_class_name = None
+ return self.perform_get_flag_condition_low_level_il(cond, sem_class_name,
+ lowlevelil.LowLevelILFunction(self, core.BNNewLowLevelILFunctionReference(il))).index
+ except OSError:
+ log.log_error(traceback.format_exc())
+ return 0
+
+ def _get_semantic_flag_group_low_level_il(self, ctxt, sem_group, il):
try:
- return self.perform_get_flag_condition_low_level_il(cond,
+ if sem_group in self._semantic_flag_groups_by_index:
+ sem_group_name = self._semantic_flag_groups_by_index[sem_group]
+ else:
+ sem_group_name = None
+ return self.perform_get_semantic_flag_group_low_level_il(sem_group_name,
lowlevelil.LowLevelILFunction(self, core.BNNewLowLevelILFunctionReference(il))).index
except OSError:
log.log_error(traceback.format_exc())
@@ -756,6 +1113,146 @@ class Architecture(object):
count[0] = 0
return None
+ def _get_register_stack_name(self, ctxt, reg_stack):
+ try:
+ if reg_stack in self._reg_stacks_by_index:
+ return core.BNAllocString(self._reg_stacks_by_index[reg_stack])
+ return core.BNAllocString("")
+ except (KeyError, OSError):
+ log.log_error(traceback.format_exc())
+ return core.BNAllocString("")
+
+ def _get_all_register_stacks(self, ctxt, count):
+ try:
+ regs = self._reg_stacks_by_index.keys()
+ count[0] = len(regs)
+ reg_buf = (ctypes.c_uint * len(regs))()
+ for i in xrange(0, len(regs)):
+ reg_buf[i] = regs[i]
+ result = ctypes.cast(reg_buf, ctypes.c_void_p)
+ self._pending_reg_lists[result.value] = (result, reg_buf)
+ return result.value
+ except KeyError:
+ log.log_error(traceback.format_exc())
+ count[0] = 0
+ return None
+
+ def _get_register_stack_info(self, ctxt, reg_stack, result):
+ try:
+ if reg_stack not in self._reg_stacks_by_index:
+ result[0].firstStorageReg = 0
+ result[0].firstTopRelativeReg = 0
+ result[0].storageCount = 0
+ result[0].topRelativeCount = 0
+ result[0].stackTopReg = 0
+ return
+ info = self.__class__.regs[self._reg_stacks_by_index[reg_stack]]
+ result[0].firstStorageReg = self._all_regs[info.storage_regs[0]]
+ result[0].storageCount = len(info.storage_regs)
+ if len(info.top_relative_regs) > 0:
+ result[0].firstTopRelativeReg = self._all_regs[info.top_relative_regs[0]]
+ result[0].topRelativeCount = len(info.top_relative_regs)
+ else:
+ result[0].firstTopRelativeReg = 0
+ result[0].topRelativeCount = 0
+ result[0].stackTopReg = self._all_regs[info.stack_top_reg]
+ except KeyError:
+ log.log_error(traceback.format_exc())
+ result[0].firstStorageReg = 0
+ result[0].firstTopRelativeReg = 0
+ result[0].storageCount = 0
+ result[0].topRelativeCount = 0
+ result[0].stackTopReg = 0
+
+ def _get_intrinsic_name(self, ctxt, intrinsic):
+ try:
+ if intrinsic in self._intrinsics_by_index:
+ return core.BNAllocString(self._intrinsics_by_index[intrinsic][0])
+ return core.BNAllocString("")
+ except (KeyError, OSError):
+ log.log_error(traceback.format_exc())
+ return core.BNAllocString("")
+
+ def _get_all_intrinsics(self, ctxt, count):
+ try:
+ regs = self._intrinsics_by_index.keys()
+ count[0] = len(regs)
+ reg_buf = (ctypes.c_uint * len(regs))()
+ for i in xrange(0, len(regs)):
+ reg_buf[i] = regs[i]
+ result = ctypes.cast(reg_buf, ctypes.c_void_p)
+ self._pending_reg_lists[result.value] = (result, reg_buf)
+ return result.value
+ except KeyError:
+ log.log_error(traceback.format_exc())
+ count[0] = 0
+ return None
+
+ def _get_intrinsic_inputs(self, ctxt, intrinsic, count):
+ try:
+ if intrinsic in self._intrinsics_by_index:
+ inputs = self._intrinsics_by_index[intrinsic][1].inputs
+ count[0] = len(inputs)
+ input_buf = (core.BNNameAndType * len(inputs))()
+ for i in xrange(0, len(inputs)):
+ input_buf[i].name = inputs[i].name
+ input_buf[i].type = core.BNNewTypeReference(inputs[i].type.handle)
+ input_buf[i].typeConfidence = inputs[i].type.confidence
+ result = ctypes.cast(input_buf, ctypes.c_void_p)
+ self._pending_name_and_type_lists[result.value] = (result, input_buf, len(inputs))
+ return result.value
+ count[0] = 0
+ return None
+ except:
+ log.log_error(traceback.format_exc())
+ count[0] = 0
+ return None
+
+ def _free_name_and_type_list(self, ctxt, buf_raw):
+ try:
+ buf = ctypes.cast(buf_raw, ctypes.c_void_p)
+ if buf.value not in self._pending_name_and_type_lists:
+ raise ValueError("freeing name and type list that wasn't allocated")
+ name_and_types = self._pending_name_and_type_lists[buf.value][1]
+ count = self._pending_name_and_type_lists[buf.value][2]
+ for i in xrange(0, count):
+ core.BNFreeType(name_and_types[i].type)
+ del self._pending_name_and_type_lists[buf.value]
+ except (ValueError, KeyError):
+ log.log_error(traceback.format_exc())
+
+ def _get_intrinsic_outputs(self, ctxt, intrinsic, count):
+ try:
+ if intrinsic in self._intrinsics_by_index:
+ outputs = self._intrinsics_by_index[intrinsic][1].outputs
+ count[0] = len(outputs)
+ output_buf = (core.BNTypeWithConfidence * len(outputs))()
+ for i in xrange(0, len(outputs)):
+ output_buf[i].type = core.BNNewTypeReference(outputs[i].handle)
+ output_buf[i].confidence = outputs[i].confidence
+ result = ctypes.cast(output_buf, ctypes.c_void_p)
+ self._pending_type_lists[result.value] = (result, output_buf, len(outputs))
+ return result.value
+ count[0] = 0
+ return None
+ except:
+ log.log_error(traceback.format_exc())
+ count[0] = 0
+ return None
+
+ def _free_type_list(self, ctxt, buf_raw):
+ try:
+ 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]
+ count = self._pending_type_lists[buf.value][2]
+ for i in xrange(0, count):
+ core.BNFreeType(types[i].type)
+ del self._pending_type_lists[buf.value]
+ except (ValueError, KeyError):
+ log.log_error(traceback.format_exc())
+
def _assemble(self, ctxt, code, addr, result, errors):
try:
data, error_str = self.perform_assemble(code, addr)
@@ -959,16 +1456,29 @@ class Architecture(object):
return self.get_default_flag_write_low_level_il(op, size, self._flag_roles[flag], operands, il)
@abc.abstractmethod
- def perform_get_flag_condition_low_level_il(self, cond, il):
+ def perform_get_flag_condition_low_level_il(self, cond, sem_class, il):
"""
.. note:: Architecture subclasses should implement this method.
.. warning:: This method should never be called directly.
- :param LowLevelILFlagCondition cond:
- :param LowLevelILFunction il:
+ :param LowLevelILFlagCondition cond: Flag condition to be computed
+ :param str sem_class: Semantic class to be used (None for default semantics)
+ :param LowLevelILFunction il: LowLevelILFunction object to append LowLevelILExpr objects to
:rtype: LowLevelILExpr
"""
- return self.get_default_flag_condition_low_level_il(cond, il)
+ return self.get_default_flag_condition_low_level_il(cond, sem_class, il)
+
+ @abc.abstractmethod
+ def perform_get_semantic_flag_group_low_level_il(self, sem_group, il):
+ """
+ .. note:: Architecture subclasses should implement this method.
+ .. warning:: This method should never be called directly.
+
+ :param str sem_group: Semantic group to be computed
+ :param LowLevelILFunction il: LowLevelILFunction object to append LowLevelILExpr objects to
+ :rtype: LowLevelILExpr
+ """
+ return il.unimplemented()
@abc.abstractmethod
def perform_assemble(self, code, addr):
@@ -1264,6 +1774,23 @@ class Architecture(object):
"""
return core.BNGetArchitectureRegisterName(self.handle, reg)
+ def get_reg_stack_name(self, reg_stack):
+ """
+ ``get_reg_stack_name`` gets a register stack name from a register stack number.
+
+ :param int reg_stack: register stack number
+ :return: the corresponding register string
+ :rtype: str
+ """
+ return core.BNGetArchitectureRegisterStackName(self.handle, reg_stack)
+
+ def get_reg_stack_for_reg(self, reg):
+ reg = self.get_reg_index(reg)
+ result = core.BNGetArchitectureRegisterStackForRegister(self.handle, reg)
+ if result == 0xffffffff:
+ return None
+ return self.get_reg_stack_name(result)
+
def get_flag_name(self, flag):
"""
``get_flag_name`` gets a flag name from a flag number.
@@ -1281,6 +1808,13 @@ class Architecture(object):
return reg.index
return reg
+ def get_reg_stack_index(self, reg_stack):
+ if isinstance(reg_stack, str):
+ return self.reg_stacks[reg_stack].index
+ elif isinstance(reg_stack, lowlevelil.ILRegisterStack):
+ return reg_stack.index
+ return reg_stack
+
def get_flag_index(self, flag):
if isinstance(flag, str):
return self._flags[flag]
@@ -1288,6 +1822,39 @@ class Architecture(object):
return flag.index
return flag
+ def get_semantic_flag_class_index(self, sem_class):
+ if sem_class is None:
+ return 0
+ elif isinstance(sem_class, str):
+ return self._semantic_flag_classes[sem_class]
+ elif isinstance(sem_class, lowlevelil.ILSemanticFlagClass):
+ return sem_class.index
+ return sem_class
+
+ def get_semantic_flag_group_index(self, sem_group):
+ if isinstance(sem_group, str):
+ return self._semantic_flag_groups[sem_group]
+ elif isinstance(sem_group, lowlevelil.ILSemanticFlagGroup):
+ return sem_group.index
+ return sem_group
+
+ def get_intrinsic_name(self, intrinsic):
+ """
+ ``get_intrinsic_name`` gets an intrinsic name from an intrinsic number.
+
+ :param int intrinsic: intrinsic number
+ :return: the corresponding intrinsic string
+ :rtype: str
+ """
+ return core.BNGetArchitectureIntrinsicName(self.handle, intrinsic)
+
+ def get_intrinsic_index(self, intrinsic):
+ if isinstance(intrinsic, str):
+ return self._intrinsics[intrinsic]
+ elif isinstance(intrinsic, lowlevelil.ILIntrinsic):
+ return intrinsic.index
+ return intrinsic
+
def get_flag_write_type_name(self, write_type):
"""
``get_flag_write_type_name`` gets the flag write type name for the given flag.
@@ -1318,6 +1885,39 @@ class Architecture(object):
"""
return self._flag_write_types[write_type]
+ def get_semantic_flag_class_by_name(self, sem_class):
+ """
+ ``get_semantic_flag_class_by_name`` gets the semantic flag class index by name.
+
+ :param int sem_class: semantic flag class
+ :return: semantic flag class index
+ :rtype: str
+ """
+ return self._semantic_flag_classes[sem_class]
+
+ def get_semantic_flag_group_by_name(self, sem_group):
+ """
+ ``get_semantic_flag_group_by_name`` gets the semantic flag group index by name.
+
+ :param int sem_group: semantic flag group
+ :return: semantic flag group index
+ :rtype: str
+ """
+ return self._semantic_flag_groups[sem_group]
+
+ def get_flag_role(self, flag, sem_class = None):
+ """
+ ``get_flag_role`` gets the role of a given flag.
+
+ :param int flag: flag
+ :param int sem_class: optional semantic flag class
+ :return: flag role
+ :rtype: FlagRole
+ """
+ flag = self.get_flag_index(flag)
+ sem_class = self.get_semantic_flag_class_index(sem_class)
+ return FlagRole(core.BNGetArchitectureFlagRole(self.handle, flag, sem_class))
+
def get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il):
"""
:param LowLevelILOperation op:
@@ -1375,13 +1975,34 @@ class Architecture(object):
"""
return lowlevelil.LowLevelILExpr(core.BNGetArchitectureFlagConditionLowLevelIL(self.handle, cond, il.handle))
- def get_default_flag_condition_low_level_il(self, cond, il):
+ def get_default_flag_condition_low_level_il(self, cond, sem_class, il):
"""
:param LowLevelILFlagCondition cond:
:param LowLevelILFunction il:
+ :param str sem_class:
+ :rtype: LowLevelILExpr
+ """
+ class_index = self.get_semantic_flag_class_index(sem_class)
+ return lowlevelil.LowLevelILExpr(core.BNGetDefaultArchitectureFlagConditionLowLevelIL(self.handle, cond, class_index, il.handle))
+
+ def get_semantic_flag_group_low_level_il(self, sem_group, il):
+ """
+ :param str sem_group:
+ :param LowLevelILFunction il:
:rtype: LowLevelILExpr
"""
- return lowlevelil.LowLevelILExpr(core.BNGetDefaultArchitectureFlagConditionLowLevelIL(self.handle, cond, il.handle))
+ group_index = self.get_semantic_flag_group_index(sem_group)
+ return lowlevelil.LowLevelILExpr(core.BNGetArchitectureSemanticFlagGroupLowLevelIL(self.handle, group_index, il.handle))
+
+ def get_flags_required_for_flag_condition(self, cond, sem_class = None):
+ sem_class = self.get_semantic_flag_class_index(sem_class)
+ count = ctypes.c_ulonglong()
+ flags = core.BNGetArchitectureFlagsRequiredForFlagCondition(self.handle, cond, sem_class, count)
+ flag_names = []
+ for i in xrange(0, count.value):
+ flag_names.append(self._flags_by_index[flags[i]])
+ core.BNFreeRegisterList(flags)
+ return flag_names
def get_modified_regs_on_write(self, reg):
"""