예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
	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')
예제 #4
0
    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)
예제 #5
0
    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
예제 #6
0
 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))
예제 #9
0
    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(