Source code for angr.analyses.class_identifier

from ..sim_type import SimCppClass, SimTypeCppFunction
from ..analyses import AnalysesHub
from . import Analysis, CFGFast, VtableFinder


[docs]class ClassIdentifier(Analysis): """ This is a class identifier for non stripped or partially stripped binaries, it identifies classes based on the demangled function names, and also assigns functions to their respective classes based on their names. It also uses the results from the VtableFinder analysis to assign the corresponding vtable to the classes. self.classes contains a mapping between class names and SimCppClass objects e.g. A::tool() and A::qux() belong to the class A """
[docs] def __init__(self): if "CFGFast" not in self.project.kb.cfgs: self.project.analyses[CFGFast].prep()(cross_references=True) self.classes = {} vtable_analysis = self.project.analyses[VtableFinder].prep()() self.vtables_list = vtable_analysis.vtables_list self._analyze()
def _analyze(self): # Assigning function to classes for func in self.project.kb.functions.values(): if func.is_plt: continue col_ind = func.demangled_name.rfind("::") class_name = func.demangled_name[:col_ind] if class_name.startswith("non-virtual thunk for "): class_name = class_name[len("non-virtual thunk for ") :] if col_ind != -1: if class_name not in self.classes: ctor = False if func.demangled_name.find("{ctor}"): ctor = True function_members = {func.addr: SimTypeCppFunction([], None, label=func.demangled_name, ctor=ctor)} new_class = SimCppClass(name=class_name, function_members=function_members) self.classes[class_name] = new_class else: ctor = False if func.demangled_name.find("{ctor}"): ctor = True cur_class = self.classes[class_name] cur_class.function_members[func.addr] = SimTypeCppFunction( [], None, label=func.demangled_name, ctor=ctor ) # Assigning a vtable to a class for vtable in self.vtables_list: for ref in self.project.kb.xrefs.xrefs_by_dst[vtable.vaddr]: vtable_calling_func = self.project.kb.functions.floor_func(ref.ins_addr) tmp_col_ind = vtable_calling_func.demangled_name.rfind("::") possible_constructor_class_name = vtable_calling_func.demangled_name[:tmp_col_ind] if "ctor" in vtable_calling_func.demangled_name and possible_constructor_class_name in self.classes: self.classes[possible_constructor_class_name].vtable_ptrs.append(vtable.vaddr)
AnalysesHub.register_default("ClassIdentifier", ClassIdentifier)