def create_vtable(view, vtable_name, vtable_address, max_funcs = 64): pointer_t = BinjaStruct.Pointer(view) funcs = list() for i in range(max_funcs): func_pointer_address = vtable_address + (i * view.address_size) func_address, _ = pointer_t.read(view, func_pointer_address) if func_address is None: break if not view.is_offset_executable(func_address): break func = view.get_function_at(func_pointer_address) if func is None: if i and view.get_code_refs(func_pointer_address, view.address_size): break funcs.append(func_address) if funcs: view.define_user_symbol(Symbol(SymbolType.DataSymbol, vtable_address, vtable_name)) view.define_user_data_var(vtable_address, Type.array(Type.pointer(view.arch, Type.void(), const = True), len(funcs))) return funcs
def _define_strings_in_sections(sections, view): for section_name in sections: section = view.sections[section_name] for s in view.get_strings(section.start, len(section)): view.define_user_data_var(s.start, Type.array(Type.char(), s.length + 1))
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 _parse_structure(type_string: str, view: BinaryView) -> Type: type_name = ''.join( takewhile(lambda i: i != '=', type_string) ) type_string = type_string[len(type_name)+1:] fields = [] while type_string: if type_string[0] == '{': field_type, type_string = _parse_structure(type_string[1:], view) fields.append(field_type) elif type_string[0] == '}': type_string = type_string[1:] break elif type_string[0] == '[': array_size = ''.join(takewhile(str.isdigit, type_string[1:])) array_type = ''.join( takewhile(lambda i: i != ']', type_string[1:]) ) type_string = type_string[len(array_size)+len(array_type)+2:] fields.append( Type.array(_lookup_type(array_type, view), int(array_size)) ) elif type_string[0] == ']': type_string = type_string[1:] continue elif _lookup_type(type_string[0], view): fields.append(_lookup_type(type_string[0], view)) type_string = type_string[1:] else: log_debug(f"Not sure what is going on with this type: {type_string!r}") raise NotImplementedError(f"{type_string!r}") parsed_struct = Structure() for field in fields: parsed_struct.append(field) log_debug(f"Created {type_name}={parsed_struct}") view.define_user_type(type_name, Type.structure_type(parsed_struct)) return ( Type.named_type_from_type( type_name, view.types.get(type_name) ), type_string )
def define_cfstrings_plugin(view: BinaryView): log_debug("define_cfstrings_plugin") from_bytes = _get_from_bytes(view) cfstring_type = view.get_type_by_name('CFString') if cfstring_type is None: cfstring_type = view.platform.parse_types_from_source( _cfstring_definition).types['CFString'] view.define_user_type('CFString', cfstring_type) wchar_type = view.platform.parse_types_from_source( _wchar_definition).types['wchar'] cfstring = Type.named_type_from_type('CFString', cfstring_type) __cfstring = view.get_section_by_name('__cfstring') if __cfstring is None: return buffer = cfstring_type.structure['buffer'] length = cfstring_type.structure['length'] for addr in range(__cfstring.start, __cfstring.end, cfstring_type.width): view.define_user_data_var(addr, cfstring) for xref in view.get_data_refs(addr): view.define_user_data_var(xref, Type.pointer(view.arch, cfstring)) string_pointer = from_bytes( view.read(addr + buffer.offset, buffer.type.width)) string_length = from_bytes( view.read(addr + length.offset, length.type.width), ) + 1 string_section = view.get_sections_at(string_pointer) if not string_section: return if string_section[0].name == '__ustring': char_type = wchar_type else: char_type = Type.char() view.define_user_data_var(string_pointer, Type.array(char_type, string_length))
def _define_selectors(view: BinaryView): __objc_selrefs = view.sections.get('__objc_selrefs') if __objc_selrefs is None: raise KeyError('This binary has no __objc_selrefs section') SEL = view.get_type_by_name('SEL') if SEL is None: raise TypeError('The SEL type is not defined!') for addr in range(__objc_selrefs.start, __objc_selrefs.end, SEL.width): view.define_user_data_var(addr, SEL) selector = int.from_bytes(view.read(addr, SEL.width), "little") if selector != 0: name = view.get_ascii_string_at(selector, 3) if name is not None: view.define_user_data_var( name.start, Type.array(Type.char(), name.length + 1))