Пример #1
0
def fixupSysctlSet():
    '''
	fixupSysctlSet:
	
	Fixes up the '__sysctl_set' segment, ensures the targets are actually
	'sysctl_oid' structures and adds the correct function type to the handler.
	'''
    segm = idaapi.get_segm_by_name("__DATA:__sysctl_set")
    if not segm:
        segm = idaapi.get_segm_by_name("__sysctl_set")
        if not segm:
            print "Could not find kernel __sysctl_set section"
            return

    segea = segm.startEA
    segend = segm.endEA

    sid = get_struc_id("sysctl_oid")
    ssize = get_struc_size(sid)
    stru = get_struc(sid)
    if ssize == 0:
        print "Could not load information about 'sysctl_oid' struct"
        return

    # clear whole range of sysctl_set segment
    idaapi.do_unknown_range(segea, segend - segea, DOUNK_DELNAMES)

    # idapython oldschool - we work with the structure offset
    oid_handler = get_member_by_name(stru, "oid_handler")

    # loop through sysctl_set segment
    while segea < segend:
        # Ensure pointer is a pointer
        idaapi.op_offset(segea, 0, idaapi.REF_OFF32, 0xffffffff, 0, 0)
        ptr = idc.Dword(segea)

        # Mark structure as sysctl_oid structure
        idaapi.do_unknown_range(ptr, ssize, DOUNK_DELNAMES)
        x = doStruct(ptr, ssize, sid)
        handler = idc.Dword(ptr + oid_handler.soff)

        # We have to support ARM THUMB code
        addr = handler & 0xFFFFFFFE

        # Set correct function type for oid_handler
        idc.SetType(
            addr,
            "int *oid_handler(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);"
        )

        segea += 4
Пример #2
0
def fixupSysctlSet():
	'''
	fixupSysctlSet:
	
	Fixes up the '__sysctl_set' segment, ensures the targets are actually
	'sysctl_oid' structures and adds the correct function type to the handler.
	'''
	segm = idaapi.get_segm_by_name("__DATA:__sysctl_set")
	if not segm:
		segm = idaapi.get_segm_by_name("__sysctl_set")
		if not segm:
			print "Could not find kernel __sysctl_set section"
			return
		
	segea = segm.startEA
	segend = segm.endEA

	sid = get_struc_id("sysctl_oid")
	ssize = get_struc_size(sid)
	stru = get_struc(sid)
	if ssize == 0:
		print "Could not load information about 'sysctl_oid' struct"
		return

	# clear whole range of sysctl_set segment
	idaapi.do_unknown_range(segea, segend-segea, DOUNK_DELNAMES)

	# idapython oldschool - we work with the structure offset
	oid_handler = get_member_by_name(stru, "oid_handler")
	
	# loop through sysctl_set segment
	while segea < segend:
		# Ensure pointer is a pointer
		idaapi.op_offset(segea, 0, idaapi.REF_OFF32, 0xffffffff, 0, 0)
		ptr = idc.Dword(segea)
		
		# Mark structure as sysctl_oid structure
		idaapi.do_unknown_range(ptr, ssize, DOUNK_DELNAMES)
		x = doStruct(ptr, ssize, sid)
		handler = idc.Dword(ptr + oid_handler.soff)

		# We have to support ARM THUMB code
		addr = handler & 0xFFFFFFFE
		
		# Set correct function type for oid_handler
		idc.SetType(addr, "int *oid_handler(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);")

		segea += 4
Пример #3
0
  def get_segments_memory(self):
    memory = b""
    step_size = self.entropy_cfg['step_size']
    segments  = OrderedDict()

    for ea in filter(self.segment_filter, idautils.Segments()):
      seg_name = idc.get_segm_name(ea)
      segm  = idaapi.get_segm_by_name(seg_name)
      data = idaapi.get_bytes(segm.start_ea, segm.size())
      assert len(data) == segm.size()

      start_offset = len(memory)
      end_offset   = (start_offset+len(data))

      seg_info = {
        'segm': segm,
        'entropy': entropy(data),
        'offsets': [
          start_offset ,
          end_offset
        ],
        'chart_offsets': [
          start_offset // step_size,
          end_offset // step_size
        ]
      }
      segments[seg_name] = seg_info
      memory += data

    self.data = memory
    self.data_size = len(memory)
    self.segments = segments
Пример #4
0
 def __init__(self):
     self.sym_file_path = idc.AskFile(0, "*.map;*.txt", "open symbol file")
     self.sym_file = None
     self.seg = idaapi.get_segm_by_name(".text")
     if self.seg is None:
         self.seg = idaapi.getnseg(0)
     self.base = self.seg.startEA
Пример #5
0
 def __init__(self, dotnet_version):
     self.dotnet_version = dotnet_version
     self.imagebase = idaapi.get_imagebase()
     self.module_header_struct = idaapi.get_segm_by_name(".rdata").start_ea
     self.nb_custom_modules = idaapi.get_dword(self.module_header_struct + \
                              dotnet_versions_offsets[self.dotnet_version]\
                              ["nbCustomModules"])
Пример #6
0
def search_ea(sig, segment="", callback=None):
    eas = []
    if segment != "":
        seg = idaapi.get_segm_by_name(segment)
        if not seg:
            return
        ea, maxea = seg.startEA, seg.endEA
        count = 0
        while ea != idaapi.BADADDR:
            ea = idaapi.find_binary(ea, maxea, sig, 16, idaapi.SEARCH_DOWN)
            if ea != idaapi.BADADDR:
                count = count + 1
                if callback != None:
                    callback(ea)
                else:
                    eas.append(ea)
                ea += 2
    else:
        for seg in Segments():
            ea = SegStart(seg)
            maxea = SegEnd(ea)
            count = 0
            while ea != idaapi.BADADDR:
                ea = idaapi.find_binary(ea, maxea, sig, 16, idaapi.SEARCH_DOWN)
                if ea != idaapi.BADADDR:
                    count = count + 1
                    if callback != None:
                        callback(ea)
                    else:
                        eas.append(ea)
                    ea += 2
    return eas
Пример #7
0
    def __init__(self, ea=UseCurrentAddress, name=None, index=None):
        """Wrapper around IDA segments.

        There are 3 ways to get a segment - by name, ea or index. Only use one.

        Args:
            ea - address in the segment
            name - name of the segment
            index - index of the segment
        """
        if sum((ea not in (self.UseCurrentAddress, None), name is not None, index is not None,)) > 1:
            raise ValueError(
                "Expected only one (ea, name or index). Got (ea={!r}, name={!r}, index={!r})".format(ea, name, index))

        elif name is not None:
            seg = idaapi.get_segm_by_name(name)

        elif index is not None:
            seg = idaapi.getnseg(index)

        elif ea == self.UseCurrentAddress:
            seg = idaapi.getseg(idc.here())

        elif ea is None:
            raise ValueError("`None` is not a valid address. To use the current screen ea, "
                             "use `Function(ea=Function.UseCurrentAddress)` or supply no `ea`.")

        else:
            seg = idaapi.getseg(ea)

        self._segment = seg
def find_tablegroups(segname=".data"):
    '''
    Returns a list of (start, end) ea pairs for the
    vtable groups in 'segname'
    '''

    # 设置计数的返回值
    # count = 0

    seg = idaapi.get_segm_by_name(segname)
    ea = seg.startEA
    vtbs = []
    # print hex(seg.endEA)
    while ea < seg.endEA:
        # 记录之前ea的值
        prev_ea = ea
        ea, ptr = read_ea(ea)
        if ptr == 0:
            continue
        # 检测是否为方法
        if isFunction(ptr):
            # print hex(ea)
            # 如果是off开头,则可以确认为虚表
            # if is_vtb_begin(prev_ea):
            ea, vtb = store_segVtb(prev_ea)
            # 空的列表则不添加
            if vtb.get('vtb_func_lists') == []:
                continue
            vtbs.append(vtb)
        # count = count + 1
        # if count==4:
        #     break

    # pprint(vtbs)
    return vtbs
Пример #9
0
    def segment_bytes(self, val):
        """
        Will obtain segment bytes for the segment in which EA is contained or by segment name.  This will be on demand 
        and segment bytes will be cached if they have not already been obtained
        
        :param string|int val: either the name of a segment or an EA within a segment
        
        :return string: bytes which are contained with the segment
        """
        if isinstance(val, str):
            seg_start = idaapi.get_segm_by_name(val).startEA
            if seg_start is None:
                raise AssertionError(
                    "could not find segment for {}".format(val))

        elif isinstance(val, numbers.Number):
            seg_start = idc.GetSegmentAttr(val, idc.SEGATTR_START)

        seg_bytes = self.segments.get(seg_start)
        if seg_bytes is None:
            seg_end = idc.GetSegmentAttr(seg_start, idc.SEGATTR_END)
            seg_bytes = self._get_segment_bytes(seg_start, seg_end)
            self.segments[seg_start] = seg_bytes

        return seg_bytes
Пример #10
0
def by_name(name):
    '''Return the segment with the given `name`.'''
    res = utils.string.to(name)
    seg = idaapi.get_segm_by_name(res)
    if seg is None:
        raise E.SegmentNotFoundError(u"{:s}.by_name({!r}) : Unable to locate the segment with the specified name.".format(__name__, name))
    return seg
def main():
    global cfgTree
    cfgTree = CFGTree()

    seg = idaapi.get_segm_by_name("__text")

    # Loop from segment start to end
    func_ea = seg.startEA

    # Get a function at the start of the segment (if any)
    func = idaapi.get_func(func_ea)
    if func is None:
        # No function there, try to get the next one
        func = idaapi.get_next_func(func_ea)

    seg_start = seg.startEA
    seg_end = seg.end_ea
    while func is not None and func.start_ea < seg_end:
        funcea = func.start_ea
        fflags = idc.get_func_flags(funcea)
        if (fflags & idc.FUNC_LIB) or (fflags & idc.FUNC_THUNK):
            continue

        # print("Function %s at 0x%x" % (idc.get_func_name(funcea), funcea))
        flow = idaapi.FlowChart(idaapi.get_func(funcea), flags=idaapi.FC_PREDS)
        construct_cfg(flow, funcea, seg_start, seg_end)
        func = idaapi.get_next_func(funcea)
    cfgTree.print_deepest_path()
Пример #12
0
def renamer_init():
    renamed = 0

    gopclntab = idaapi.get_segm_by_name('.gopclntab')
    if gopclntab is not None:
        # Skip unimportant header and goto section size
        addr = gopclntab.startEA + 8
        size, addr_size = create_pointer(addr)
        addr += addr_size

        # Unsure if this end is correct
        early_end = addr + (size * addr_size * 2)
        while addr < early_end:
            func_offset, addr_size = create_pointer(addr)
            name_offset, addr_size = create_pointer(addr + addr_size)
            addr += addr_size * 2

            func_name_addr = Dword(name_offset + gopclntab.startEA +
                                   addr_size) + gopclntab.startEA
            func_name = GetString(func_name_addr)
            MakeStr(func_name_addr, func_name_addr + len(func_name))
            appended = clean_func_name = clean_function_name(func_name)
            debug(
                'Going to remap function at 0x%x with %s - cleaned up as %s' %
                (func_offset, func_name, clean_func_name))

            if idaapi.get_func_name(func_offset) is not None:
                if MakeName(func_offset, clean_func_name):
                    renamed += 1
                else:
                    error('clean_func_name error %s' % clean_func_name)

    return renamed
Пример #13
0
def find_func_by_name(name):
    text_seg = idaapi.get_segm_by_name('.text')

    for addr in Functions(text_seg.startEA, text_seg.endEA):
        if name == idaapi.get_func_name(addr):
            return idaapi.get_func(addr)

    return None
Пример #14
0
def get_seg(seg_names):
    seg = None
    for seg_name in seg_names:
        seg = idaapi.get_segm_by_name(seg_name)
        if seg:
            return seg

    return seg
Пример #15
0
def _get_seg(possible_seg_names):
    seg = None
    for seg_name in possible_seg_names:
        seg = idaapi.get_segm_by_name(seg_name)
        if seg:
            return seg

    return seg
Пример #16
0
def by_name(name):
    '''Return the segment with the given `name`.'''
    s = idaapi.get_segm_by_name(name)
    if s is None:
        raise E.SegmentNotFoundError(
            "{:s}.by_name({!r}) : Unable to locate the segment with the specified name."
            .format(__name__, name))
    return s
Пример #17
0
 def check_if_segm_exists(self):
   segm = idaapi.get_segm_by_name(self.config.entropy['segm_name'])
   if segm:
     self.config.entropy['segm_exists'] = True
     self.config.entropy['segm_addr']   = segm.start_ea
   else:
     self.config.entropy['segm_exists'] = False
     self.config.entropy['segm_addr']   = None
Пример #18
0
def stringRecoveryB():

    #for exe
    _rodata_name = "_rodata"
    if not idaapi.get_segm_by_name(".rodata"):
        _rodata_name = "_rdata"

    userfunc = getUserFunctions(False)
    for func in userfunc:
        addr_list = []
        inst = func
        while inst < find_func_end(func):
            addr_list += [inst]
            inst = find_code(inst, SEARCH_DOWN)
        for i in range(len(addr_list) - 2):
            if print_insn_mnem(addr_list[i]) == "lea" and print_insn_mnem(
                    addr_list[i + 1]) == "mov" and print_insn_mnem(
                        addr_list[i + 2]) == "mov":
                if "qword ptr [" in print_operand(
                        addr_list[i + 1],
                        0) and "qword ptr [" in print_operand(
                            addr_list[i + 2], 0):
                    if get_operand_value(addr_list[i + 2],
                                         0) - get_operand_value(
                                             addr_list[i + 1], 0) == 8:
                        Addr = get_operand_value(addr_list[i], 1)
                        Len = get_operand_value(addr_list[i + 2], 1)
                        seg_name = idaapi.get_visible_segm_name(
                            idaapi.getseg(Addr))
                        if seg_name == _rodata_name:
                            if get_wide_byte(Addr + Len) != 0:
                                MyMakeStr(Addr, Len)
                                #print hex(Addr), Len
                elif print_operand(addr_list[i + 1],
                                   0) == "eax" and print_operand(
                                       addr_list[i + 2], 1) == "eax":
                    Addr = get_operand_value(addr_list[i], 1)
                    Len = get_operand_value(addr_list[i + 1], 1)
                    seg_name = idaapi.get_visible_segm_name(
                        idaapi.getseg(Addr))
                    if seg_name == _rodata_name:
                        if get_wide_byte(Addr + Len) == 0:
                            Len += 1
                        MyMakeStr(Addr, Len)
                        #print hex(addr_list[i]), hex(Addr), Len
            if print_insn_mnem(addr_list[i]) == "lea":
                if "ref_" in print_operand(addr_list[i],
                                           1) or "off_" in print_operand(
                                               addr_list[i], 1):
                    Addr = get_operand_value(addr_list[i], 1)
                    seg_name = idaapi.get_visible_segm_name(
                        idaapi.getseg(Addr))
                    if seg_name == _rodata_name or seg_name == "_data_rel_ro":
                        Len = get_qword(Addr + 8)
                        Cmt = get_string(get_qword(Addr), Len)
                        if Cmt != "":
                            #print hex(addr_list[i]),Len,get_string(get_qword(Addr),Len)
                            MakeRptCmt(addr_list[i], Cmt)
Пример #19
0
def find_segment(seg_name):
    text_segment = idaapi.get_segm_by_name(seg_name).start_ea
    if text_segment == BADADDR:
        text_segment = FirstSeg()
    
    if text_segment == BADADDR:
        return BADADDR
    
    return text_segment
Пример #20
0
def go_buildid():
    # TODO: work only for windows
    textstart = idaapi.get_segm_by_name(".text").startEA
    buildid = GetManyBytes(textstart, 0x3c)
    if buildid.startswith("\xff Go build ID: \""):
        MakeStr(textstart, textstart + 0x3c)
        return buildid[1:-1]
    else:
        return None
def set_hypercalls_name():
    global g_TableEntrySize

    StartAddress = idaapi.get_segm_by_name(
        "CONST"
    ).start_ea  # usually start of CONST segment, but it will can change in future
    print("Address of HvCallTable is ", hex(StartAddress))

    hvCallCount = get_hypercall_count(StartAddress)

    hv_table_count = len(g_hvcalls_dict)

    if hvCallCount > len(g_hvcalls_dict):
        print(
            "Warning! Hypercall's count is more then size of table with list of known hypercalls. Some hypercalls will be undefined. "
        )

    add_hypercall_stats_enum(hvCallCount)
    check_hvix_os_version(hvCallCount)

    idc.set_name(StartAddress, str('HvCallTable'), SN_NOWARN)

    # Working with first element manually

    HvCallReserved00 = idc.get_qword(StartAddress)
    ida_bytes.del_items(HvCallReserved00, 0, 1)
    idc.create_insn(HvCallReserved00)
    idc.add_func(HvCallReserved00)
    idc.set_name(HvCallReserved00, str('HvCallReserved00'), SN_NOWARN)
    for j in range(0, 6):
        idc.create_data(StartAddress + 8 + j * 2, FF_WORD, 2,
                        ida_idaapi.BADADDR)
    j = j + 1
    idc.create_data(StartAddress + 8 + j * 2, FF_DWORD, 4, ida_idaapi.BADADDR)
    idc.op_enum(StartAddress + 8 + j * 2, 0, g_hv_stats, 0)

    # Next elements
    for i in range(1, hvCallCount + 1):
        hvCallAddress = idc.get_qword(StartAddress + i * g_TableEntrySize)

        if hvCallAddress != HvCallReserved00:
            idc.create_insn(hvCallAddress)
            idc.add_func(hvCallAddress)
            if i < hv_table_count:
                idc.set_name(hvCallAddress, g_hvcalls_dict[i], SN_NOWARN)
            else:
                hvcall_name = "HvCallUknown" + hex(i)
                idc.set_name(hvCallAddress, hvcall_name, SN_NOWARN)
        for j in range(0, 6):
            dw_addr = idc.create_data(
                StartAddress + i * g_TableEntrySize + 8 + j * 2, FF_WORD, 2,
                ida_idaapi.BADADDR)
        j = j + 1
        idc.create_data(StartAddress + i * g_TableEntrySize + 8 + j * 2,
                        FF_DWORD, 4, ida_idaapi.BADADDR)
        idc.op_enum(StartAddress + i * g_TableEntrySize + 8 + j * 2, 0,
                    g_hv_stats, 0)
Пример #22
0
 def seg_by_name(self, name):
     ida_seg = idaapi.get_segm_by_name(name)
     if ida_seg is None:
         return None
     perms = 0
     perms |= SEG_PROT_R if ida_seg.perm & idaapi.SEGPERM_READ else 0
     perms |= SEG_PROT_W if ida_seg.perm & idaapi.SEGPERM_WRITE else 0
     perms |= SEG_PROT_X if ida_seg.perm & idaapi.SEGPERM_EXEC else 0
     return self.angrdbg_mod.Segment(name, ida_seg.start_ea, ida_seg.end_ea, perms)
Пример #23
0
 def get_idata(self): #return tuple(start_addr, end_addr)
     ida_seg = idaapi.get_segm_by_name(".idata")
     if ida_seg is None:
         addr = None
         def cb(ea, name, i):
             addr = ea
         idaapi.enum_import_names(0, cb)
         ida_seg = idaapi.seg_by_addr(addr)
     return (ida_seg.start_ea, ida_seg.end_ea)
def by_name(name):
    '''Return the segment with the given `name`.'''
    res = utils.string.to(name)
    seg = idaapi.get_segm_by_name(res)
    if seg is None:
        raise E.SegmentNotFoundError(
            u"{:s}.by_name({!r}) : Unable to locate the segment with the specified name."
            .format(__name__, name))
    return seg
Пример #25
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
Пример #26
0
def find_sig(segment, sig, callback):
    seg = idaapi.get_segm_by_name(segment)
    if not seg:
        return
    ea, maxea = seg.start_ea, seg.end_ea
    while ea != idaapi.BADADDR:
        ea = idaapi.find_binary(ea, maxea, sig, 16, idaapi.SEARCH_DOWN)
        if ea != idaapi.BADADDR:
            callback(ea)
            ea += 4
Пример #27
0
 def get_heap_base(self, address=None):
     if not address:
         segm = idaapi.get_segm_by_name("[heap]")  # same as mp_->sbrk_base
         if segm:
             return segm.start_ea
     else:
         heap_addr = self.heap_for_ptr(address)
         heap_addr = heap_addr + sizeof(self.heap_info_s) + sizeof(
             self.malloc_state_s)
         return round_up(heap_addr, self.malloc_alignment)
     return None
Пример #28
0
	def find_gopclntab(self):
		found = False
		try:
			ea = idaapi.get_segm_by_name(".gopclntab").startEA
			found = True
		except:
			ea = MinEA()
			ea = FindBinary(ea, SEARCH_DOWN, self.header)
			if ea!=0xffffffffffffffff:
				found = True
		return (found, ea)
Пример #29
0
def find_1337babes():
	res = []
	ea = idaapi.get_segm_by_name('.text').startEA
	while True:
		found_addr = FindBinary(ea, SEARCH_NEXT|SEARCH_DOWN, "BE BA 37 13")
		if found_addr != 0xFFFFFFFFFFFFFFFF:
			res.append(found_addr)
			ea = found_addr
		else:
			break
  	return res
Пример #30
0
    def __init__(self):
        self.text = get_segm_by_name(".text")
        self.data = get_segm_by_name(".data")
        self.rdata = get_segm_by_name(".rdata")
        # try to use rdata if there actually is an rdata segment, otherwise just use data
        if self.rdata is not None:
            self.valid_ranges = [(self.rdata.startEA, self.rdata.endEA), (self.data.startEA, self.data.endEA)]
        else:
            self.valid_ranges = [(self.data.startEA, self.data.endEA)]

#        self.x64 = (idaapi.getseg(here()).bitness == 2)
#        if self.x64:
#            self.PTR_TYPE = FF_QWRD
#            self.REF_OFF = REF_OFF64
#            self.PTR_SIZE = 8
#            self.get_ptr = get_64bit
#        else:
        self.PTR_TYPE = FF_DWRD
        self.REF_OFF = REF_OFF32
        self.PTR_SIZE = 4
        self.get_ptr = get_32bit
Пример #31
0
    def _lookup_segments(self):
        """
        Looks up __TEXT:__cstring, __TEXT:__text, __DATA:__const
        """

        self.cstring_seg = get_segm_by_name(CSTRING_SEGNAME)
        if type(self.cstring_seg) == type(None):
            print "[!] Error looking up %s" % CSTRING_SEGNAME
            return False

        self.text_seg = get_segm_by_name(TEXT_SEGNAME)
        if type(self.text_seg) == type(None):
            print "[!] Error looking up %s" % TEXT_SEGNAME
            return False

        self.data_seg = get_segm_by_name(DATA_SEGNAME)
        if type(self.data_seg) == type(None):
            print "[!] Error looking up %s" % DATA_SEGNAME
            return False

        return True
Пример #32
0
def relocate_bootblock():
	bootblk_start = 0xF000 << 4
	bootblk_end = 0x10000 << 4
	bootblk_baseparagraph = 0xF000
	bootblk_size = 0x10000 # 64 Kbyte

	idaapi.add_segm(bootblk_baseparagraph, bootblk_start, bootblk_end, "BOOTBLK", "CODE")
	bootblk = idaapi.get_segm_by_name("BOOTBLK")
	idaapi.set_segm_addressing(bootblk, 16)
	bootblk_addr = get_bootblock_start_address()
	print("Found bootblock at {0} addr!".format(hex(bootblk_addr)))
	relocate_segment(bootblk_addr, bootblk_start, bootblk_size)
Пример #33
0
def obtain_segment_data(segname):
    """
    Given a segment name, return the bytes within the segment.

    :param segname: Name of the segment

    :return: Data from the specified segment.
    """
    seg = idaapi.get_segm_by_name(segname)
    if seg:
        return _read_bytes(seg.startEA, seg.endEA)
    return None
Пример #34
0
def find_section(name):
    sec = idaapi.get_segm_by_name(name)

    S = 0
    E = 0

    if sec is not None:
        S = sec.startEA
        E = sec.endEA
        print "found %s (%x - %x)" % (name, S, E)

    return S, E
    def _lookup_segments(self):
        """
        Looks up __TEXT:__cstring, __TEXT:__text, __DATA:__const
        """

        self.cstring_seg = get_segm_by_name(CSTRING_SEGNAME)
        if type(self.cstring_seg) == type(None):
            print "[!] Error looking up %s" % CSTRING_SEGNAME
            return False

        self.text_seg = get_segm_by_name(TEXT_SEGNAME)
        if type(self.text_seg) == type(None):
            print "[!] Error looking up %s" % TEXT_SEGNAME
            return False

        self.data_seg = get_segm_by_name(DATA_SEGNAME)
        if type(self.data_seg) == type(None):
            print "[!] Error looking up %s" % DATA_SEGNAME
            return False

        return True
Пример #36
0
def strings_init():
    strings_added = 0
    retry = []
    text_seg = idaapi.get_segm_by_name('.text')

    # This may be inherently flawed as it will only search for defined functions
    # and as of IDA Pro 6.95 it fails to autoanalyze many GO functions, currently
    # this works well since we redefine/find (almost) all the functions prior to
    # this being used. Could be worth a strategy rethink later one or on diff archs
    for addr in Functions(text_seg.startEA, text_seg.endEA):
        name = GetFunctionName(addr)

        end_addr = Chunks(addr).next()[1]
        if (end_addr < addr):
            error('Unable to find good end for the function %s' % name)
            pass

        debug('Found function %s starting/ending @ 0x%x 0x%x' %
              (name, addr, end_addr))

        while addr <= end_addr:
            if is_string_load(addr):
                if 'rodata' not in idaapi.get_segm_name(
                        addr) and 'text' not in idaapi.get_segm_name(addr):
                    debug('Should a string be in the %s section?' %
                          idaapi.get_segm_name(addr))
                string_addr = GetOperandValue(addr, 1)
                addr_3 = FindCode(FindCode(addr, SEARCH_DOWN), SEARCH_DOWN)
                string_len = GetOperandValue(addr_3, 1)
                if create_string(string_addr, string_len):
                    if create_offset(addr):
                        strings_added += 1
                else:
                    # There appears to be something odd that goes on with IDA making some strings, always works
                    # the second time, so lets just force a retry...
                    retry.append((addr, string_addr, string_len))

                # Skip the extra mov lines since we know it won't be a load on any of them
                addr = FindCode(addr_3, SEARCH_DOWN)
            else:
                addr = FindCode(addr, SEARCH_DOWN)

    for instr_addr, string_addr, string_len in retry:
        if create_string(string_addr, string_len):
            if create_offset(instr_addr):
                strings_added += 1
        else:
            error(
                'Unable to make a string @ 0x%x with length of %d for usage in function @ 0x%x'
                % (string_addr, string_len, instr_addr))

    return strings_added
Пример #37
0
def rebuild_functions_from_prologues():
    segm = idaapi.get_segm_by_name("__text")
    seg_start = segm.startEA
    seg_end = segm.endEA
    print ("Segment Address : 0x%08x-0x%08x"%(seg_start, seg_end))
    cursor = seg_start
    while cursor < seg_end:
        #print ("Cursor Offset : 0x%08x"%cursor)
        #cursor = idaapi.find_not_func(cursor, 0x1)
        #print Byte(cursor)
        if (Byte(cursor) == 0x55 and Byte(cursor+1) == 0x48 and Byte(cursor+2) == 0x89):
            idc.MakeFunction(cursor)
        cursor += 1
Пример #38
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
Пример #39
0
    def activate(self, ctx):
        print 'Starting Swift demangling'

        seg = idaapi.get_segm_by_name('.plt');
        # if seg == None:
        #     print 'Segment .plt was not found, exiting'
        #     return

        count = 0
        for funcea in Functions(seg.startEA, seg.endEA):
            func_name = GetFunctionName(funcea)[1:]
            demangled_output = self.demangle(func_name).split(' ---> ')

            name = demangled_output[0].strip()
            demangled_name = demangled_output[1].strip()

            if name == demangled_name:
                continue

            count += 1
            self.comment_xrefs(funcea, demangled_name)

        print 'Successfully demangled %d functions' % count
Пример #40
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))
Пример #41
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
Пример #42
0
def byName(name):
    '''Return the segment_t with the given /name/'''
    s = idaapi.get_segm_by_name(name)
    if s is None:
        raise Exception, "segment.byName(%r):unable to locate segment"% name
    return s
Пример #43
0
def test_read(ea):
	args = walk_stack(ea, 3)
	arg_dict = {}
	for x in args:
		arg_dict[x[1]] = trace_arg(x[0])
	arg_dict['nbytes'] = hex2int(arg_dict['nbytes'])
	arg_dict['buf'] = calculate_buffer_size(arg_dict['buf'])

	if arg_dict['buf'] < arg_dict['nbytes']:
		return True, hex(ea), arg_dict
	else:
		return False, hex(ea), arg_dict


### Populate BSS <Hail Chris Eagle>
start = idaapi.get_segm_by_name(".bss").startEA
end = idaapi.get_segm_by_name(".bss").endEA
item = idc.NextHead(start - 1, end)
bss = {}
while item != BADADDR:
   next = idc.NextHead(item, end)
   if next != BADADDR:
      bss[idc.Name(item)] = next - item
   else:
      bss[idc.Name(item)] = end - item
   item = next

### Populate Functions
functions = {}
for x in idautils.Functions():
    functions[idc.GetFunctionName(x)] = x
Пример #44
0
        # 8A 89 B0 D5 04 10  mov     cl, key[ecx]
        #       ^ key offset
        key_offset = struct.unpack("<I", idaapi.get_many_bytes(addr + 2, 4))[0]
    elif idaapi.get_many_bytes(addr, 1) == "\x6B":
        # 6B C2 33                   imul    eax, edx, 51
        #       ^ key length
        key_len = idaapi.get_byte(addr + 2)
    elif idaapi.get_many_bytes(addr, 3) == "\x8B\x04\xDD":
        # 8B 04 DD C0 DE 06 10       mov     eax, packed_strings_list[ebx*8]
        #          ^ address of string list
        struct_base = struct.unpack("<I", idaapi.get_many_bytes(addr + 3, 4))[0]

print "[*] Decoding function : 0x{:08x}".format(int(decoding_func.startEA))
print "[*] Encoded string list base : 0x{:08x}".format(struct_base)

data_seg = idaapi.get_segm_by_name(".data")
xor_key = idaapi.get_many_bytes(key_offset, key_len)
index = 0

while True:
    addr = struct_base + index * 8
    data_ptr, size = struct.unpack("<II", idaapi.get_many_bytes(addr, 8))

    if data_ptr < data_seg.startEA or data_ptr > data_seg.endEA:
        # We don't know how many strings there are so we stop when the pointer
        # to the data doesn't make sense.
        break

    data = idaapi.get_many_bytes(data_ptr, size)
    decrypted_string = "".join(
        [chr(ord(data[i]) ^ ord(xor_key[i % len(xor_key)])) for i in range(size)]