def _populate_vmethods_struct(sid, classinfo): """Populate the ::vmethods struct.""" # Loop over the new vtable methods. super_nmethods = 0 if classinfo.superclass: super_nmethods = classinfo.superclass.vtable_nmethods members = set() for index, vmethod in enumerate(vtable.class_vtable_methods(classinfo)): # Skip entries in the superclass's vtable. if index < super_nmethods: continue # Get the base name of the method (i.e., for Class::method(args), extract method). sym = idau.get_ea_name(vmethod, user=True) base = symbol.method_name(sym) if not base: base = 'method_{}'.format(index) base = symbol.make_ident(base) # We'll try to use the base as our method name, but if it already exists, try appending # "_1", "_2", etc. name = base suffix = 0 while name in members: suffix += 1 name = '{}_{}'.format(base, suffix) members.add(name) # Create the member. offset = (index - super_nmethods) * idau.WORD_SIZE ret = idau.struct_add_ptr(sid, name, offset, type='void *') if ret != 0: _log(0, 'Could not create {}::vmethods.{}: {}', classinfo.classname, name, ret) return False return True
def _propagate_virtual_method_types_for_class(classinfo): """Propagate the types of a class's virtual methods to the vtable struct.""" for relative_index, vmethod in enumerate( vtable.class_vtable_methods(classinfo, new=True)): _propagate_virtual_method_type_for_method(classinfo, relative_index, vmethod)