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 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 _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 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 _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 load_svd(bv, svd_file=None): if not svd_file: svd_file = get_open_filename_input("SVD File") if isinstance(svd_file, str): svd_file = bytes(svd_file, encoding="utf-8") if not os.access(svd_file, os.R_OK): log_error(f"SVD Browser: Unable to open {svd_file}") return log_info(f"SVD Loader: Loading {svd_file}") device = parse(svd_file) peripherals = device['peripherals'].values() base_peripherals = [p for p in peripherals if 'derives' not in p] derived_peripherals = [p for p in peripherals if 'derives' in p] def register_peripheral(p, struct_type): bv.add_user_section(p['name'], p['base'], p['size'], SectionSemantics.ReadWriteDataSectionSemantics) bv.add_user_segment( p['base'], p['size'], 0, 0, SegmentFlag.SegmentContainsData | SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable) bv.define_data_var(p['base'], struct_type) bv.define_user_symbol( Symbol(SymbolType.ImportedDataSymbol, p['base'], p['name'])) for p in base_peripherals: s = Structure() for r in p['registers'].values(): if r['size'] is None: s.insert(r['offset'], Type.int(4, False), r['name']) else: s.insert(r['offset'], Type.int(int(r['size'] / 8), False), r['name']) struct_type = Type.structure_type(s) bv.define_user_type(p['name'], struct_type) register_peripheral(p, struct_type) for p in derived_peripherals: struct_type = bv.get_type_by_name( device['peripherals'][p['derives']]['name']) register_peripheral(p, struct_type)
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)