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 update_memory_view(self): if self.adapter == None: raise Exception('missing adapter') if self.memory_view == None: raise Exception('missing memory_view') for symbol in self.old_symbols: # Symbols are immutable so just destroy the old one self.memory_view.undefine_auto_symbol(symbol) for dv in self.old_dvs: self.memory_view.undefine_data_var(dv) self.old_symbols = [] self.old_dvs = set() new_dvs = set() for (reg, addr) in self.registers: bits = self.registers.bits(reg) symbol_name = '$' + reg self.memory_view.define_auto_symbol( Symbol(SymbolType.ExternalSymbol, addr, symbol_name, namespace=symbol_name)) self.old_symbols.append( self.memory_view.get_symbol_by_raw_name(symbol_name, namespace=symbol_name)) self.memory_view.define_data_var(addr, Type.int(bits // 8, sign=False)) self.old_dvs.add(addr) # Special struct for stack frame if self.remote_arch.name == 'x86_64': width = self.registers['rbp'] - self.registers[ 'rsp'] + self.remote_arch.address_size if width > 0: if width > 0x1000: width = 0x1000 struct = Structure() struct.type = StructureType.StructStructureType struct.width = width for i in range(0, width, self.remote_arch.address_size): var_name = "var_{:x}".format(width - i) struct.insert(i, Type.pointer(self.remote_arch, Type.void()), var_name) self.memory_view.define_data_var(self.registers['rsp'], Type.structure_type(struct)) self.memory_view.define_auto_symbol( Symbol(SymbolType.ExternalSymbol, self.registers['rsp'], "$stack_frame", raw_name="$stack_frame")) self.old_symbols.append( self.memory_view.get_symbol_by_raw_name("$stack_frame")) self.old_dvs.add(self.registers['rsp']) else: pass
def update_memory_view(self): if self.adapter == None: raise Exception('missing adapter') if self.memory_view == None: raise Exception('missing memory_view') addr_regs = {} reg_addrs = {} for reg in self.adapter.reg_list(): addr = self.adapter.reg_read(reg) reg_symbol_name = '$' + reg if addr not in addr_regs.keys(): addr_regs[addr] = [reg_symbol_name] else: addr_regs[addr].append(reg_symbol_name) reg_addrs[reg] = addr for symbol in self.old_symbols: # Symbols are immutable so just destroy the old one self.memory_view.undefine_auto_symbol(symbol) for dv in self.old_dvs: self.memory_view.undefine_data_var(dv) self.old_symbols = [] self.old_dvs = set() new_dvs = set() for (reg, addr) in reg_addrs.items(): symbol_name = '$' + reg self.memory_view.define_auto_symbol(Symbol(SymbolType.ExternalSymbol, addr, symbol_name, namespace=symbol_name)) self.old_symbols.append(self.memory_view.get_symbol_by_raw_name(symbol_name, namespace=symbol_name)) new_dvs.add(addr) for new_dv in new_dvs: self.memory_view.define_data_var(new_dv, Type.int(8)) self.old_dvs.add(new_dv) # Special struct for stack frame if self.bv.arch.name == 'x86_64': width = reg_addrs['rbp'] - reg_addrs['rsp'] + self.bv.arch.address_size if width > 0: if width > 0x1000: width = 0x1000 struct = Structure() struct.type = StructureType.StructStructureType struct.width = width for i in range(0, width, self.bv.arch.address_size): var_name = "var_{:x}".format(width - i) struct.insert(i, Type.pointer(self.bv.arch, Type.void()), var_name) self.memory_view.define_data_var(reg_addrs['rsp'], Type.structure_type(struct)) self.memory_view.define_auto_symbol(Symbol(SymbolType.ExternalSymbol, reg_addrs['rsp'], "$stack_frame", raw_name="$stack_frame")) self.old_symbols.append(self.memory_view.get_symbol_by_raw_name("$stack_frame")) self.old_dvs.add(reg_addrs['rsp']) else: raise NotImplementedError('only x86_64 so far')
def from_address(cls, address: int, class_name: str, view: BinaryView): if address == 0: return None from_bytes = get_from_bytes(view) ivar_t_type = view.types['ivar_t'] ivar_t = Type.named_type_from_type( 'ivar_t', ivar_t_type ) members = get_structure_members(address, ivar_t_type, view) member_dict = {m.name: m for m in ivar_t_type.structure.members} # x64 uses uint64_t for offset, but everything else # uses uint32_t ivar_offset_type = ( member_dict['offset'].type.target if view.arch != Architecture['x86_64'] else Type.int(8, False) ) ivar_offset_type.const = True if view.get_data_var_at(address) is None: view.define_user_data_var(address, ivar_t) if members['name'] != 0: name_string = view.get_ascii_string_at(members['name'], 1) if name_string is not None: members['name'] = name_string.value else: members['name'] = '' if members['type']: type_string = view.get_ascii_string_at(members['type'], 1).value members['type'] = _lookup_type(type_string, view) if not members['type']: members['type'] = Type.pointer(view.arch, Type.void()) if members['offset']: view.define_user_data_var(members['offset'], ivar_offset_type) view.define_user_symbol( Symbol( SymbolType.DataSymbol, members['offset'], f'{members["name"]}_offset', namespace=class_name ) ) members['offset'] = from_bytes( view.read(members['offset'], member_dict['offset'].type.target.width) ) else: members['offset'] = None return cls(address, **members)
def init(self): try: hdr = self.parent_view.read(self.HDR_OFFSET, self.HDR_SIZE) self.rom_title = hdr[0:15] self.color = hdr[15] self.licensee_code = struct.unpack("H", hdr[16:18])[0] self.gb_type = hdr[18] self.cart_type = hdr[19] self.rom_banks = hdr[20] self.ram_banks = hdr[21] self.destination_code = hdr[22] self.old_licensee_code = hdr[23] self.mask_rom_version = hdr[24] self.complement_check = hdr[25] self.checksum = struct.unpack("H", hdr[26:])[0] except: log_error(traceback.format_exc()) return False # Add ROM mappings # ROM0 self.add_auto_segment( self.ROM0_OFFSET, self.ROM0_SIZE, self.ROM0_OFFSET, self.ROM0_SIZE, SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable) self.add_auto_section("ROM0", self.ROM0_OFFSET, self.ROM0_SIZE, SectionSemantics.ReadOnlyCodeSectionSemantics) # ROM1 self.add_auto_segment( self.ROM1_OFFSET, self.ROM1_SIZE, self.ROM1_OFFSET, self.ROM1_SIZE, SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable) self.add_auto_section("ROM1", self.ROM1_OFFSET, self.ROM1_SIZE, SectionSemantics.ReadWriteDataSectionSemantics) # Add RAM mappings for _, address, length in self.RAM_SEGMENTS: self.add_auto_segment( address, length, 0, 0, SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable) # Add IO registers for address, name in LR35902.IO_REGISTERS.items(): self.define_auto_symbol_and_var_or_function( Symbol(SymbolType.DataSymbol, address, name), Type.int(1)) # Define entrypoint self.define_auto_symbol( Symbol(SymbolType.FunctionSymbol, self.START_ADDR, "_start")) self.add_entry_point(self.START_ADDR) # Define interrupts for name, address in self.INTERRUPT_HANDLERS: self.define_auto_symbol( Symbol(SymbolType.FunctionSymbol, address, name)) #self.define_auto_symbol_and_var_or_function(Symbol(SymbolType.FunctionSymbol, address, name), Type.function(Type.void(), [])) return True
def __init__(self, arch: Architecture): self.cVmtSelfPtr = Type.pointer(arch, Type.void()) self.cVmtIntfTable = Type.pointer(arch, Type.void()) self.cVmtAutoTable = Type.pointer(arch, Type.void()) self.cVmtInitTable = Type.pointer(arch, Type.void()) self.cVmtTypeInfo = Type.pointer(arch, Type.void()) self.cVmtFieldTable = Type.pointer(arch, Type.void()) self.cVmtMethodTable = Type.pointer(arch, Type.void()) self.cVmtDynamicTable = Type.pointer(arch, Type.void()) self.cVmtClassName = Type.pointer(arch, Type.void()) self.cVmtInstanceSize = Type.int(arch.address_size) self.cVmtParent = Type.pointer(arch, Type.void())
def analyze_indirect_jump(self, expr: MediumLevelILInstruction): log_debug("analyze_indirect_jump") jump_value = JumpVisitor().visit(expr) if jump_value is None: log_debug("Jump target not constant") return False indirect_type = Type.int(self.view.arch.address_size, False) indirect_type.const = True if not self.view.is_offset_readable(jump_value): log_debug("Jump target is not readable") return False self.view.define_user_data_var(jump_value, indirect_type) self.target_queue.put(expr.address) return False
def fix_printfs(view: BinaryView): printf = view.get_symbols_by_name('_printf') if not printf: printf = view.get_symbols_by_name('printf') if not printf: return for sym in printf: function = view.get_function_at(sym.address) if not function: continue xrefs = view.get_code_refs(function.start) for xref in xrefs: caller: Function = xref.function call_mlil = caller.get_low_level_il_at(xref.address).mlil print(call_mlil) if call_mlil is None: continue fmt_operand = call_mlil.params[0] if fmt_operand.operation == MediumLevelILOperation.MLIL_VAR: log.log_warn( f"Potential format string bug: {fmt_operand.address:x}") continue elif fmt_operand.operation in ( MediumLevelILOperation.MLIL_CONST_PTR, MediumLevelILOperation.MLIL_CONST): fmt_address = fmt_operand.constant fmt = view.get_ascii_string_at(fmt_address, 2) if fmt is None: continue fmt_value = fmt.value else: continue specifiers = fmt_value.split('%') param_types = [] for specifier in specifiers[1:]: if not specifier: continue if specifier.startswith('d'): param_types.append(Type.int(4, sign=True)) elif specifier.startswith('s'): param_types.append(Type.pointer(view.arch, Type.char())) elif specifier.startswith('p'): param_types.append(Type.pointer(view.arch, Type.void())) else: log.log_warn( f'Unknown format specifier: {specifier}; skipping') param_types.append(Type.pointer(view.arch, Type.void())) param_idx = 1 params = [ FunctionParameter(Type.pointer(view.arch, Type.char()), 'fmt') ] for param in param_types: params.append(FunctionParameter(param, f'arg{param_idx}')) param_idx += 1 caller.set_call_type_adjustment(xref.address, Type.function(Type.int(4), params))
struct class_ro_t* vtable; }; struct category_t { const char *name; class_t *cls; struct method_list_t *instanceMethods; struct method_list_t *classMethods; struct protocol_list_t *protocols; struct property_list_t *instanceProperties; }; ''' basic_types = { 'c': Type.char(), 'i': Type.int(4, True), 's': Type.int(2, True), 'l': Type.int(4, True), 'q': Type.int(8, True), 'C': Type.int(1, False), 'I': Type.int(4, False), 'S': Type.int(2, False), 'L': Type.int(4, False), 'Q': Type.int(8, False), 'f': Type.float(4), 'd': Type.float(8), 'B': Type.bool(), 'v': Type.void() } def define_types_plugin(view):
from binaryninja import ( Architecture, FunctionParameter, Platform, QualifiedName, Type, TypeLibrary, Structure ) advapi32_x86 = TypeLibrary.new(Architecture["x86"], "advapi32.dll") advapi32_x86.add_platform(Platform["windows-x86"]) BOOL = Type.int(4, altname="BOOL") HCRYPTPROV_type = Type.structure_type(Structure()) HCRYPTPROV = Type.named_type_from_type( "HCRYPTPROV", HCRYPTPROV_type ) LPCSTR_type = Type.pointer(Architecture["x86"], Type.char()) LPCSTR = Type.named_type_from_type('LPCSTR', LPCSTR_type) DWORD = Type.int(4, sign=False, altname="DWORD") advapi32_x86.add_named_type("HCRYPTPROV", HCRYPTPROV_type) CryptAcquireContextA = Type.function( BOOL, [ FunctionParameter(