コード例 #1
0
def importldsymbols(bv,filename):
    """Janky parser to import a GNU LD symbols file to Binary Ninja."""
    f=open(filename,"r");
    for l in f:
        words=l.strip().split();

        try:
            name=words[0];
            adrstr=words[2];
            adr=int(adrstr.strip(";"),16);

            #Function symbols are odd address in Flash.
            if adr&0xF8000001==0x08000001:
                bv.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, adr&~1, name));
                bv.add_function(adr&~1);
                print("Imported function symbol %s at 0x%x"%(name,adr));

            #Data symbols are in SRAM or TCRAM with unpredictable alignment.
            elif adr&0xC0000000==0:
                bv.define_auto_symbol(Symbol(SymbolType.DataSymbol, adr, name));
                print("Imported data symbol %s at 0x%x"%(name,adr));
            else:
                print "Uncategorized adr=0x%08x."%adr;
        except:
            # Print warnings when our janky parser goes awry.
            if len(words)>0 and words[0]!="/*" and words[0]!="*/":
                print("#Warning in: %s\n"%words);
                log_error(traceback.format_exc())
コード例 #2
0
    def init(self):

        user_choice = get_choice_input("Select MCU family", "MCU selection",
                                       self.MCUS)
        if user_choice is not None:
            chosen_mcu = self.MCUS[user_choice]
            mcu_lib = importlib.import_module("binaryninja_cortex.platforms." +
                                              chosen_mcu)
            mcu = mcu_lib.Chip
        else:
            mcu_lib = importlib.import_module("binaryninja_cortex.platforms")
            mcu = mcu_lib.MCU

        #Add RAM segment
        self.add_auto_segment(
            mcu.RAM_OFF, 0xffff, 0, 0, SegmentFlag.SegmentReadable
            | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)

        # Add peripherals segment
        self.add_auto_segment(
            mcu.PERIPH_OFF, 0x10000000, 0, 0,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable)

        #Add flash segment, assume flash < 2MB
        self.add_auto_segment(
            mcu.ROM_OFF, 0x200000, 0, 0x200000,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)

        #Add IVT symbols

        #SP_VALUE is a data pointer
        self.define_auto_symbol_and_var_or_function(
            Symbol(SymbolType.DataSymbol, mcu.ROM_OFF, mcu.IRQ[0]),
            Type.pointer(self.arch, Type.void(), const=True), self.platform)
        addr = struct.unpack("<I", self.parent_view.read(0, 4))[0]
        self.define_auto_symbol(
            Symbol(SymbolType.DataSymbol, addr, "p_{}".format(mcu.IRQ[0])))

        #All other vectory are function pointers
        for i in range(1, len(mcu.IRQ)):
            self.define_auto_symbol_and_var_or_function(
                Symbol(SymbolType.DataSymbol, mcu.ROM_OFF + (4 * i),
                       mcu.IRQ[i]),
                Type.pointer(self.arch, Type.void(), const=True),
                self.platform)
            addr = struct.unpack("<I", self.parent_view.read(4 * i, 4))[0] & ~1
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, addr,
                       "f_{}".format(mcu.IRQ[i])))
            self.add_function(addr, self.platform)

        #Add entry point to RESET_IRQ
        self.add_entry_point(self.symbols['f_RESET_IRQ'].address,
                             self.platform)

        return True
コード例 #3
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
コード例 #4
0
    def init(self):
        max_instructions = 0
        for basic_block in self.vtil.explored_blocks.basic_blocks:
            max_instructions += len(basic_block.instructions)

        # Fill the cache
        for i in range(0, max_instructions):
            find_instruction(i, self.vtil)

        self.add_auto_segment(
            0, max_instructions, 0, max_instructions,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable
        )
        self.add_auto_section(
            ".text", 0, max_instructions,
            SectionSemantics.ReadOnlyCodeSectionSemantics
        )

        entry_vip = self.vtil.entrypoint.entry_vip
        entry_addr = find_block_address(entry_vip, self.vtil)
        symbol = Symbol(SymbolType.FunctionSymbol, entry_addr, f"_vip_{hex(entry_vip)[2:]}")
        self.define_auto_symbol(symbol)

        for basic_block in self.vtil.explored_blocks.basic_blocks:
            vip = basic_block.entry_vip
            addr = find_block_address(vip, self.vtil)

            # Append a comment to help with indirect jumps:
            comment = ""
            branch_ins = basic_block.instructions[-1]
            if branch_ins.name == "jmp":
                if isinstance(branch_ins.operands[0].operand, VTILParser.RegisterDesc):
                    comment += "Indirect => { " + ', '.join('vip_{:x}'.format(trgt) for trgt in basic_block.next_vip) + " }"

            if basic_block.sp_offset != branch_ins.sp_offset:
                if comment != "": comment += " | "
                comment += f"SP Delta: {hex(basic_block.sp_offset)}"

            if comment != "":
                self.set_comment_at(addr + len(basic_block.instructions) - 1, comment)

            if entry_vip == vip: continue

            symbol = Symbol(SymbolType.FunctionSymbol, addr, f"vip_{hex(vip)[2:]}")
            self.define_auto_symbol(symbol)
            self.set_comment_at(addr, f"vip_{hex(vip)[2:]}:")


        self.add_entry_point(entry_addr)

        return True
コード例 #5
0
ファイル: md380.py プロジェクト: zarya/md380tools
def importr2symbols(bv, filename):
    """Janky shotgun parser to import Radare2 symbols file to Binary Ninja."""
    f = open(filename, "r")
    for l in f:
        words = l.strip().split()

        try:
            if words[0][0] == "#":
                pass
            elif words[0] == "f" and words[2] == "@":
                #f name @ 0xDEADBEEF
                name = words[1]
                adrstr = words[3]
                adr = int(adrstr.strip(";"), 16)

                #Functions are in Flash
                if adr & 0xF8000000 == 0x08000000:
                    bv.define_auto_symbol(
                        Symbol(SymbolType.FunctionSymbol, adr & ~1, name))
                    bv.add_function(adr & ~1)
                    print("Imported function symbol %s at 0x%x" % (name, adr))
                #Data in SRAM or DRAM
                elif adr & 0xFE000000 == 0x02000000:
                    bv.define_auto_symbol(
                        Symbol(SymbolType.DataSymbol, adr & ~1, name))
                    print("Imported data symbol %s at 0x%x" % (name, adr))

            elif (words[0] == "af+"
                  or words[0] == "f") and int(words[2], 16) > 0:
                name = words[3]
                adrstr = words[1]
                adr = int(adrstr.strip(";"), 16)

                #Functions are in Flash
                if adr & 0xF8000000 == 0x08000000:
                    bv.define_auto_symbol(
                        Symbol(SymbolType.FunctionSymbol, adr & ~1, name))
                    bv.add_function(adr & ~1)
                    print("Imported function symbol %s at 0x%x" % (name, adr))
                #Data in SRAM or DRAM
                elif adr & 0xFE000000 == 0x02000000:
                    bv.define_auto_symbol(
                        Symbol(SymbolType.DataSymbol, adr & ~1, name))
                    print("Imported data symbol %s at 0x%x" % (name, adr))

            else:
                print("Ignoring: %s" % words)
        except:
            if len(words) > 3:
                print("Ignoring: %s\n" % words)
コード例 #6
0
    def get_exports(self):
        symbols = []

        for (name, args, entries) in self.sections:
            if name != 'EXPORTS':
                continue
            for (name, args) in entries.items():
                # Format: NAME=INTERNAL_NAME @ordinal [KEYWORDS...]
                name = quoted_split(name, '=')[0]
                if not args[0].startswith('@'):
                    continue

                if args[0][1:]:
                    o = args[0][1:]
                    tag_idx = 1
                elif len(args) > 1:
                    o = args[1]
                    tag_idx = 2
                else:
                    continue

                if not o.isdigit():
                    continue
                if 'DATA' in args[tag_idx:]:
                    symtype = SymbolType.DataSymbol
                else:
                    symtype = SymbolType.FunctionSymbol
                symbols.append(Symbol(symtype, 0, name, ordinal=int(o)))

        return symbols
コード例 #7
0
    def load_symbols(self):
        super(SurfaceECView, self).load_symbols()
        # There's six sequential jump tables, used by functions that call
        # jump_R1:2.
        base = 0x45eb  # TODO pull from functions using them?
        for i in range(6):
            self.define_auto_symbol(
                Symbol(SymbolType.DataSymbol, mem.CODE + base,
                       'jump_table_' + str(i)))
            self.define_user_data_var(mem.CODE + base,
                                      self.parse_type_string('void*[16]')[0])
            for ea in range(base, base + 16 * 2, 2):
                fp = struct.unpack('>H', self.read(ea, 2))[0]
                fp += mem.CODE
                self.add_function(fp)
            base += 16 * 2

        # Flash bank swapping trampolines at 0x3500, refs to them between
        # 0x3548 first one
        # 0x3ff8 last one
        # TODO: autodiscover this region with an instruction regex?
        for ea in range(0x3548, 0x3ff8 + 6, 6):
            if (self.read(ea, 1) != '\x90' or self.read(ea + 3, 1) != '\x02'):
                msg = 'Bad instruction in trampoline jump at ' + hex(ea)
                raise RuntimeError(msg)
            self.add_function(ea)
コード例 #8
0
    def load_memory(self):
        super(SurfaceECView, self).load_memory()

        seg_f = SegmentFlag
        rw_ = seg_f.SegmentReadable | seg_f.SegmentWritable
        r_xc = (seg_f.SegmentReadable | seg_f.SegmentExecutable
                | seg_f.SegmentContainsCode)
        r__d = seg_f.SegmentReadable | seg_f.SegmentContainsData

        image_base = 0x0182b  # probably signature before
        # bootloader @ first 0x2000, then this stub
        self.add_auto_segment(mem.CODE + 0x2000, 0x6000, image_base, 0x6000,
                              r_xc)
        self.add_auto_section('.code', mem.CODE + 0x2000, 0x6000,
                              SectionSemantics.ReadOnlyCodeSectionSemantics)
        for page in range(4):  # then 4 pages for high half of code
            self.add_auto_segment(mem.CODE + 0x8000 + 0x8000 * page, 0x8000,
                                  image_base + 0x6000 + 0x8000 * page, 0x8000,
                                  r_xc)
            self.add_auto_section(
                '.page%d' % page, mem.CODE + 0x8000 + 0x8000 * page, 0x8000,
                SectionSemantics.ReadOnlyCodeSectionSemantics)
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol,
                       mem.CODE + 0x8000 + 0x8000 * page, 'page_%d' % page))
            self.add_function(mem.CODE + 0x8000 * (page + 1))
コード例 #9
0
ファイル: __init__.py プロジェクト: 404d/autoutils
def do_discover_caller_names(bv, func):
    param_name = interaction.get_text_line_input(
        "Please enter the name of the parameter that contains the method name",
        "Parameter name")
    # Docs says the above function returns a string with a link to the Python 3
    # docs (e.g. a Py3 str), but it actually returns a bytes-object under Py3
    param_name = param_name.decode("utf-8")
    func_params = [
        param for param in func.parameter_vars if param.name == param_name
    ]
    force = False

    if len(func_params) != 1:
        log_error("Unable to determine method name argument")
        return

    for name, func in discover_names(func, func_params).items():
        # Skip if named correctly
        if func.symbol.name == name:
            continue

        # Skip if we're not forcing and the user has named this already
        if not func.symbol.auto and not force:
            log_debug("Skipped %r due to no auto symbol" % name)
            continue

        log_info("Renaming %r to %r" % (func, name))
        func.view.define_auto_symbol(
            Symbol(func.symbol.type, func.symbol.address, short_name=name))
コード例 #10
0
    def process_symtable(self, table):
        pos = 0
        while pos + 6 < len(table):
            name = ""
            (value, type) = struct.unpack(">Lc", table[pos:pos + 5])
            type = chr(type[0] ^ 0x80)
            pos += 4
            if type == 'z':
                #n = 0                                                          # NOT USED: size of name to malloc()
                pos += 2  # advance to beginning of hist
                while table[pos:pos + 2] != b'\x00\x00':
                    #n += 2
                    pos += 2  # next 2-bytes block
                pos += 2  # skip double nil
            else:
                while pos < len(table):
                    pos += 1
                    if chr(table[pos]) == "\x00":
                        pos += 1
                        break
                    name += chr(table[pos])

            #log_info('%08x\t%c\t%s' % (value,type,name))
            if type == 'T' or type == 't' or type == 'L' or type == 'l':
                self.define_auto_symbol(
                    Symbol(SymbolType.FunctionSymbol, value, name))
コード例 #11
0
def decrypt_strings(bv):
    data_section = bv.get_section_by_name(".data")
    data = bv.read(data_section.start, data_section.end - data_section.start)

    printables = [ord(c) for c in string.printable]

    for i in range(0, len(data) - 4, 4):
        key, size = struct.unpack("<2I", data[i:i+8])
        size ^= key
        if size > 0 and size < 400 and i + size < len(data):
            byte_key = data[i:i+4]
            decrypted = bytearray()
            valid = True
            for j in range(size):
                char = data[i+8+j] ^ byte_key[j % 4]
                if char not in printables:
                    valid = False
                    break
                decrypted.append(char)
            if valid:
                sym_addr = data_section.start + i
                s = bytes(decrypted).decode()
                sym_name = s[:20].strip()
                for c in " \t\r\n":
                    sym_name = sym_name.replace(c, "_")
                sym_name = "str_" + sym_name
                symbol = Symbol(SymbolType.DataSymbol, sym_addr, sym_name)
                bv.define_user_symbol(symbol)
                bv.write(sym_addr, s + "\x00")
コード例 #12
0
    def init(self):
        self.raw = self.data
        self.binary = self.raw.read(0, len(self.raw))

        self.add_analysis_completion_event(self.on_complete)

        # set base address
        if self.IS_64:
            self.load_address = 0x240000000
            self.arch = Architecture['aarch64']
            self.platform = self.arch.standalone_platform
        else:
            self.load_address = 0x10000000
            self.arch = Architecture['thumb2']
            self.platform = self.arch.standalone_platform

            print("Base address : " + hex(self.load_address))


        self.add_auto_segment(self.load_address, len(self.parent_view), 0, len(self.parent_view), SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
        self.add_user_section(self.name, self.load_address, len(self.raw), SectionSemantics.ReadOnlyCodeSectionSemantics)
        self.add_entry_point(self.load_address)
        self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, self.load_address, '_start'))
        self.update_analysis()

        return True
コード例 #13
0
ファイル: view.py プロジェクト: hgarrereyn/bn-pokemon-mini
    def init(self):
        # RAM
        self.add_auto_segment(
            0x1000, 0x1000, 0, 0x1000,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable)
        # Hardware IO Registers
        self.add_auto_segment(
            0x2000, 0x100, 0, 0x100,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable)

        # Cartridge memory
        self.add_auto_segment(
            0x2100, 0x1fdeff, 0x2100, 0x1fdeff,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)

        # Cartridge memory mirrors
        self.add_auto_segment(
            0x200000, 0x1fffff, 0x2100, 0x1fdeff,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
        self.add_auto_segment(
            0x400000, 0x1fffff, 0x2100, 0x1fdeff,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
        self.add_auto_segment(
            0x600000, 0x1fffff, 0x2100, 0x1fdeff,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
        self.add_auto_segment(
            0x800000, 0x1fffff, 0x2100, 0x1fdeff,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
        self.add_auto_segment(
            0xA00000, 0x1fffff, 0x2100, 0x1fdeff,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
        self.add_auto_segment(
            0xC00000, 0x1fffff, 0x2100, 0x1fdeff,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
        self.add_auto_segment(
            0xE00000, 0x1fffff, 0x2100, 0x1fdeff,
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)

        for addr, name in default_symbols.items():
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, addr, name))

        for addr, name in mmio_regs.items():
            self.define_auto_symbol(Symbol(SymbolType.DataSymbol, addr, name))

        self.add_entry_point(0x2102)
        return True
コード例 #14
0
ファイル: sync.py プロジェクト: jeffli678/peutils
def resolve_imports_for_library(bv, lib):
    source_bv = peutils.files[lib.name.lower()]
    exports = pe_parsing.get_exports(source_bv)

    for import_ in lib.imports:
        # Find the name
        name = None
        for export in exports:
            if export.ord == import_.ordinal:
                print(export)
                name = export.name
                export_symbol = export.symbol

        if not name:
            log_warn("Unable to find name for %r" % import_)

        # Redefine the IAT thunk symbol
        original_symbol = bv.get_symbol_at(import_.datavar_addr)

        # Delete any existing auto symbols
        if original_symbol:
            log_info("Renaming %s to %s:%s" %
                     (original_symbol.name, lib.name, name))
            bv.undefine_auto_symbol(original_symbol)
        else:
            log_info("Creating IAT symbol %s:%s @ %08x" %
                     (lib.name.split(".")[0], name, import_.datavar_addr))

        # Create the new symbol
        bv.define_auto_symbol(
            Symbol(
                SymbolType.ImportAddressSymbol,
                import_.datavar_addr,
                name + "@IAT",
                namespace=lib.name.split(".")[0],
            ))

        # Transplant type info
        export_func = source_bv.get_function_at(export_symbol.address)
        type_tokens = [token.text for token in export_func.type_tokens]
        i = type_tokens.index(export_symbol.name)
        type_tokens[i] = "(*const func_name)"

        type_string = "".join(type_tokens)
        log_info("Setting type for %s to %r" % (name, type_string))

        try:
            (type_, name) = bv.parse_type_string(type_string)
        except:
            log_error("Invalid type, skipping")

        bv.define_data_var(import_.datavar_addr, type_)

        # FIXME: Apply params to ImportedFunctionSymbols -- check xref on
        # datavar and filter by associated symbols
        # This doesn't actually seem to help and apparently I didn't have to do
        # this before? Maybe I just didn't handle jump
        """
コード例 #15
0
def import_ida(json_file, bv, options):
    if json_file is None:
        return False, "No json file specified"

    imported = None

    try:
        f = open(json_file, "rb")
        imported = json.load(f)
    except Exception as e:
        return False, "Failed to parse json file {} {}".format(json_file, e)

    resolved_functions = imported["functions"]
    resolved_strings = imported["strings"]

    # TODO: import segments
    # TODO: Handle Conflicts

    if options.import_functions:
        log("Applying import data", options.verbose)
        for name, rec in resolved_functions.items():
            bv.add_function(rec["start"])
            func = bv.get_function_at(rec["start"])
            if name != ("sub_%x" % rec["start"]):
                func.name = name

            if options.import_comments:
                if "comment" in rec:
                    func.comment = rec["comment"]

                if "comments" in rec:
                    for comment, addr in rec["comments"].items():
                        func.set_comment_at(addr, comment)

            if "can_return" in rec:
                func.can_return = rec["can_return"]

        bv.update_analysis_and_wait()

    if options.import_strings:
        log("Importing string types", options.verbose)
        for addr, (name, length, t, data_refs) in resolved_strings.items():
            bv.define_user_data_var(int(addr), Type.array(Type.int(1, None, "char"), length))
            if options.import_strings_names:
                bv.define_user_symbol(Symbol(SymbolType.DataSymbol, int(addr), name))
            for ref in data_refs:  # references to this data
                for block in bv.get_basic_blocks_at(ref):  # find any references in code
                    for i in block.get_disassembly_text():  # go through all the instructions in the block
                        if i.address == ref:
                            for token in i.tokens:
                                if token.type == InstructionTextTokenType.PossibleAddressToken:
                                    print "setting token", i.address, token.value, token.operand, IntegerDisplayType.PointerDisplayType, block.arch
                                    block.function.set_int_display_type(i.address, token.value, token.operand, IntegerDisplayType.PointerDisplayType, block.arch)
                                    break

    log("Updating Analysis", options.verbose)
    bv.update_analysis_and_wait()
    return True, None
コード例 #16
0
def load_map_file(thread, view, filename):
    lines = open(filename, 'r').readlines()
    symbols = parse_map_file(lines)
    arch = view.arch

    for name, addr in symbols:
        if not view.is_valid_offset(addr):
            continue

        current_sym = view.get_symbol_at(addr)

        if current_sym is not None:
            if not current_sym.auto:
                continue

            if current_sym.type not in [
                    SymbolType.DataSymbol, SymbolType.FunctionSymbol
            ]:
                continue

            view.undefine_user_symbol(current_sym)

        sym_type, sym_parts = demangle_ms(arch, name)

        if sym_type is None:
            sym_type = Type.void()

        if isinstance(sym_parts, str):
            sym_parts = [sym_parts]

        sym_name = '::'.join(sym_parts)

        if view.is_offset_executable(addr):
            view.create_user_function(addr)
            view.define_user_symbol(
                Symbol(SymbolType.FunctionSymbol,
                       addr,
                       sym_name,
                       raw_name=name))
        else:
            view.define_data_var(addr, sym_type)
            view.define_user_symbol(
                Symbol(SymbolType.DataSymbol, addr, sym_name, raw_name=name))

    fix_mangled_symbols(thread, view)
コード例 #17
0
ファイル: __init__.py プロジェクト: psifertex/binaryninja-svd
 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']))
コード例 #18
0
ファイル: md380.py プロジェクト: zarya/md380tools
    def init_thumb2(self, adr=0x08000000):
        try:
            self.init_common()
            self.thumb2_offset = 0
            self.arm_entry_addr = struct.unpack("<L", self.hdr[0x4:0x8])[0]
            self.thumb2_load_addr = adr  #struct.unpack("<L", self.hdr[0x38:0x3C])[0]
            self.thumb2_size = len(self.hdr)

            # Add segment for SRAM, not backed by file contents
            self.add_auto_segment(
                0x20000000, 0x20000, 0, 0, SegmentFlag.SegmentReadable
                | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)
            # Add segment for TCRAM, not backed by file contents
            self.add_auto_segment(
                0x10000000, 0x10000, 0, 0,
                SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable)

            #Add a segment for this Flash application.
            self.add_auto_segment(
                self.thumb2_load_addr, self.thumb2_size, self.thumb2_offset,
                self.thumb2_size,
                SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)

            #Define the RESET vector entry point.
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, self.arm_entry_addr & ~1,
                       "RESET"))
            self.add_entry_point(self.arm_entry_addr & ~1)

            #Define other entries of the Interrupt Vector Table (IVT)
            for ivtindex in range(8, 0x184 + 4, 4):
                ivector = struct.unpack("<L",
                                        self.hdr[ivtindex:ivtindex + 4])[0]
                if ivector > 0:
                    #Create the symbol, then the entry point.
                    self.define_auto_symbol(
                        Symbol(SymbolType.FunctionSymbol, ivector & ~1,
                               "vec_%x" % ivector))
                    self.add_function(ivector & ~1)
            return True
        except:
            log_error(traceback.format_exc())
            return False
コード例 #19
0
ファイル: RelView.py プロジェクト: Vector35/Z80
    def init(self):
        self.arch = Architecture['Z80']
        self.platform = Architecture['Z80'].standalone_platform

        syms = []
        have_code = False

        for line in self.parent_view.read(0, len(self.parent_view)).split(b'\x0a'):
            line = line.decode('utf-8')

            # AREA line -> create a section
            match = re.match(r'A _CODE size (.*) flags (.*) addr (.*)', line)
            if match:
                (size, flags, addr) = (int(x, 16) for x in match.group(1, 2, 3))
                assert flags == 0
                assert addr == 0
                log_info('adding _CODE [%X, %X)' % (addr, addr+size))

                self.add_auto_segment(addr, size, 0, 0, SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)
                
                #self.add_user_section('_CODE', addr, size, SectionSemantics.ReadOnlyCodeSectionSemantics)
                have_code = True
                continue

            # WRITE line -> write bytes to section
            match = re.match(r'^T (.. ..) (.*)', line)
            if match:
                (addr, data) = match.group(1, 2)
                # eg: "04 00" -> 0x0004
                addr = int(addr[3:5] + addr[0:2], 16)
                # eg: "AA BB CC DD" -> b'\xAA\xBB\xCC\xDD'
                data = b''.join([pack('B', int(x, 16)) for x in data.split(' ')])
                log_info('writing to %X: %s' % (addr, match.group(2)))
                self.write(addr, data) 
                continue 

            # SYMBOL line -> store
            match = re.match(r'^S (.+) Def(.*)', line)
            if match:
                (name, addr) = match.group(1, 2)
                if not name in ['.__.ABS.', '.  .ABS']:
                    addr = int(addr, 16)
                    log_info('saving symbol %s @ %X' % (name, addr))
                    syms.append((name, addr))
                    continue
        
        assert have_code
        for (name, addr) in syms:
            log_info('applying symbol %s @ %X' % (name, addr))
            self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, addr, name))
            self.add_function(addr)

        return True
コード例 #20
0
    def _add_interrupt_symbols(self, data):
        reader = BinaryReader(data)

        # Skip stack pointer
        reader.seek(4)

        for interrupt in INTERRUPT_TABLE:
            address = reader.read32() & ~1

            if address != 0:
                symbol = Symbol(SymbolType.FunctionSymbol, address, interrupt)
                self.define_auto_symbol(symbol)
                self.add_function(address)
コード例 #21
0
ファイル: binja.py プロジェクト: Shizmob/binja-depanalyzer
 def get_exports(self):
     return [
         Symbol(s.type,
                s.address,
                s.short_name,
                full_name=get_symbol_name(self.bv, s),
                raw_name=s.raw_name,
                binding=s.binding,
                namespace=s.namespace,
                ordinal=s.ordinal) for s in self.bv.get_symbols()
         if s.type in EXPORTABLE_TYPES
         and s.binding == SymbolBinding.GlobalBinding
     ]
コード例 #22
0
def update_get_api_call(bv, xref):
    print("[*] Doing 0x{:x}".format(xref.address))
    hash_value = None
    cur_addr = xref.address - 1
    while hash_value is None:
        prev = None
        while not prev:
            cur_addr -= 1
            prev = xref.function.get_low_level_il_at(cur_addr)
        if prev.operation == LowLevelILOperation.LLIL_SET_REG and prev.operands[0].name == "edx":
            v = prev.operands[1].operands[0]
            if isinstance(v, int):
                hash_value = v
            else:
                break
        if prev.address == xref.function.start:
            break

    if hash_value is None:
        print("[-] Error: hash not found")
        return 1
    if hash_value not in func_dict:
        print("[-] Error: unknown hash")
        return 2

    api_name = func_dict[hash_value]
    var_key = (xref.function, api_name)
    if var_key not in var_name_counts:
        var_name_counts[var_key] = 1
        final_name = api_name
    else:
        final_name = "{:s}_{:d}".format(api_name, var_name_counts[var_key])
        var_name_counts[var_key] += 1
    bv.set_comment_at(xref.address, api_name)
    xref.function.create_user_address_tag(xref.address, bv.tag_types["Library"], api_name)
    for hl_bb in xref.function.hlil:
        for instr in hl_bb:
            if xref.address == instr.address:
                var = instr.operands[0]
                while isinstance(var, HighLevelILInstruction):
                    var = var.operands[0]
                if not isinstance(var, Variable):
                    continue
                xref.function.create_user_var(var, var.type, final_name)
                next_instr = xref.function.get_low_level_il_at(xref.address + 5)
                if next_instr.operation == LowLevelILOperation.LLIL_STORE and next_instr.operands[1].operands[0].name == "eax":
                    mem_addr = next_instr.operands[0].operands[0]
                    symbol = Symbol(SymbolType.DataSymbol, mem_addr, "_" + api_name)
                    bv.define_user_symbol(symbol)
                return 0
    return -1
コード例 #23
0
ファイル: util.py プロジェクト: Shizmob/binja-depanalyzer
def set_symbol_name(bv, sym, name):
	""" Rename symbol to given name """
	# If the symbol has an associated function, this is way quicker and also updates it.
	func = bv.get_function_at(sym.address)
	if func:
		func.name = name
	else:
		name = name.split('@', 1)[0]
		old_suffixes = sym.raw_name.split('@')[1:]
		if old_suffixes:
			name += '@' + '@'.join(old_suffixes)
		new_sym = Symbol(sym.type, sym.address, name, binding=sym.binding, namespace=sym.namespace, ordinal=sym.ordinal)
		bv.undefine_auto_symbol(sym)
		bv.define_user_symbol(new_sym)
コード例 #24
0
ファイル: binaryview.py プロジェクト: chenruibuaa/i8051
    def load_memory(self):
        """Creates basic IRAM/XRAM/SFR memory spaces required by the lifter.

        Extend with CODE loading for your particular image.

        XRAM is assumed to be the maximum possible size - override xram_size if
        you want more precision.
        """
        rw = (SegmentFlag.SegmentReadable | 
              SegmentFlag.SegmentWritable)

        # The indirect-access part of the IRAM (reachable via @R0, @R1,
        # push/pop, and DMA peripheral) is kept continuous with the
        # direct-access portion. SFRs are pushed off to a separate region 
        # given how special they are.
        # I think this will simplify the lift implementation compared to other
        # possible layouts.
        self.add_auto_segment(mem.IRAM, 0x100, 0, 0, rw)
        sem_rwd = SectionSemantics.ReadWriteDataSectionSemantics
        self.add_auto_section('.register_banks',        mem.IRAM + 0x00, 0x20, sem_rwd)
        self.add_auto_section('.data_bitwise_access',   mem.IRAM + 0x20, 0x10, sem_rwd)
        self.add_auto_section('.data',                  mem.IRAM + 0x30, 0x50, sem_rwd)
        self.add_auto_section('.data_indirect_only',    mem.IRAM + 0x80, 0x80, sem_rwd)

        # Provide nice markup for stuff like `pop 0h; pop 1h; pop 2h; pop 3h`
        # Sometimes, anyway. For some reason symbols aren't always created?
        bank_t = self.platform.parse_types_from_source('''
            struct register_bank __packed{uint8_t R[8];}; 
            /* register_bank bank[4]; */
        ''').types['register_bank']
        for index, ea in enumerate(range(mem.IRAM+0x00, mem.IRAM+0x20, 0x08)):
            name = 'RB%s' % (index,)
            self.define_auto_symbol(Symbol(SymbolType.DataSymbol, ea, name))
            self.define_user_data_var(ea, bank_t)


        # The SFR region is accessible directly within the address range
        # 0x80..0xff. The mem.SFRs offset is a type tag only; for example,
        # the accumulator is at address 0xe0, which is (mem.SFRs+0xe0) in the
        # flattened memory map. That's | what this addition is for. I think
        # that makes sense?            V
        self.add_auto_segment(mem.SFRs + 0x80, 0x80, 0, 0, rw)
        self.add_auto_section('.special_function_registers', 
                                mem.SFRs + 0x80, 0x80, sem_rwd)

        self.add_auto_segment(mem.XRAM, self.xram_size, 0, 0, rw)
        self.add_auto_section('.xram', mem.XRAM, self.xram_size, sem_rwd)
コード例 #25
0
    def init(self):
        self.platform = Platform['8049_rb0mb0']

        length = len(self.parent_view)

        try:
            # create the data memory segment and section
            self.add_auto_segment(
                0, 128, 0, 0, SegmentFlag.SegmentContainsData
                | SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable)
            self.add_auto_section(
                '.ram', 0, 128, SectionSemantics.ReadWriteDataSectionSemantics)

            # create the program memory segment, section and entry point
            self.add_auto_segment(
                self.CODE_OFFSET, length, 0, length,
                SegmentFlag.SegmentContainsCode
                | SegmentFlag.SegmentContainsData | SegmentFlag.SegmentReadable
                | SegmentFlag.SegmentExecutable)
            self.add_auto_section(
                '.rom', self.CODE_OFFSET, length,
                SectionSemantics.ReadOnlyCodeSectionSemantics)
            self.add_entry_point(self.CODE_OFFSET)

            self.define_auto_symbol_and_var_or_function(
                Symbol(SymbolType.FunctionSymbol, self.CODE_OFFSET | 0,
                       'reset'), None, self.platform)
            self.define_auto_symbol_and_var_or_function(
                Symbol(SymbolType.FunctionSymbol, self.CODE_OFFSET | 3,
                       'interrupt'), None, self.platform)
            self.define_auto_symbol_and_var_or_function(
                Symbol(SymbolType.FunctionSymbol, self.CODE_OFFSET | 7,
                       'timer'), None, self.platform)

            # working registers
            for n in range(8):
                self.define_auto_symbol_and_var_or_function(
                    Symbol(SymbolType.DataSymbol, n, 'R{}'.format(n)),
                    Type.int(1, False), self.platform)
                self.define_auto_symbol_and_var_or_function(
                    Symbol(SymbolType.DataSymbol, n + 24, 'R{}\''.format(n)),
                    Type.int(1, False), self.platform)

            # stack registers
            for n in range(8):
                self.define_auto_symbol_and_var_or_function(
                    Symbol(SymbolType.DataSymbol, n * 2 + 8, 'S{}'.format(n)),
                    Type.int(2, False), self.platform)

            return True

        except:
            log_error(traceback.format_exc())
            return False
コード例 #26
0
def fix_mangled_symbols(thread, view):
    for sym in view.symbols.values():
        if thread.cancelled:
            break
        if not isinstance(sym, Symbol):
            continue

        if sym.short_name.startswith('?') and not sym.raw_name.startswith('?'):
            demangled_type, demangled_name = demangle_ms(
                view.arch, sym.short_name)
            if demangled_type is not None:
                new_symbol = Symbol(
                    sym.type,
                    sym.address,
                    short_name=get_qualified_name(demangled_name),
                    full_name=get_qualified_name(demangled_name),
                    raw_name=sym.short_name,
                    binding=sym.binding,
                    namespace=sym.namespace,
                    ordinal=sym.ordinal)

                view.undefine_user_symbol(sym)
                view.define_user_symbol(new_symbol)
                view.define_user_data_var(new_symbol.address, demangled_type)

                sym = new_symbol

        # Create vtables
        if 'vftable\'' in sym.full_name:
            create_vtable(view, None, sym.address)

        # Create strings
        if sym.raw_name.startswith('??_C@_'):
            view.undefine_user_symbol(sym)
            ascii_string = view.get_ascii_string_at(sym.address)

            if (ascii_string is not None) and (ascii_string.start
                                               == sym.address):
                view.define_user_data_var(
                    sym.address, Type.array(Type.char(), ascii_string.length))

    for func in view.functions:
        if thread.cancelled:
            break
        process_msvc_func(func)
コード例 #27
0
    def init(self):
        self.platform = Platform['interpro-clipper']

        try:
            # determine key parameters based on signature
            header = self.parent_view.read(0, 16)
            if header[4:8] == 'BoB!':
                # Turquoise EPROM
                self.rom_start = 0x7f100000
                self.rom_size = 0x40000
            elif header[8:12] == 'SapH':
                # Sapphire EPROM
                self.rom_start = 0x7f100000
                self.rom_size = len(self.parent_view)
            elif header[8:12] == 'sAP4':
                # Sapphire FLASH
                self.rom_start = 0x7f180000
                self.rom_size = 0x40000

                self.packed_addr = 0x7f1b7e70
                self.unpacked_addr = 0x7a0000
                self.unpacked_size = 0x20000
            else:
                return False

            actual_unpacked_size = len(self.parent_view) - self.rom_size

            # create the ROM segment, section and entry point
            self.add_auto_segment(self.rom_start, self.rom_size, 0, self.rom_size, SegmentFlag.SegmentContainsCode | SegmentFlag.SegmentContainsData | SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
            self.add_auto_section('.rom', self.rom_start, self.rom_size, SectionSemantics.ReadOnlyCodeSectionSemantics)
            self.add_entry_point(self.rom_start)

            # create an unpacked segment and section if necessary
            if self.unpacked_size > 0:
                self.add_auto_segment(self.unpacked_addr, self.unpacked_size, self.rom_size, actual_unpacked_size, SegmentFlag.SegmentContainsData | SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable)
                self.add_auto_section('.unpacked', self.unpacked_addr, self.unpacked_size, SectionSemantics.ReadWriteDataSectionSemantics)

                self.define_auto_symbol(Symbol(SymbolType.DataSymbol, self.packed_addr, 'packed_data'))

            return True

        except:
			log_error(traceback.format_exc())
			return False
コード例 #28
0
    def init(self):
        try:
            hdr = self.parent_view.read(4, 2)
            self.binary_length = struct.unpack("<H", hdr)[0]

            # Add mapping for RAM and hardware registers, not backed by file contents
            self.add_auto_segment(
                0x8000, self.binary_length, 6, self.binary_length,
                SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable
                | SegmentFlag.SegmentExecutable)
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, 0x8000, "main"))

            self.add_entry_point(0x8000)

            return True
        except:
            traceback.print_exc()
            print("ERROR!!!")
            log_error(traceback.format_exc())
            return False
コード例 #29
0
    def init(self):
        self.raw = self.data
        self.binary = self.raw.read(0, len(self.raw))

        self.add_analysis_completion_event(self.on_complete)

        load_settings = self.get_load_settings(self.name)
        if load_settings is None:

            if self.IS_64:
                self.load_address = 0x240000000
                self.arch = Architecture['aarch64']
                self.platform = self.arch.standalone_platform
            else:
                self.load_address = 0x10000000
                self.arch = Architecture['thumb2']
                self.platform = self.arch.standalone_platform

            print("Base address : " + hex(self.load_address))

        else:
            print("Load Settings: ")
            print(load_settings)
            arch = load_settings.get_string("loader.architecture", self)
            self.arch = Architecture[arch]
            self.platform = self.arch.standalone_platform
            self.load_address = int(
                load_settings.get_string("loader.imageBase", self))

        self.add_auto_segment(
            self.load_address, len(self.parent_view), 0, len(self.parent_view),
            SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
        self.add_user_section(self.name, self.load_address, len(self.raw),
                              SectionSemantics.ReadOnlyCodeSectionSemantics)
        self.add_entry_point(self.load_address)
        self.define_auto_symbol(
            Symbol(SymbolType.FunctionSymbol, self.load_address, '_start'))
        self.update_analysis()

        return True
コード例 #30
0
    def init(self):
        self.raw = self.data
        self.add_analysis_completion_event(self.on_complete)
        try:
            load_settings = self.get_load_settings(self.name)
            if load_settings is None:
                print("Load Settings is None")
                self.arch = Architecture['aarch64']
                self.platform = self.arch.standalone_platform
                # return True
                self.load_address = self.find_reset(self.data)
                if self.load_address == -1:
                    print("Error: Could not find reset vector!")
                    self.load_address = 0
                print("LOAD ADDRESS: " + hex(self.load_address))
                # self.add_auto_segment(0, len(self.parent_view), 0, len(self.parent_view), SegmentFlag.SegmentReadable)
            else:
                print("Load Settings: ")
                print(load_settings)
                arch = load_settings.get_string("loader.architecture", self)
                self.arch = Architecture[arch]
                self.platform = self.arch.standalone_platform
                # self.platform = Architecture['aarch64'].standalone_platform
                self.load_address = int(
                    load_settings.get_string("loader.imageBase", self))

            self.add_auto_segment(
                self.load_address, len(self.parent_view), 0,
                len(self.parent_view),
                SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
            self.add_entry_point(self.load_address)
            self.define_auto_symbol(
                Symbol(SymbolType.FunctionSymbol, self.load_address, '_start'))
            self.update_analysis()
            # self.find_interesting()

            return True
        except:
            print(traceback.format_exc())
            return False