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)
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)
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)
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
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)
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)
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
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
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
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)
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
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 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
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
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
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
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))