def _check_potential_array(cfunc, expr): """ Checks `call(..., &buffer, ..., number)` and returns information for recasting """ if expr.op != idaapi.cot_var: return var_expr = expr.to_specific_type parent = cfunc.body.find_parent_of(expr) if parent.op != idaapi.cot_ref: return parent = cfunc.body.find_parent_of(parent) if parent.op != idaapi.cot_call: return call_expr = parent.to_specific_type for arg_expr in call_expr.a: if arg_expr.op == idaapi.cot_num: number = arg_expr.numval() if number: variable = cfunc.lvars[var_expr.v.idx] char_array_tinfo = idaapi.tinfo_t() char_array_tinfo.create_array( idaapi.tinfo_t(idaapi.BTF_CHAR), number) idaapi.update_action_label( RecastItemRight.name, 'Recast Variable "{}" to "{}"'.format( variable.name, char_array_tinfo.dstr())) return RecastLocalVariable(char_array_tinfo, variable)
def populating_tform_popup(self, form, popup): global highlight if idaapi.get_tform_type(form) == idaapi.BWN_DISASM: highlight = idaapi.get_highlight(form) if highlight: idaapi.update_action_label("search:action", "Search Google for \"" + highlight[0] + "\"") idaapi.attach_action_to_popup(form, popup, "search:action", None)
def extract_recast_info(self, cfunc, ctree_item): if ctree_item.citype != idaapi.VDI_EXPR: return expression = ctree_item.it result = RecastItemRight._check_potential_array(cfunc, expression) if result: return result # Look through parents until we found Cast while expression and expression.op != idaapi.cot_cast: expression = expression.to_specific_type expression = cfunc.body.find_parent_of(expression) if not expression: return expression = expression.to_specific_type # Find `(TYPE) something;` or `(TYPE *) &something;` and calculate appropriate type for recast if expression.x.op == idaapi.cot_ref: tinfo = expression.type.get_pointed_object() expression = expression.x else: tinfo = expression.type if expression.x.op == idaapi.cot_var: # (TYPE) var; variable = cfunc.get_lvars()[expression.x.v.idx] return RecastLocalVariable(tinfo, variable) elif expression.x.op == idaapi.cot_obj: # (TYPE) g_var; if helper.is_code_ea(expression.x.obj_ea) and tinfo.is_funcptr(): # (TYPE) sub_XXXXXX; tinfo = tinfo.get_pointed_object() gvar_ea = expression.x.obj_ea return RecastGlobalVariable(tinfo, gvar_ea) elif expression.x.op == idaapi.cot_call: # (TYPE) call(); idaapi.update_action_label(RecastItemRight.name, "Recast Return") func_ea = expression.x.x.obj_ea return RecastReturn(tinfo, func_ea) elif expression.x.op == idaapi.cot_memptr: # (TYPE) var->member; idaapi.update_action_label(RecastItemRight.name, "Recast Field") struct_name = expression.x.x.type.get_pointed_object().dstr() struct_offset = expression.x.m return RecastStructure(tinfo, struct_name, struct_offset)
def check(cfunc, ctree_item): if ctree_item.citype == idaapi.VDI_EXPR: expression = ctree_item.it while expression and expression.op != idaapi.cot_cast: expression = expression.to_specific_type expression = cfunc.body.find_parent_of(expression) if expression: expression = expression.to_specific_type if expression.x.op == idaapi.cot_ref: new_type = expression.type.get_pointed_object() expression = expression.x else: new_type = expression.type if expression.x.op == idaapi.cot_var: variable = cfunc.get_lvars()[expression.x.v.idx] idaapi.update_action_label( RecastItemRight.name, 'Recast Variable "{0}"'.format(variable.name)) return RECAST_LOCAL_VARIABLE, new_type, variable elif expression.x.op == idaapi.cot_obj: idaapi.update_action_label(RecastItemRight.name, 'Recast Global') return RECAST_GLOBAL_VARIABLE, new_type, expression.x.obj_ea elif expression.x.op == idaapi.cot_call: idaapi.update_action_label(RecastItemRight.name, "Recast Return") return RECAST_RETURN, new_type, expression.x.x.obj_ea
def check(cfunc, ctree_item): if ctree_item.citype == idaapi.VDI_EXPR: expression = ctree_item.it.to_specific_type child = None while expression and expression.op not in (idaapi.cot_asg, idaapi.cit_return, idaapi.cot_call): child = expression.to_specific_type expression = cfunc.body.find_parent_of(expression) if expression: expression = expression.to_specific_type if expression.op == idaapi.cot_asg and \ expression.x.op in (idaapi.cot_var, idaapi.cot_obj, idaapi.cot_memptr, idaapi.cot_memref): right_expr = expression.y right_tinfo = right_expr.x.type if right_expr.op == idaapi.cot_cast else right_expr.type # Check if both left and right parts of expression are of the same types. # If no then we can recast then. if right_tinfo.dstr() == expression.x.type.dstr(): return if expression.x.op == idaapi.cot_var: variable = cfunc.get_lvars()[expression.x.v.idx] idaapi.update_action_label( RecastItemLeft.name, 'Recast Variable "{0}"'.format(variable.name)) return RECAST_LOCAL_VARIABLE, right_tinfo, variable elif expression.x.op == idaapi.cot_obj: idaapi.update_action_label(RecastItemLeft.name, 'Recast Global') return RECAST_GLOBAL_VARIABLE, right_tinfo, expression.x.obj_ea elif expression.x.op == idaapi.cot_memptr: idaapi.update_action_label(RecastItemLeft.name, 'Recast Field') return RECAST_STRUCTURE, expression.x.x.type.get_pointed_object( ).dstr(), expression.x.m, right_tinfo elif expression.x.op == idaapi.cot_memref: idaapi.update_action_label(RecastItemLeft.name, 'Recast Field') return RECAST_STRUCTURE, expression.x.x.type.dstr( ), expression.x.m, right_tinfo elif expression.op == idaapi.cit_return: idaapi.update_action_label(RecastItemLeft.name, "Recast Return") child = child or expression.creturn.expr if child.op == idaapi.cot_cast: return RECAST_RETURN, child.x.type, None func_tinfo = idaapi.tinfo_t() cfunc.get_func_type(func_tinfo) rettype = func_tinfo.get_rettype() print func_tinfo.get_rettype().dstr(), child.type.dstr() if func_tinfo.get_rettype().dstr() != child.type.dstr(): return RECAST_RETURN, child.type, None elif expression.op == idaapi.cot_call: if expression.x.op == idaapi.cot_memptr: # TODO: Recast arguments of virtual functions return if child and child.op == idaapi.cot_cast: if child.cexpr.x.op == idaapi.cot_memptr: idaapi.update_action_label( RecastItemLeft.name, 'Recast Virtual Function') return RECAST_STRUCTURE, child.cexpr.x.x.type.get_pointed_object( ).dstr(), child.cexpr.x.m, child.type arg_index, _ = Helper.get_func_argument_info( expression, child.cexpr) idaapi.update_action_label(RecastItemLeft.name, "Recast Argument") return (RECAST_ARGUMENT, arg_index, expression.x.type.get_pointed_object(), child.x.type, expression.x.obj_ea)
def finish_populating_widget_popup(self, form, popup): try: b = idaapi.get_widget_type(form) == idaapi.BWN_DISASM except: b = idaapi.get_tform_type(form) == idaapi.BWN_DISASM if b: # Add separator idaapi.attach_action_to_popup(form, popup, None, None) # Add actions try: currentAddress = idc.get_screen_ea() except: currentAddress = idc.ScreenEA() #if currentAddress in [node.node_id for node in self.cc.PatternGenerator.targetNodes]: if currentAddress in self.cc.PatternGenerator.coloredNodes: idaapi.attach_action_to_popup(form, popup, "grap:pg:match_default", None) idaapi.attach_action_to_popup(form, popup, "grap:pg:match_full", None) idaapi.update_action_label( "grap:pg:match_full", self.cc.PatternGenerator.preview_match( currentAddress, "[grap] Full match", "match_full")) idaapi.attach_action_to_popup(form, popup, "grap:pg:match_opcode_arg1", None) idaapi.update_action_label( "grap:pg:match_opcode_arg1", self.cc.PatternGenerator.preview_match( currentAddress, "[grap] Opcode+arg1", "match_opcode_arg1")) idaapi.attach_action_to_popup(form, popup, "grap:pg:match_opcode_arg2", None) idaapi.update_action_label( "grap:pg:match_opcode_arg2", self.cc.PatternGenerator.preview_match( currentAddress, "[grap] Opcode+arg2", "match_opcode_arg2")) idaapi.attach_action_to_popup(form, popup, "grap:pg:match_opcode", None) idaapi.update_action_label( "grap:pg:match_opcode", self.cc.PatternGenerator.preview_match( currentAddress, "[grap] Opcode", "match_opcode")) idaapi.attach_action_to_popup(form, popup, "grap:pg:match_wildcard", None) idaapi.attach_action_to_popup(form, popup, "grap:pg:remove_target", None) for type in [ "match_default", "match_full", "match_opcode_arg1", "match_opcode_arg2", "match_opcode", "match_wildcard" ]: idaapi.update_action_icon("grap:pg:" + type, -1) if currentAddress not in self.cc.PatternGenerator.targetNodeType: type = "match_default" else: type = self.cc.PatternGenerator.targetNodeType[ currentAddress] idaapi.update_action_icon("grap:pg:" + type, self.selected_icon_number) elif self.cc.PatternGenerator.rootNode is None or currentAddress != self.cc.PatternGenerator.rootNode.node_id: idaapi.attach_action_to_popup(form, popup, "grap:pg:set_root", None) idaapi.attach_action_to_popup(form, popup, "grap:pg:add_target", None)
def set_label(self, label): idaapi.update_action_label(self.name, label)
def check(cfunc, ctree_item): if ctree_item.citype == idaapi.VDI_EXPR: expression = ctree_item.it.to_specific_type child = None while expression and expression.op not in (idaapi.cot_asg, idaapi.cit_return, idaapi.cot_call): child = expression.to_specific_type expression = cfunc.body.find_parent_of(expression) if expression: expression = expression.to_specific_type if expression.op == idaapi.cot_asg and \ expression.x.op in (idaapi.cot_var, idaapi.cot_obj, idaapi.cot_memptr, idaapi.cot_memref) \ and expression.y.op == idaapi.cot_cast: if expression.x.op == idaapi.cot_var: variable = cfunc.get_lvars()[expression.x.v.idx] idaapi.update_action_label( RecastItemLeft.name, 'Recast Variable "{0}"'.format(variable.name)) return RECAST_LOCAL_VARIABLE, expression.y.x.type, variable elif expression.x.op == idaapi.cot_obj: idaapi.update_action_label(RecastItemLeft.name, 'Recast Global') return RECAST_GLOBAL_VARIABLE, expression.y.x.type, expression.x.obj_ea elif expression.x.op == idaapi.cot_memptr: idaapi.update_action_label(RecastItemLeft.name, 'Recast Field') return RECAST_STRUCTURE, expression.x.x.type.get_pointed_object( ).dstr(), expression.x.m, expression.y.x.type elif expression.x.op == idaapi.cot_memref: idaapi.update_action_label(RecastItemLeft.name, 'Recast Field') return RECAST_STRUCTURE, expression.x.x.type.dstr( ), expression.x.m, expression.y.x.type elif expression.op == idaapi.cit_return: child = child or expression.creturn.expr if child.op == idaapi.cot_cast: idaapi.update_action_label(RecastItemLeft.name, "Recast Return") return RECAST_RETURN, child.x.type, None elif expression.op == idaapi.cot_call: if child and child.op == idaapi.cot_cast: if child.cexpr.x.op == idaapi.cot_memptr: idaapi.update_action_label( RecastItemLeft.name, 'Recast Virtual Function') return RECAST_STRUCTURE, child.cexpr.x.x.type.get_pointed_object( ).dstr(), child.cexpr.x.m, child.type arg_index, _ = Helper.get_func_argument_info( expression, child.cexpr) idaapi.update_action_label(RecastItemLeft.name, "Recast Argument") return (RECAST_ARGUMENT, arg_index, expression.x.type.get_pointed_object(), child.x.type, expression.x.obj_ea)