def __create_class_name_type(bv: BinaryView, vmt: DelphiVMT, out_struct: types.Structure) -> bool: vmt_offsets = vmt.vmt_offsets if not vmt.seek_to_vmt_offset(vmt_offsets.cVmtClassName): return False class_name_ptr = vmt.read_ptr() if class_name_ptr is None: return False if not vmt.seek_to_code(class_name_ptr): return False class_name_len = vmt.read8() if class_name_len is None: return False class_name_struct = types.Structure() class_name_struct.append(Type.int(1, False), 'length') class_name_struct.append(Type.array(Type.char(), class_name_len), 'value') struct_type = Type.structure_type(class_name_struct) bv.define_user_data_var(class_name_ptr, struct_type) out_struct.append(Type.pointer(bv.arch, struct_type), 'cVmtClassName') # Create Symbole for class name class_name_sym = Symbol(SymbolType.DataSymbol, class_name_ptr, f'{vmt.class_name}Name') bv.define_user_symbol(class_name_sym) return True
def _add_vmt_methods(bv: BinaryView, vmt: DelphiVMT, out_struct: types.Structure) -> bool: offset_ptr_size = vmt.offset_ptr_size if not vmt.seek_to_vmt_offset(vmt.vmt_offsets.cVmtParent + offset_ptr_size): return False for _ in range(len(vmt.virtual_methods)): value = vmt.read_ptr() if value == 0: continue if value not in vmt.virtual_methods: prev_offset = vmt.br_offset - offset_ptr_size raise RuntimeError( f'Invalid method address detected at 0x{prev_offset:08x} ({vmt.class_name})') # Create function if not exists if bv.get_function_at(value) is None: bv.create_user_function(value) function = bv.get_function_at(value) # Set method name if not already set function_name = function.name method_name = vmt.virtual_methods[value] if function_name.startswith('sub_'): bv.define_user_symbol(Symbol( SymbolType.FunctionSymbol, value, method_name )) # Add field to structure field_type = Type.pointer( bv.arch, Type.function( function.return_type, [(Type.void() if x.type is None else x.type) for x in function.parameter_vars], function.calling_convention ) ) field_name = method_name.split('.')[-1] out_struct.append(field_type, field_name) return True
def _add_vmt_fields(bv: BinaryView, vmt: DelphiVMT, out_struct: types.Structure) -> bool: offset_ptr_size = vmt.offset_ptr_size field_types = VMTFieldTypes(bv.arch) vmt_offsets = vmt.vmt_offsets offsets = vmt_offsets.__dict__.items() offset_map = {y:x for x, y in offsets} for offset in range(vmt_offsets.cVmtSelfPtr, vmt_offsets.cVmtParent+1, offset_ptr_size): if offset == vmt_offsets.cVmtClassName: if not BNHelpers.__create_class_name_type(bv, vmt, out_struct): return False continue name = offset_map[offset] field_type = getattr(field_types, name) out_struct.append(field_type, name) return True
def type_info_ty(kind=None): type_info_struct = Structure() type_info_struct.append(void_p_ty, 'vtable') type_info_struct.append(char_p_ty, 'name') if kind == 'si_class': type_info_struct.append(base_type_info_ptr_ty, 'base_type') return Type.structure_type(type_info_struct)
def vtable_ty(vfunc_count): try: vtable_struct = StructureBuilder.create() except NameError: vtable_struct = Structure() vtable_struct.append(signed_int_ty, 'top_offset') vtable_struct.append(base_type_info_ptr_ty, 'typeinfo') vtable_struct.append(Type.array(void_p_ty, vfunc_count), 'functions') return Type.structure_type(vtable_struct)
def type_info_ty(kind=None): try: type_info_struct = StructureBuilder.create() except NameError: type_info_struct = Structure() type_info_struct.append(void_p_ty, 'vtable') type_info_struct.append(char_p_ty, 'name') if kind == 'si_class': type_info_struct.append(base_type_info_ptr_ty, 'base_type') return Type.structure_type(type_info_struct)
def vtable_ty(vfunc_count): vtable_struct = Structure() vtable_struct.append(signed_int_ty, 'top_offset') vtable_struct.append(base_type_info_ptr_ty, 'typeinfo') vtable_struct.append(Type.array(void_p_ty, vfunc_count), 'functions') return Type.structure_type(vtable_struct)