Ejemplo n.º 1
0
def myAddSeg(startea, endea, base, use32, name, clas):
    s = idaapi.segment_t()
    s.startEA = startea
    s.endEA = endea
    s.sel = idaapi.setup_selector(base)
    s.bitness = use32
    s.align = idaapi.saRelPara
    s.comb = idaapi.scPub
    idaapi.add_segm_ex(s, name, clas, idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
Ejemplo n.º 2
0
def add_seg(start_ea, end_ea, name, cls, use32, align, comb):
    s = idaapi.segment_t()
    s.startEA = start_ea
    s.endEA = end_ea
    s.sel = idaapi.setup_selector(0)
    s.bitness = use32
    s.align = align
    s.comb = comb
    return idaapi.add_segm_ex(s, name, cls, idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
Ejemplo n.º 3
0
def add_seg(start_ea, end_ea, name, cls, use32, align, comb):
    s = idaapi.segment_t()
    s.startEA     = start_ea
    s.endEA       = end_ea
    s.sel         = idaapi.setup_selector(0)
    s.bitness     = use32
    s.align       = align
    s.comb        = comb
    return idaapi.add_segm_ex(s, name, cls, idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_OR_DIE)
Ejemplo n.º 4
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.º 5
0
def add_seg(startea, endea, bank, name):
    s = idaapi.segment_t()
    s.start_ea = startea + bank * 0x10000
    s.end_ea = endea + bank * 0x10000
    s.sel = idaapi.setup_selector(bank * 0x1000)
    s.bitness = 0
    s.align = idaapi.saRelPara
    s.comb = idaapi.scPub
    idaapi.add_segm_ex(s, name, "",
                       idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
Ejemplo n.º 6
0
def myAddSeg(startea, endea, base, use32, name, clas):
    s = idaapi.segment_t()
    s.start_ea = startea
    s.end_ea = endea
    s.sel = idaapi.setup_selector(base)
    s.bitness = use32
    s.align = idaapi.saRelPara
    s.comb = idaapi.scPub
    #idaapi.add_segm_ex(s, name, clas, idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_OR_DIE)
    idaapi.add_segm(base, startea, endea, name, clas)
Ejemplo n.º 7
0
def AdditionalSegment(size, offset, name):
    s = idaapi.segment_t()
    step = 0x1000000 - 1
    s.startEA = idaapi.freechunk(0x1000000, size, step)
    s.endEA = s.startEA + size
    s.sel = idaapi.setup_selector((s.startEA - offset) >> 4)
    s.type = idaapi.SEG_DATA
    if byte_size("X") > 2:
        s.bitness = 1
    else:
        s.bitness = 0
    idaapi.add_segm_ex(s, name, "DATA", idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
    return s.startEA - offset
Ejemplo n.º 8
0
def AdditionalSegment(size, offset, name):
  s = idaapi.segment_t()
  step = 0x1000000-1
  s.startEA = idaapi.freechunk(0x1000000, size, step)
  s.endEA   = s.startEA + size
  s.sel     = idaapi.setup_selector((s.startEA-offset) >> 4)
  s.type    = idaapi.SEG_DATA
  if byte_size('X') > 2:
    s.bitness = 1
  else:
    s.bitness = 0
  idaapi.add_segm_ex(s, name, "DATA", idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_OR_DIE)
  return s.startEA - offset
Ejemplo n.º 9
0
    def AddDefaultSH4Segments(self):
        """Add a segment to the IDB with some basic options set for convenience."""
        base_address = 0x0C000000
        # Create segments on the range of 0x04000000 bytes
        for segment in range(5):
            name = "Area_%d" % (segment + 3)
            s = idaapi.segment_t()
            s.startEA = base_address
            s.endEA = base_address + 0x04000000
            s.bitness = 1  # 32-bit
            s.align = idaapi.saRelByte
            s.comb = idaapi.scPub
            s.sel = idaapi.setup_selector(0)
            # We mark the segments as code, as we know these are loops in memory
            idaapi.add_segm_ex(s, name, 'CODE',
                               idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
            base_address += 0x04000000

        # Second set of segments (now is the privileged ones)
        base_address = 0x80000000
        # Create segments on the range of 0x04000000 bytes
        for segment in range(4):
            name = "Priv_%d" % (segment + 1)
            s = idaapi.segment_t()
            s.startEA = base_address
            if base_address == 0xE0000000:
                s.endEA = base_address + 0x10000000
            else:
                s.endEA = base_address + 0x20000000
            s.bitness = 1  # 32-bit
            s.align = idaapi.saRelByte
            s.comb = idaapi.scPub
            s.sel = idaapi.setup_selector(0)
            # We mark the segments as code, as we know these are loops in memory
            idaapi.add_segm_ex(s, name, None,
                               idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
            base_address += 0x20000000
Ejemplo n.º 10
0
    def _AddSegment(self, name, base_address, data=None):
        """Add a segment to the IDB with some basic options set for convenience."""
        s = idaapi.segment_t()

        s.startEA = base_address
        s.endEA = base_address + len(data)
        s.bitness = 1  # 32-bit
        s.align = idaapi.saRelByte
        s.comb = idaapi.scPub
        s.sel = idaapi.setup_selector(0)

        # We mark the segments as code, as we know these are loops in memory
        idaapi.add_segm_ex(s, name, "CODE",
                           idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
        idaapi.mem2base(data, base_address)
def AddSegment(name, base_address, data):
    """Add a segment to the IDB with some basic options set for convenience."""
    s = idaapi.segment_t()
    
    s.startEA = base_address
    s.endEA = base_address + len(data)
    
    s.bitness = 1 # 32-bit
    
    s.align = idaapi.saRelByte
    s.comb = idaapi.scPub
    
    s.sel = idaapi.setup_selector(0)
    
    idaapi.add_segm_ex(s, name, None, idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
    idaapi.mem2base(data, base_address)
Ejemplo n.º 12
0
def AddSegment(name, base_address, data):
    """Add a segment to the IDB with some basic options set for convenience."""
    s = idaapi.segment_t()

    s.startEA = base_address
    s.endEA = base_address + len(data)

    s.bitness = 1  # 32-bit

    s.align = idaapi.saRelByte
    s.comb = idaapi.scPub

    s.sel = idaapi.setup_selector(0)

    idaapi.add_segm_ex(s, name, None,
                       idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
    idaapi.mem2base(data, base_address)
Ejemplo n.º 13
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.º 14
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
Ejemplo n.º 15
0
def load_file(li, neflags, format):
    """Load the file into database
    
    Args:
        li: a file-like object which can be used to access the input data
        neflags: options selected by the user, see loader.hpp
    Returns: 
        0-failure
        1-ok
    """

    idaapi.set_processor_type("sh4", SETPROC_ALL | SETPROC_FATAL)

    li.seek(0, idaapi.SEEK_END)
    size = li.tell()
    li.seek(0)
    rom_data = li.read(size)

    s = idaapi.segment_t()
    s.startEA = 0
    s.endEA = size
    s.bitness = 1  # 32-bit
    s.align = idaapi.saRelByte
    s.comb = idaapi.scPub
    s.sel = idaapi.setup_selector(0)

    idaapi.add_segm_ex(s, "ROM", "DATA",
                       idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE)
    idaapi.mem2base(rom_data, 0)

    headr = JasperThe2kCat()
    headr.AnotateHeader(binary_file=li)
    headr.MakeStrings(binary_file=li)
    gentries = gameEntries()

    gentries.readGameLoops(binary_file=li)
    gentries.CreateSegments(binary_file=li)
    gentries.makeDWordTables()
    gentries.makeDWordTables(start_address=0x2a0, end_address=0x1000)
    gentries.addIDA_entry()

    print("load ok")
    return 1
Ejemplo n.º 16
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
Ejemplo n.º 17
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.º 18
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
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.º 20
0
def findAllKEXT():
	"""
	findAllKEXT:
	
	Finds all KEXT contained in the kernelcache file. The mach-o
	headers will be converted into the appropiate structs, the
	new sections will be defined and the name and version number
	of the KEXT are extracted. In the end a window is shown that
	shows all contained KEXT.
	"""
	
	# Ask the user if he wants to add all the KEXT sections
	# to the IDA database. 
	answer = idc.AskYN(0, """Do you want to add all the KEXT sections to the IDA database?
	
If this was already done before or there was already code or data in the same place in the IDA database, IDA might react very slow, crash or just stop to work.""")
	
	# KEXT cache starts behind the __LINKEDIT segment
	# NOTE: IDA calls the segment __LINKEDIT_hidden
	
	linkedit = idaapi.get_segm_by_name("__LINKEDIT_hidden")
	if not linkedit:
		print "[-] cannot find KEXTCACHE: __LINKEDIT segment not found"
		return
	kextcache = idaapi.get_next_seg(linkedit.endEA)
	if not kextcache:
		print "[-] cannot find KEXTCACHE: __LINKEDIT not followed by any segment"
		return
	
	dummyName = idaapi.get_segm_name(kextcache)
	if dummyName != "__text":
		print "[-] cannot find KEXTCACHE: __LINKEDIT not followed by __text segment"
		return
	
	if answer == 1:
		# Destroy everything in the kextcache area
		idaapi.do_unknown_range(kextcache.startEA, kextcache.endEA-kextcache.startEA, DOUNK_DELNAMES)
	
	startEA = kextcache.startEA
	kextlist = []
	while True:
		sig = idc.Dword(startEA)
		if sig != 0xfeedface:
			"[-] expected the next KEXT but did not find correct signature"
			break
		
		seg_lc = None
		
		sections = []
		added = 0
		
		next = forceStruct(startEA, "mach_header")
		ncmds = get_member_from_struct(startEA, "mach_header", "ncmds")
		for i in range(ncmds):
			lc_addr = next
			cmd = get_member_from_struct(next, "load_command", "cmd")
			if cmd == 1:
				seg_lc = next
				next = forceStruct(seg_lc, "segment_command")
				nsecs = get_member_from_struct(seg_lc, "segment_command", "nsects")
				for j in range(nsecs):
					section = next
					next = forceStruct(section, "section")
					
					# Get basic information about segment (needed for ALL the code below)
					secStart = get_member_from_struct(section, "section", "addr")
					secEnd = secStart + get_member_from_struct(section, "section", "size")
					secname = idc.GetString(section)
					
					# We should tell IDA about what this section is
					s = idaapi.segment_t()
					s.startEA	  = secStart
					s.endEA		  = secEnd
					s.sel		  = idaapi.setup_selector(0)
					if secname == "__text":
						s.bitness = 0
					else:
						s.bitness = 1
					s.align		  = get_member_from_struct(section, "section", "align")
					s.comb		  = 0 # ???
					
					if secname == "__text" or secname == "stubs":
						sclass = "CODE"
					elif secname == "__bss":
						sclass = "BSS"
					else:
						sclass = "DATA"
					
					if len(sections) == 0:
						sec = {}
						sec["name"] = "MACH-O HEADER"
						sec["start"] = "%08X" % (startEA)
						sec["end"] = "%08X" % (secStart-1)
						sections.append(sec)
					
					sec = {}
					sec["name"] = secname
					sec["start"] = "%08X" % (secStart)
					sec["end"] = "%08X" % (secEnd-1)
					sections.append(sec)
					
					if answer == 1:
						# Destroy everything inside the segment
						idaapi.do_unknown_range(secStart, secEnd-secStart, DOUNK_DELNAMES)
					
						# Ensure that the whole section is undefined
						idaapi.add_segm_ex(s, secname, sclass, idaapi.ADDSEG_NOSREG|idaapi.ADDSEG_QUIET)
					
					if secname == "__text":
						idc.SetRegEx(secStart, "T", 1, 0)

					# special handling of constructor and destructor
					if secname == "__constructor" or secname == "__destructor":
						for z in range(secStart, secEnd, 4):
							idc.OpOffEx(z, -1, REF_OFF32, 0xFFFFFFFF, 0, 0)
					
					# We have to check for __data section because we want
					# to find the kmod_info structure
					if secname != "__data":
						continue
						
					kextName = None
					for z in range(secStart, secEnd, 4):
						k = z
						# We assume that all KEXT name start with "com."
						kextNameSig = idc.Dword(k)
						if kextNameSig == 0x2e6d6f63:
							forceStruct(k-12, "kmod_info")
							kextName = idc.GetString(k)
							kextVersion = idc.GetString(k+64)
							#print "-> %s - version: %s" % (kextName, kextVersion)
							
							dic = {}
							dic["addr"] = "%08X" % (startEA)
							dic["name"] = kextName
							dic["version"] = kextVersion
							kextlist.append(dic)
							added = 1
							break
					if kextName == None:
						print "ERROR COULD NOT FIND NAME"
					
			elif cmd == 0x1b:
				next = forceStruct(lc_addr, "uuid_command")
			elif cmd == 0x2:
				next = forceStruct(lc_addr, "symtab_command")
				#print "Found symbol table KEXT at %08x" % (startEA)
			else:
				print "Unknown load command %08x" % (cmd)
			
			if added:
				kextlist[len(kextlist)-1]["sections"] = sections
			
			next = lc_addr + get_member_from_struct(lc_addr, "load_command", "cmdsize")
		
		if seg_lc == None:
			startEA += 4
			while idc.Dword(startEA) != 0xfeedface:
				startEA += 4
			continue
		
		startEA = get_member_from_struct(seg_lc, "segment_command", "vmaddr")
		startEA += get_member_from_struct(seg_lc, "segment_command", "vmsize")

	c = MySelectionDialog("Retrieved KEXT", [ ["Address", 10], [ "Name", 65 ], ["Version", 65] ], formatKEXTresults(kextlist))
	selected_row = c.Show(True)
	if selected_row >= 0:
		sel = kextlist[selected_row]
		
		c = MySelectionDialog("Sections inside " + sel["name"], [ ["Name", 16], [ "Start", 10 ], ["End", 10] ], formatSECTIONresults(sel["sections"]))
		selected_row = c.Show(True)
		if selected_row >= 0:
			sel = sel["sections"][selected_row]
			
			idc.Jump(int(sel["start"], 16))