Ejemplo n.º 1
0
def create(offset, size, name, **kwds):
    '''Create a segment at /offset/ and /size/ and name it /name/

    /bits/ can be used to specify the bit size of the segment
    /comb/ can be used to specify any flags (idaapi.sc*)
    /align/ can be used to specify paragraph alignment (idaapi.sa*)
    /org/ specifies the origin of the segment (must be paragraph aligned due to ida)
    '''
    s = idaapi.get_segm_by_name(name)
    if s is not None:
        logging.fatal(
            "segment.create(%x, %x, %r, %r) : a segment with the specified name already exists : %s",
            offset, size, name, kwds, name)
        return None

    bits = kwds.get(
        'bits', 32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).
        abits())  # FIXME: use disassembler default bit length instead of 32

    if bits == 16:
        ## create a selector with the requested origin
        org = kwds.get('org', 0)
        if org & 0xf > 0:
            logging.fatal(
                "segment.create(%x, %x, %r, %r) : origin (.org) is not aligned to the size of a paragraph (0x10):%x",
                offset, size, name, kwds, org)
            return None

        para = offset / 16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel, (para - kwds.get('org', 0) / 16) & 0xffffffff)
    else:
        ## auto-create a selector for everything else
        sel = idaapi.setup_selector(
            kwds['selector']
        ) if 'selector' in kwds else idaapi.find_free_selector()

    # create segment. ripped from idc
    s = idaapi.segment_t()
    s.startEA = offset
    s.endEA = offset + size
    s.sel = sel
    s.bitness = {16: 0, 32: 1, 64: 2}[bits]
    s.comb = kwds.get('comb', idaapi.scPub)  # public
    s.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    res = idaapi.add_segm_ex(s, name, "",
                             idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_SPARSE)
    if res == 0:
        logging.warn(
            "segment.create(%x, %x, %r, %r) : unable to add a new segment",
            offset, size, name, kwds)
        res = idaapi.del_selector(sel)
        #assert res != 0
        return None
    return s
Ejemplo n.º 2
0
def create(offset, size, name, **kwds):
    '''Create a segment at /offset/ and /size/ and name it /name/

    /bits/ can be used to specify the bit size of the segment
    /comb/ can be used to specify any flags (idaapi.sc*)
    /align/ can be used to specify paragraph alignment (idaapi.sa*)
    /org/ specifies the origin of the segment (must be paragraph aligned due to ida)
    '''
    s = idaapi.get_segm_by_name(name)
    if s is not None:
        logging.fatal("segment.create(%x, %x, %r, %r) : a segment with the specified name already exists : %s", offset, size, name, kwds, name)
        return None

    bits = kwds.get( 'bits', 32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).abits()) # FIXME: use disassembler default bit length instead of 32

    if bits == 16:
        ## create a selector with the requested origin
        org = kwds.get('org',0)
        if org&0xf > 0:
            logging.fatal("segment.create(%x, %x, %r, %r) : origin (.org) is not aligned to the size of a paragraph (0x10):%x", offset, size, name, kwds, org)
            return None

        para = offset/16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel, (para-kwds.get('org',0)/16)&0xffffffff)
    else:
        ## auto-create a selector for everything else
        sel = idaapi.setup_selector(kwds['selector']) if 'selector' in kwds else idaapi.find_free_selector()

    # create segment. ripped from idc
    s = idaapi.segment_t()
    s.startEA = offset
    s.endEA = offset+size
    s.sel = sel
    s.bitness = {16:0,32:1,64:2}[bits]
    s.comb = kwds.get('comb', idaapi.scPub)       # public
    s.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    res = idaapi.add_segm_ex(s, name, "", idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_SPARSE)
    if res == 0:
        logging.warn("segment.create(%x, %x, %r, %r) : unable to add a new segment", offset, size, name, kwds)
        res = idaapi.del_selector(sel)
        #assert res != 0
        return None
    return s
Ejemplo n.º 3
0
def new(offset, size, name, **kwds):
    """Create a segment at ``offset`` with ``size`` and name it according to ``name``.
    ``bits`` can be used to specify the bit size of the segment
    ``comb`` can be used to specify any flags (idaapi.sc*)
    ``align`` can be used to specify paragraph alignment (idaapi.sa*)
    ``org`` specifies the origin of the segment (must be paragraph aligned due to ida)
    """
    s = idaapi.get_segm_by_name(name)
    if s is not None:
        logging.fatal("{:s}.new({:x}, {:x}, {!r}, {!r}) : a segment with the specified name already exists : {:s}".format(__name__, offset, size, name, kwds, name))
        return None

    bits = kwds.get( 'bits', 32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).abits()) # FIXME: use disassembler default bit length instead of 32

    if bits == 16:
        ## create a selector with the requested origin
        org = kwds.get('org',0)
        if org&0xf > 0:
            logging.fatal("{:s}.new({:x}, {:x}, {!r}, {!r}) : origin (.org) is not aligned to the size of a paragraph (0x10) : {:x}".format(__name__, offset, size, name, kwds, org))
            return None

        para = offset/16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel, (para-kwds.get('org',0)/16)&0xffffffff)
    else:
        ## auto-create a selector for everything else
        sel = idaapi.setup_selector(kwds['selector']) if 'selector' in kwds else idaapi.find_free_selector()

    # create segment. ripped from idc
    s = idaapi.segment_t()
    s.startEA = offset
    s.endEA = offset+size
    s.sel = sel
    s.bitness = {16:0,32:1,64:2}[bits]
    s.comb = kwds.get('comb', idaapi.scPub)       # public
    s.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    res = idaapi.add_segm_ex(s, name, "", idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_SPARSE)
    if res == 0:
        logging.warn("{:s}.new({:x}, {:x}, {!r}, {!r}) : unable to add a new segment".format(__name__, offset, size, name, kwds))
        res = idaapi.del_selector(sel)
        #assert res != 0
        return None
    return s
def new(offset, size, name, **kwds):
    """Create a segment at `offset` with `size` and name it according to `name`.

    The keyword `bits` can be used to specify the bit size of the segment
    The keyword `comb` can be used to specify any flags (idaapi.sc*)
    The keyword `align` can be used to specify paragraph alignment (idaapi.sa*)
    The keyword `org` specifies the origin of the segment (must be paragraph aligned due to ida)
    """
    res = utils.string.to(name)

    # find the segment according to the name specified by the user
    seg = idaapi.get_segm_by_name(res)
    if seg is not None:
        raise E.DuplicateItemError(
            u"{:s}.new({:#x}, {:+#x}, \"{:s}\"{:s}) : A segment with the specified name (\"{:s}\") already exists."
            .format(
                __name__, offset, size, utils.string.escape(name, '"'),
                u", {:s}".format(utils.string.kwargs(kwds)) if kwds else '',
                utils.string.escape(name, '"')))

    # FIXME: use disassembler default bit length instead of 32
    bits = kwds.get(
        'bits',
        32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).abits())

    ## create a selector with the requested origin
    if bits == 16:
        org = kwds.get('org', 0)
        if org & 0xf > 0:
            raise E.InvalidTypeOrValueError(
                u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : The specified origin ({:#x}) is not aligned to the size of a paragraph (0x10)."
                .format(
                    __name__, offset, size, name, u", {:s}".format(
                        utils.string.kwargs(kwds)) if kwds else '', org))

        para = offset // 16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel,
                            (para - kwds.get('org', 0) // 16) & 0xffffffff)

    ## if the user specified a selector, then use it
    elif 'sel' in kwds or 'selector' in kwds:
        sel = kwds.get('sel', kwds.get('selector',
                                       idaapi.find_free_selector()))

    ## choose the paragraph size defined by the user
    elif 'para' in kwds or 'paragraphs' in kwds:
        para = kwds.get('paragraph', kwds.get('para', 1))
        sel = idaapi.setup_selector(para)

    ## find a selector that is 1 paragraph size,
    elif idaapi.get_selector_qty():
        sel = idaapi.find_selector(1)

    # otherwise find a free one and set it.
    else:
        sel = idaapi.find_free_selector()
        idaapi.set_selector(sel, 1)

    # populate the segment_t for versions of IDA prior to 7.0
    if idaapi.__version__ < 7.0:
        seg = idaapi.segment_t()
        seg.startEA, seg.endEA = offset, offset + size

    # now for versions of IDA 7.0 and newer
    else:
        seg = idaapi.segment_t()
        seg.start_ea, seg.end_ea = offset, offset + size

    # assign the rest of the necessary attributes
    seg.sel = sel
    seg.bitness = {16: 0, 32: 1, 64: 2}[bits]
    seg.comb = kwds.get('comb', idaapi.scPub)  # public
    seg.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    # now we can add our segment_t to the database
    res = utils.string.to(name)
    ok = idaapi.add_segm_ex(seg, res, "",
                            idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_SPARSE)
    if not ok:
        ok = idaapi.del_selector(sel)
        if not ok:
            logging.warning(
                u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : Unable to delete the created selector ({:#x}) for the new segment."
                .format(
                    __name__, offset, size, name, u", {:s}".format(
                        utils.string.kwargs(kwds)) if kwds else '', sel))
        raise E.DisassemblerError(
            u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : Unable to add a new segment."
            .format(
                __name__, offset, size, name,
                u", {:s}".format(utils.string.kwargs(kwds)) if kwds else ''))
    return seg
Ejemplo n.º 5
0
def load_file(li, neflags, format):
    idaapi.set_processor_type('xap2csr',
                              idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL)
    li.seek(0)
    lines = li.read(li.size()).split('\n')
    segs = {}
    for seg in ('code', 'data'):
        segs[seg] = {'chunks': [], 'syms': []}

    def handle_line(line):
        raise ValueError('got non-commented line before title: %r' % (line, ))

    for line in lines:
        #print repr(line)
        line = line.strip()
        if not line:
            continue
        if not line.startswith('// '):
            line = re.sub('\s*//.*', '', line)
            handle_line(line)
            continue
        m = re.match('^// Title +: "(Code|Constant|Symbol) Table"', line)
        if not m:
            continue
        kind = m.group(1)
        if kind in ('Code', 'Constant'):
            chunks = segs['code' if kind == 'Code' else 'data']['chunks']
            if chunks != []:
                raise ValueError('more than one %s table in file' % (kind, ))
            cur_addr_box = [None]
            cur_chunk_box = [None]

            def handle_line(line):
                m = re.match('^@([0-9A-Fa-f]+)\s+([0-9A-Fa-f]{4})$', line)
                if not m:
                    raise ValueError('unrecognized seg line: %r' % (line, ))
                addr, word = [int(x, 16) for x in m.groups()]
                cur_addr, cur_chunk = cur_addr_box[0], cur_chunk_box[0]
                if cur_addr is None or addr > cur_addr:
                    cur_chunk = cur_chunk_box[0] = []
                    chunks.append((addr, cur_chunk))
                elif addr < cur_addr:
                    raise ValueError(
                        'going backwards with addresses (cur_addr=0x%x): %r' %
                        (
                            cur_addr,
                            line,
                        ))
                cur_chunk.append(word)
                cur_addr_box[0] = addr + 1
        else:
            assert kind == 'Symbol'
            cur_syms_box = [None]

            def handle_line(line):
                if line in ('.CODE', '.DATA'):
                    cur_syms_box[0] = segs[line[1:].lower()]['syms']
                else:
                    m = re.match('^([^,]+), ([0-9a-fA-F]+)*$', line)
                    if not m:
                        raise ValueError('unknown symbol line: %r' % (line, ))
                    cur_syms = cur_syms_box[0]
                    if cur_syms is None:
                        raise ValueError('symbols without a segment: %r' %
                                         (line, ))
                    cur_syms.append((int(m.group(2),
                                         16), m.group(1)))  # (addr, name)

    for (segname, info) in segs.iteritems():
        kind = {'code': 0, 'data': 1}[segname]
        base_addr = (0, 0x1000000)[kind]
        if segname == 'code' and info['chunks'] == [] and info['syms'] == []:
            continue
        if not idaapi.set_selector(kind + 1, base_addr >> 4):
            raise Exception("couldn't set selector for segment %s" % (name, ))
        for addr, chunk in info['chunks']:
            seg = idaapi.segment_t()
            seg.startEA = base_addr + addr
            seg.endEA = base_addr + addr + len(chunk)
            seg.bitness = 1  # 32-bit (we can have more than 16 bits of code, so just use for both)
            seg.sel = kind + 1
            name = '%s_%x' % (segname, addr)
            klass = segname.upper()
            #print '%s from %x to %x' % (name, seg.startEA, seg.endEA)
            if not idaapi.add_segm_ex(seg, name, klass, ADDSEG_NOSREG):
                raise Exception("couldn't add segment %s" % (name, ))
            ea = seg.startEA
            for word in chunk:
                idaapi.put_byte(ea, word)
                ea += 1
            if segname == 'code':
                idaapi.autoMark(seg.startEA, AU_CODE)
        if segname == 'data':
            # fill in the remaining area with BSS
            spaces = zip(
                [0] + [addr + len(chunk) for (addr, chunk) in info['chunks']],
                [addr for (addr, chunk) in info['chunks']] + [0x10000])
            for start, end in spaces:
                if end - start < 0x10:
                    continue
                assert end > start
                seg = idaapi.segment_t()
                seg.startEA = base_addr + start
                seg.endEA = base_addr + end
                seg.bitness = 1
                seg.sel = kind + 1
                name = 'bss_%x' % (start, )
                #print '%s from %x to %x' % (name, seg.startEA, seg.endEA)
                if not idaapi.add_segm_ex(
                        seg, name, 'BSS',
                        idaapi.ADDSEG_SPARSE | ADDSEG_NOSREG):
                    raise Exception("couldn't add segment %s" % (name, ))
    return 1
Ejemplo n.º 6
0
def new(offset, size, name, **kwds):
    """Create a segment at `offset` with `size` and name it according to `name`.

    The keyword `bits` can be used to specify the bit size of the segment
    The keyword `comb` can be used to specify any flags (idaapi.sc*)
    The keyword `align` can be used to specify paragraph alignment (idaapi.sa*)
    The keyword `org` specifies the origin of the segment (must be paragraph aligned due to ida)
    """
    seg = idaapi.get_segm_by_name(name)
    if seg is not None:
        raise NameError(
            "{:s}.new({:#x}, {:+#x}, {!r}{:s}) : A segment with the specified name ({!r}) already exists."
            .format(
                __name__, offset, size, name, ", {:s}".format(', '.join(
                    "{:s}={!r}".format(k, v)
                    for k, v in kwds.iteritems())) if kwds else '', name))

    bits = kwds.get(
        'bits', 32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).
        abits())  # FIXME: use disassembler default bit length instead of 32

    ## create a selector with the requested origin
    if bits == 16:
        org = kwds.get('org', 0)
        if org & 0xf > 0:
            raise E.InvalidTypeOrValueError(
                "{:s}.new({:#x}, {:+#x}, {!r}{:s}) : The specified origin ({:#x}) is not aligned to the size of a paragraph (0x10)."
                .format(
                    __name__, offset, size, name, ", {:s}".format(', '.join(
                        "{:s}={!r}".format(k, v)
                        for k, v in kwds.iteritems())) if kwds else '', org))

        para = offset / 16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel, (para - kwds.get('org', 0) / 16) & 0xffffffff)

    ## if the user specified a selector, then use it
    elif 'sel' in kwds or 'selector' in kwds:
        sel = kwds.get('sel', kwds.get('selector',
                                       idaapi.find_free_selector()))

    ## choose the paragraph size defined by the user
    elif 'para' in kwds or 'paragraphs' in kwds:
        para = kwds.get('paragraph', kwds.get('para', 1))
        sel = idaapi.setup_selector(res)

    ## find a selector that is 1 paragraph size,
    elif idaapi.get_selector_qty():
        sel = idaapi.find_selector(1)

    # otherwise find a free one and set it.
    else:
        sel = idaapi.find_free_selector()
        idaapi.set_selector(sel, 1)

    # create segment. ripped from idc
    seg = idaapi.segment_t()
    seg.startEA = offset
    seg.endEA = offset + size
    seg.sel = sel
    seg.bitness = {16: 0, 32: 1, 64: 2}[bits]
    seg.comb = kwds.get('comb', idaapi.scPub)  # public
    seg.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    ok = idaapi.add_segm_ex(seg, name, "",
                            idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_SPARSE)
    if not ok:
        ok = idaapi.del_selector(sel)
        if not ok:
            logging.warn(
                "{:s}.new({:#x}, {:+#x}, {!r}{:s}) : Unable to delete the created selector ({:#x}) for the new segment."
                .format(
                    __name__, offset, size, name, ", {:s}".format(', '.join(
                        "{:s}={!r}".format(k, v)
                        for k, v in kwds.iteritems())) if kwds else '', sel))

        raise E.DisassemblerError(
            "{:s}.new({:#x}, {:+#x}, {!r}{:s}) : Unable to add a new segment.".
            format(
                __name__, offset, size, name, ", {:s}".format(', '.join(
                    "{:s}={!r}".format(k, v)
                    for k, v in kwds.iteritems())) if kwds else ''))
    return seg
Ejemplo n.º 7
0
def new(offset, size, name, **kwds):
    """Create a segment at ``offset`` with ``size`` and name it according to ``name``.

    The keyword ``bits`` can be used to specify the bit size of the segment
    The keyword ``comb`` can be used to specify any flags (idaapi.sc*)
    The keyword ``align`` can be used to specify paragraph alignment (idaapi.sa*)
    The keyword ``org`` specifies the origin of the segment (must be paragraph aligned due to ida)
    """
    s = idaapi.get_segm_by_name(name)
    if s is not None:
        logging.fatal(
            "{:s}.new({:#x}, {:+#x}, {!r}, {!r}) : A segment with the specified name ({!r}) already exists."
            .format(__name__, offset, size, name, kwds, name))
        return None

    bits = kwds.get(
        'bits', 32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).
        abits())  # FIXME: use disassembler default bit length instead of 32

    ## create a selector with the requested origin
    if bits == 16:
        org = kwds.get('org', 0)
        if org & 0xf > 0:
            logging.fatal(
                "{:s}.new({:#x}, {:+#x}, {!r}, {!r}) : The origin ({:#x}) is not aligned to the size of a paragraph (0x10)."
                .format(__name__, offset, size, name, kwds, org))
            return None

        para = offset / 16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel, (para - kwds.get('org', 0) / 16) & 0xffffffff)

    ## if the user specified a selector, then use it
    elif 'sel' in kwds or 'selector' in kwds:
        sel = kwds.get('sel', kwds.get('selector',
                                       idaapi.find_free_selector()))

    ## choose the paragraph size defined by the user
    elif 'para' in kwds or 'paragraphs' in kwds:
        para = kwds.get('paragraph', kwds.get('para', 1))
        sel = idaapi.setup_selector(res)

    ## find a selector that is 1 paragraph size,
    elif idaapi.get_selector_qty():
        sel = idaapi.find_selector(1)

    # otherwise find a free one and set it.
    else:
        sel = idaapi.find_free_selector()
        idaapi.set_selector(sel, 1)

    # create segment. ripped from idc
    s = idaapi.segment_t()
    s.startEA = offset
    s.endEA = offset + size
    s.sel = sel
    s.bitness = {16: 0, 32: 1, 64: 2}[bits]
    s.comb = kwds.get('comb', idaapi.scPub)  # public
    s.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    res = idaapi.add_segm_ex(s, name, "",
                             idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_SPARSE)
    if res == 0:
        logging.warn(
            "{:s}.new({:#x}, {:+#x}, {!r}, {!r}) : Unable to add a new segment."
            .format(__name__, offset, size, name, kwds))
        res = idaapi.del_selector(sel)
        #assert res != 0
        return None
    return s
Ejemplo n.º 8
0
def load_file(li, neflags, format):
    idaapi.set_processor_type('xap2csr', idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL)
    li.seek(0)
    lines = li.read(li.size()).split('\n')
    segs = {}
    for seg in ('code', 'data'):
        segs[seg] = {'chunks': [], 'syms': []}
    def handle_line(line):
        raise ValueError('got non-commented line before title: %r' % (line,))
    for line in lines:
        #print repr(line)
        line = line.strip()
        if not line:
            continue
        if not line.startswith('// '):
            line = re.sub('\s*//.*', '', line)
            handle_line(line)
            continue
        m = re.match('^// Title +: "(Code|Constant|Symbol) Table"', line)
        if not m:
            continue
        kind = m.group(1)
        if kind in ('Code', 'Constant'):
            chunks = segs['code' if kind == 'Code' else 'data']['chunks']
            if chunks != []:
                raise ValueError('more than one %s table in file' % (kind,))
            cur_addr_box = [None]
            cur_chunk_box = [None]
            def handle_line(line):
                m = re.match('^@([0-9A-Fa-f]+)\s+([0-9A-Fa-f]{4})$', line)
                if not m:
                    raise ValueError('unrecognized seg line: %r' % (line,))
                addr, word = [int(x, 16) for x in m.groups()]
                cur_addr, cur_chunk = cur_addr_box[0], cur_chunk_box[0]
                if cur_addr is None or addr > cur_addr:
                    cur_chunk = cur_chunk_box[0] = []
                    chunks.append((addr, cur_chunk))
                elif addr < cur_addr:
                    raise ValueError('going backwards with addresses (cur_addr=0x%x): %r' % (cur_addr, line,))
                cur_chunk.append(word)
                cur_addr_box[0] = addr + 1
        else:
            assert kind == 'Symbol'
            cur_syms_box = [None]
            def handle_line(line):
                if line in ('.CODE', '.DATA'):
                    cur_syms_box[0] = segs[line[1:].lower()]['syms']
                else:
                    m = re.match('^([^,]+), ([0-9a-fA-F]+)*$', line)
                    if not m:
                        raise ValueError('unknown symbol line: %r' % (line,))
                    cur_syms = cur_syms_box[0]
                    if cur_syms is None:
                        raise ValueError('symbols without a segment: %r' % (line,))
                    cur_syms.append((int(m.group(2), 16), m.group(1))) # (addr, name)
    for (segname, info) in segs.iteritems():
        kind = {'code': 0, 'data': 1}[segname]
        base_addr = (0, 0x1000000)[kind]
        if segname == 'code' and info['chunks'] == [] and info['syms'] == []:
            continue
        if not idaapi.set_selector(kind + 1, base_addr >> 4):
            raise Exception("couldn't set selector for segment %s" % (name,))
        for addr, chunk in info['chunks']:
            seg = idaapi.segment_t()
            seg.startEA = base_addr + addr
            seg.endEA = base_addr + addr + len(chunk)
            seg.bitness = 1 # 32-bit (we can have more than 16 bits of code, so just use for both)
            seg.sel = kind + 1
            name = '%s_%x' % (segname, addr)
            klass = segname.upper()
            #print '%s from %x to %x' % (name, seg.startEA, seg.endEA)
            if not idaapi.add_segm_ex(seg, name, klass, ADDSEG_NOSREG):
                raise Exception("couldn't add segment %s" % (name,))
            ea = seg.startEA
            for word in chunk:
                idaapi.put_byte(ea, word)
                ea += 1
            if segname == 'code':
                idaapi.autoMark(seg.startEA, AU_CODE)
        if segname == 'data':
            # fill in the remaining area with BSS
            spaces = zip([0] + [addr+len(chunk) for (addr, chunk) in info['chunks']],
                         [addr for (addr, chunk) in info['chunks']] + [0x10000])
            for start, end in spaces:
                if end - start < 0x10:
                    continue
                assert end > start
                seg = idaapi.segment_t()
                seg.startEA = base_addr + start
                seg.endEA = base_addr + end
                seg.bitness = 1
                seg.sel = kind + 1
                name = 'bss_%x' % (start,)
                #print '%s from %x to %x' % (name, seg.startEA, seg.endEA)
                if not idaapi.add_segm_ex(seg, name, 'BSS', idaapi.ADDSEG_SPARSE | ADDSEG_NOSREG):
                    raise Exception("couldn't add segment %s" % (name,))
    return 1
Ejemplo n.º 9
0
def new(offset, size, name, **kwds):
    """Create a segment at `offset` with `size` and name it according to `name`.

    The keyword `bits` can be used to specify the bit size of the segment
    The keyword `comb` can be used to specify any flags (idaapi.sc*)
    The keyword `align` can be used to specify paragraph alignment (idaapi.sa*)
    The keyword `org` specifies the origin of the segment (must be paragraph aligned due to ida)
    """
    res = utils.string.to(name)

    # find the segment according to the name specified by the user
    seg = idaapi.get_segm_by_name(res)
    if seg is not None:
        raise E.DuplicateItemError(u"{:s}.new({:#x}, {:+#x}, \"{:s}\"{:s}) : A segment with the specified name (\"{:s}\") already exists.".format(__name__, offset, size, utils.string.escape(name, '"'), u", {:s}".format(utils.string.kwargs(kwds)) if kwds else '', utils.string.escape(name, '"')))

    # FIXME: use disassembler default bit length instead of 32
    bits = kwds.get( 'bits', 32 if idaapi.getseg(offset) is None else idaapi.getseg(offset).abits())

    ## create a selector with the requested origin
    if bits == 16:
        org = kwds.get('org',0)
        if org & 0xf > 0:
            raise E.InvalidTypeOrValueError(u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : The specified origin ({:#x}) is not aligned to the size of a paragraph (0x10).".format(__name__, offset, size, name, u", {:s}".format(utils.string.kwargs(kwds)) if kwds else '', org))

        para = offset/16
        sel = idaapi.allocate_selector(para)
        idaapi.set_selector(sel, (para-kwds.get('org',0)/16)&0xffffffff)

    ## if the user specified a selector, then use it
    elif 'sel' in kwds or 'selector' in kwds:
        sel = kwds.get('sel', kwds.get('selector', idaapi.find_free_selector()))

    ## choose the paragraph size defined by the user
    elif 'para' in kwds or 'paragraphs' in kwds:
        para = kwds.get('paragraph', kwds.get('para', 1))
        sel = idaapi.setup_selector(para)

    ## find a selector that is 1 paragraph size,
    elif idaapi.get_selector_qty():
        sel = idaapi.find_selector(1)

    # otherwise find a free one and set it.
    else:
        sel = idaapi.find_free_selector()
        idaapi.set_selector(sel, 1)

    # populate the segment_t using code ripped from the idc module
    seg = idaapi.segment_t()
    seg.startEA = offset
    seg.endEA = offset+size
    seg.sel = sel
    seg.bitness = {16:0,32:1,64:2}[bits]
    seg.comb = kwds.get('comb', idaapi.scPub)       # public
    seg.align = kwds.get('align', idaapi.saRelByte)  # paragraphs

    # now we can add our segment_t to the database
    res = utils.string.to(name)
    ok = idaapi.add_segm_ex(seg, res, "", idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_SPARSE)
    if not ok:
        ok = idaapi.del_selector(sel)
        if not ok:
            logging.warn(u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : Unable to delete the created selector ({:#x}) for the new segment.".format(__name__, offset, size, name, u", {:s}".format(utils.string.kwargs(kwds)) if kwds else '', sel))
        raise E.DisassemblerError(u"{:s}.new({:#x}, {:+#x}, {!r}{:s}) : Unable to add a new segment.".format(__name__, offset, size, name, u", {:s}".format(utils.string.kwargs(kwds)) if kwds else ''))
    return seg