def getXRefsTo(self):
        """
        Computes a list of the names of the xrefs to the function.
        This includes all functions that call this, but also data xrefs.
        :returns: a tuple of two lists: crefs and drefs
        """
        # type: () -> (list[int], list[int])
        crefs = []
        drefs = []
        # If the current address is function process it
        if idc.get_func_flags(self.func_ea) != -1:
            # Find all code references to func
            ref = idc.get_first_cref_to(self.func_ea)
            while ref != idaapi.BADADDR:
                # name = get_func_name(ref)
                # if not name: name = "ROM:%08X" % ref
                crefs.append(ref)
                ref = idaapi.get_next_cref_to(self.func_ea, ref)
            # Find all data references to func
            for ref in idautils.DataRefsTo(self.func_ea):
                drefs.append(ref)
            for ref in idautils.DataRefsTo(self.func_ea + 1):
                drefs.append(ref)

            return crefs, drefs
예제 #2
0
    def getXRefsTo(self):
        """
        Computes a list of the names of the xrefs to the data item and updates the xrefsto computed
        parameter.
        This includes all functions calls/branches, but also data xrefs such as LDR/STR and data (DCDs, DCBs..)
        there is also the weird case that a labelless asm line has a cref to the last asm line.
        :returns: a tuple of two lists: crefs and drefs
        """
        # type: () -> (list[int], list[int])
        crefs = []
        drefs = []

        # Find all code references to item
        ref = idc.get_first_cref_to(self.ea)
        while ref != idaapi.BADADDR:
            crefs.append(ref)
            ref = idaapi.get_next_cref_to(self.ea, ref)

        # Find all data references to item
        for ref in idautils.DataRefsTo(self.ea):
            drefs.append(ref)
        for ref in idautils.DataRefsTo(
                self.ea - 1):  # needed in case this is a code item
            drefs.append(ref)

        return (crefs, drefs)
예제 #3
0
def find_game_init():
    strings = idautils.Strings()
    
    taint_ea = None
    
    # Find the string which is referenced only in CGameUI::Initialize
    for i in strings:
        if taint_ea is None and str(i) == 'Whether taint logging is enabled':
            taint_ea = i.ea
            break
            
    if taint_ea is None:
        raise RuntimeError('Unable to find CGGameUI::Initialize (1)')
        
    refs = list(idautils.DataRefsTo(taint_ea))
    
    if len(refs) != 1:
        raise RuntimeError('Unable to find CGGameUI::Initialize (2)')
    
    func_start = find_func_containing(refs[0])
    func_name = idc.get_func_name(func_start)
    
    mangled_name = '__ZN8CGGameUI10InitializeEv'
    
    if func_name != mangled_name:
        idc.set_name(func_start, mangled_name, SN_CHECK)

    print('CGGameUI::Initialize:  0x%x ' % func_start)
        
    return func_start
예제 #4
0
    def Anayl_Func_Call(self, func_name, para_num):
        if func_name == "":
            return
        segkind = ['.text', '.init', '.plt']
        startaddr = MinEA()
        while True:
            fun_addr = FindText(startaddr, SEARCH_DOWN, 0, 0, str(func_name))
            if not (SegName(fun_addr)) in segkind:
                break
            startaddr = NextHead(fun_addr)

        print 'find pattern string addr', hex(fun_addr)

        call_addrs = idautils.DataRefsTo(fun_addr)
        dic = {}
        for item in call_addrs:
            if (not isCode(GetFlags(item))):
                continue
            CALL_ADDR = item
            while (not ua_mnem(CALL_ADDR) == 'BL'):
                CALL_ADDR = NextHead(CALL_ADDR)
            CALL_ADDR = PrevHead(CALL_ADDR)
            para = self.BackForward(CALL_ADDR, para_num)
            xref_funname = GetFunctionName(CALL_ADDR)
            dic[xref_funname] = para
        return dic
예제 #5
0
def fromDataToFunc(ea, deep):
    if deep > 5:
        print('No Xref function is found ' + hex(ea))
        return []
    funcs = []
    refs = idautils.DataRefsTo(ea)
    for r in refs:
        if idc.get_segm_name(r) == '.text':
            funcs.append(idc.get_func_attr(r, idc.FUNCATTR_START))
        elif idc.get_segm_name(r) == '.data' or idc.get_segm_name(r) == '.bss':
            # orign = r
            # r = r-1
            cnt = 1
            while not idc.get_name(r):
                r -= 1
                cnt += 1
                if cnt > 100:
                    print('cannot find a real label in .data' + hex(ea))
                    break
            if cnt < 100:
                funcs = funcs + fromDataToFunc(r, deep + 1)
        else:
            print("Ref in Seg {} at Addr {}".format(idc.get_segm_name(r), r))

    if not funcs:
        print('No Xref function is found ' + hex(ea))
    return funcs
예제 #6
0
def find_exported_eas():
    """Find the address of all exported functions. Exported functions are
  entrypoints into this program that external code can execute."""
    exported_eas = set()
    for index, ordinal, ea, name in idautils.Entries():

        # Not sure how this happens, but IDA seemed to treat
        # `obstack_alloc_failed_handler` in `call cs:[obstack_alloc_failed_handler]`
        # as an entrypoint.
        num_data_refs = len(tuple(idautils.DataRefsTo(ea)))
        num_code_refs = len(tuple(idautils.CodeRefsTo(ea, True)))
        num_code_refs += len(tuple(idautils.CodeRefsTo(ea, True)))
        if num_data_refs and not num_code_refs:
            log.warning(
                "Ignoring entrypoint {:08x}, it's only referenced by data".
                format(ea))
            continue

        if not has_segment_type(ea, idc.SEG_CODE):
            log.warning(
                "Ignoring entrypoint {:08x}, it is not in a code segment".
                format(ea))
            continue

        if not idc.hasName(ea):
            old_name = name
            if name.startswith("."):
                name = idc.GetCommentEx(ea, 0)

            log.info("Renaming `{}` at {:08x} to `{}`".format(
                old_name, ea, name))
            idc.MakeName(ea, name)

    return exported_eas
예제 #7
0
 def __PltResolver(jmprel, strtab, symtab):
     idx = 0
     while True:
         r_off = idc.Qword(jmprel + 0x18 * idx)
         r_info1 = idc.Dword(jmprel + 0x18 * idx + 0x8)
         r_info2 = idc.Dword(jmprel + 0x18 * idx + 0xc)
         r_addend = idc.Qword(jmprel + 0x18 * idx + 0x10)
         if r_off > 0x7fffffff:
             return
         if r_info1 == 7:
             st_name = idc.Dword(symtab + r_info2 * 0x18)
             name = idc.GetString(strtab + st_name)
             # rename got
             idc.set_name(r_off, name + '_ptr')
             plt_func = idc.Qword(r_off)
             # rename plt
             idc.set_name(plt_func, 'j_' + name)
             SetFuncFlags(plt_func)
             # rename plt.sec
             for addr in idautils.DataRefsTo(
                     r_off):  # 新版本gcc中got表的ref只在.plt.sec段出现
                 plt_sec_func = idaapi.get_func(addr).startEA
                 idc.set_name(plt_sec_func,
                              '_' + name)  # 其实重点是.plt.sec设置为 _xxx 即可正常解析
                 ParseTypes(plt_sec_func)
                 SetFuncFlags(plt_sec_func)
         idx += 1
예제 #8
0
def find_xrefs(addr):
  lrefs = list(idautils.DataRefsTo(addr))
  if len(lrefs) == 0:
    lrefs = list(idautils.refs(addr, first, next))

  lrefs = [r for r in lrefs if not idc.isCode(idc.GetFlags(r))]
  return lrefs
예제 #9
0
	def __PltResolver(jmprel,strtab,symtab):
		idx=0
		while True:
			r_off = idc.Qword(jmprel+0x18*idx)
			r_info1 = idc.Dword(jmprel+0x18*idx+0x8)
			r_info2 = idc.Dword(jmprel+0x18*idx+0xc)
			r_addend = idc.Qword(jmprel+0x18*idx+0x10)
			if r_off > 0x7fffffff:
				return
			if r_info1 == 7:
				st_name = idc.Dword(symtab+r_info2*0x18)
				name = idc.GetString(strtab+st_name)
				# rename got
				idc.set_name(r_off,name+'_ptr')
				plt_func = idc.Qword(r_off)
				# rename plt
				idc.set_name(plt_func,'j_'+name)
				SetFuncFlags(plt_func)
				# rename plt.sec
				for addr in idautils.DataRefsTo(r_off):
					plt_sec_func = idaapi.get_func(addr)
					if plt_sec_func:
						plt_sec_func_addr = plt_sec_func.startEA
						idc.set_name(plt_sec_func_addr,'_'+name)
						SetFuncFlags(plt_sec_func_addr)
					else:
						print "[!] idaapi.get_func({}) failed".format(hex(addr))
			idx+=1
예제 #10
0
 def __PltResolver(jmprel, strtab, symtab):
     idx = 0
     while True:
         r_off = idc.get_qword(jmprel + 0x18 * idx)
         r_info1 = idc.get_wide_dword(jmprel + 0x18 * idx + 0x8)
         r_info2 = idc.get_wide_dword(jmprel + 0x18 * idx + 0xc)
         r_addend = idc.get_qword(jmprel + 0x18 * idx + 0x10)
         if r_off > 0x7fffffff:
             return
         if r_info1 == 7:
             st_name = idc.get_wide_dword(symtab + r_info2 * 0x18)
             name = idc.get_strlit_contents(strtab + st_name)
             # rename got
             idc.set_name(r_off, name.decode("ascii") + '_ptr')
             plt_func = idc.get_qword(r_off)
             if debug_mode:
                 print(hex(plt_func.start_ea), name)
             # rename plt
             idc.set_name(plt_func, 'j_' + name.decode("ascii"))
             SetFuncFlags(plt_func)
             # rename plt.sec
             for addr in idautils.DataRefsTo(r_off):
                 plt_sec_func = idaapi.get_func(addr)
                 if plt_sec_func:
                     plt_sec_func_addr = plt_sec_func.start_ea
                     idc.set_name(plt_sec_func_addr,
                                  '_' + name.decode("ascii"))
                     SetFuncFlags(plt_sec_func_addr)
                 else:
                     print("[!] idaapi.get_func({}) failed".format(
                         hex(addr)))
         idx += 1
예제 #11
0
def instruction_is_referenced(ea):
    """Returns `True` if it appears that there's a non-fall-through reference
  to the instruction at `ea`."""
    global POSSIBLE_CODE_REFS
    if len(tuple(idautils.CodeRefsTo(ea, False))):
        return True
    if len(tuple(idautils.DataRefsTo(ea))):
        return True
    return ea in POSSIBLE_CODE_REFS
예제 #12
0
def idautils_getdatarefs_to():
    """
  IDA GUI: Right click on any address and click List Cross-references to. This is just a list of all those locations in all segments that refer to this address.
           The only ones that matter for this API are the ones NOT in the .text segment.
           While this code will work, it makes more sense to iterate over an entire function and check every location for Cross references.
  """

    print "Getting all data references to a specific address"
    datarefs = idautils.DataRefsTo(0x000000004A6811E0)
    for ref in datarefs:
        print str(ref) + ':' + str(hex(ref))
예제 #13
0
 def __PltResolver(jmprel, strtab, symtab, pltgot):
     seg_sec = idc.selector_by_name('.plt.sec')
     sec_start = idc.get_segm_by_sel(seg_sec)
     sec_end = idc.get_segm_end(sec_start)
     if sec_start == idaapi.BADADDR:
         print("[-] can't find .plt.sec segment")
         return
     idx = 0
     while True:
         r_off = idc.get_wide_dword(jmprel + 0x8 * idx)
         r_info1 = idc.get_wide_byte(jmprel + 0x8 * idx + 0x4)
         r_info2 = idc.get_wide_byte(jmprel + 0x8 * idx + 0x5)
         if r_off > 0x7fffffff:
             return
         if r_info1 == 7:
             st_name = idc.get_wide_dword(symtab + r_info2 * 0x10)
             name = idc.get_strlit_contents(strtab + st_name)
             # rename got
             idc.set_name(r_off, name.decode("ascii") + '_ptr')
             plt_func = idc.get_wide_dword(r_off)
             # rename plt
             idc.set_name(plt_func, 'j_' + name.decode("ascii"))
             SetFuncFlags(plt_func)
             # rename plt.sec
             for addr in idautils.DataRefsTo(r_off):
                 plt_sec_func = idaapi.get_func(addr)
                 if plt_sec_func:
                     plt_sec_func_addr = plt_sec_func.start_ea
                     idc.set_name(plt_sec_func_addr,
                                  '_' + name.decode("ascii"))
                     SetFuncFlags(plt_sec_func_addr)
                 else:
                     print("[!] idaapi.get_func({}) failed".format(
                         hex(addr)))
             got_off = r_off - pltgot
             target = '+{}h'.format(
                 hex(got_off).lower().replace('0x',
                                              '').replace('l',
                                                          '').rjust(2, '0'))
             for func_ea in idautils.Functions(sec_start, sec_end):
                 func = idaapi.get_func(func_ea)
                 cur = func.start_ea
                 end = func.endEA
                 find = False
                 while cur <= end:
                     code = idc.GetDisasm(cur).lower().replace(' ', '')
                     if target in code:
                         find = True
                         break
                     cur = idc.NextHead(cur, end)
                 if find:
                     idc.set_name(func_ea, '_' + name)
                     SetFuncFlags(func_ea)
         idx += 1
 def generate_refs(self):
     for start, end in self.non_init_segm:
         for func in idautils.Functions(start, end):
             for item in idautils.FuncItems(func):
                 for xref in chain(idautils.DataRefsFrom(item),
                                   idautils.CodeRefsFrom(item, 1)):
                     if self.is_ea_in_segs(xref, self.init_segm):
                         if not self.refs.get(func, None):
                             self.refs[func] = {'to': set(), 'from': set()}
                         self.refs[func]['from'].add((item, xref))
                         for to_xref in chain(idautils.DataRefsTo(func),
                                              idautils.CodeRefsTo(func, 1)):
                             self.refs[func]['to'].add(to_xref)
예제 #15
0
 def __PltResolver(jmprel, strtab, symtab, pltgot):
     seg_sec = idc.SegByName('.plt.sec')
     sec_start = idc.SegByBase(seg_sec)
     sec_end = idc.SegEnd(sec_start)
     if sec_start == idaapi.BADADDR:
         print "[-] can't find .plt.sec segment"
         return
     idx = 0
     while True:
         r_off = idc.Dword(jmprel + 0x8 * idx)
         r_info1 = idc.Byte(jmprel + 0x8 * idx + 0x4)
         r_info2 = idc.Byte(jmprel + 0x8 * idx + 0x5)
         if r_off > 0x7fffffff:
             return
         if r_info1 == 7:
             st_name = idc.Dword(symtab + r_info2 * 0x10)
             name = idc.GetString(strtab + st_name)
             # rename got
             idc.set_name(r_off, name + '_ptr')
             plt_func = idc.Dword(r_off)
             # rename plt
             idc.set_name(plt_func, 'j_' + name)
             SetFuncFlags(plt_func)
             # rename plt.sec
             for addr in idautils.DataRefsTo(r_off):
                 plt_sec_func = idaapi.get_func(addr).startEA
                 idc.set_name(plt_sec_func, '_' + name)
                 SetFuncFlags(plt_sec_func)
             got_off = r_off - pltgot
             target = '+{}h'.format(
                 hex(got_off).lower().replace('0x',
                                              '').replace('l',
                                                          '').rjust(2, '0'))
             for func_ea in idautils.Functions(sec_start, sec_end):
                 func = idaapi.get_func(func_ea)
                 cur = func.startEA
                 end = func.endEA
                 find = False
                 while cur <= end:
                     code = idc.GetDisasm(cur).lower().replace(' ', '')
                     if target in code:
                         find = True
                         break
                     cur = idc.NextHead(cur, end)
                 if find:
                     idc.set_name(func_ea, '_' + name)
                     SetFuncFlags(func_ea)
         idx += 1
예제 #16
0
def analyse_callbacks():
    """Analyse functions that are used as callbacks."""
    global POSSIBLE_CODE_REFS
    log.info("Analysing callbacks")
    for ea in POSSIBLE_CODE_REFS:
        if program.has_basic_block(ea):
            block = program.get_basic_block(ea)
            if not block.address_is_taken:
                block.address_is_taken = True
                log.info("Block {:08x} is a callback".format(ea))

    for block in program.basic_blocks():
        if not block.address_is_taken:
            if len(tuple(idautils.DataRefsTo(block.ea))):
                block.address_is_taken = True
                log.info("Block {:08x} is a callback".format(block.ea))
예제 #17
0
    def fill_eas(self, start_ea):
        self.eas = []

        print "start_ea", start_ea

        for i, xhead in enumerate(
                idautils.Heads(start_ea, start_ea + (pointer_size * 200))):
            dref = list(idautils.DataRefsFrom(xhead))
            if dref:
                addy_flags = idc.GetFlags(dref[0])
                if (addy_flags & idc.FF_FUNC) == 0:
                    break
                if i > 0 and len(list(idautils.DataRefsTo(xhead))) > 0:
                    break
                self.eas.append(dref[0])
            else:
                break
        if len(self.eas) == 0:
            print "Failed to create virtual table"
        print "Got %s eas" % len(self.eas)
예제 #18
0
def str_fun_xrefs():
    str_fun_xref = {}
    for s in IDAStrings:
        for ref in idautils.DataRefsTo(s.ea):
            f = idaapi.get_func(ref)
            if not f:
                continue

            if idc.GetMnem(ref) == "":
                continue

            f_ea = f.startEA
            try:
                #because we are only carrying the string value itself, duplications should be removed.
                #This is important because of OFFS/ADR instruction double references being very typical,
                #and multiple allocations/frees in same function causing extra references too.
                str_fun_xref[f_ea].add(str(s))
            except:
                str_fun_xref[f_ea] = set([str(s)])

    return str_fun_xref
예제 #19
0
def update_struct_offsets(data_addr, struct_label, struct_name, pad=0):
    """
    Find xrefs to a struct pointer and change all the offsets to be struct
    offsets. This is useful for updating references to function pointers in
    EFI tables.

    For example:
    mov     rax, cs:qword_whatever
    call    qword ptr [rax+150h]

    Becomes:
    mov     rax, cs:gBootServices
    call    [rax+EFI_BOOT_SERVICES.UninstallMultipleProtocolInterfaces]

    Parameters:
    addr        - The address of the struct pointer global
    struct_name - The name of the structure to use for offsets
    """

    # Find all xrefs to this data in the code
    xrefs = list(idautils.DataRefsTo(data_addr))
    print "{}Found {} xrefs".format(' ' * pad, len(xrefs))
    print "{}Struct name : {}".format(' ' * pad, struct_name)
    # Process xrefs
    for xref in xrefs:
        inst = idautils.DecodeInstruction(xref)
        # We're only interested in xrefs in code where the left operand is a
        # register, and the right operand is the memory address of our data
        # structure.
        if inst.Op1.type == ida_ua.o_reg and \
           inst.Op2.type == ida_ua.o_mem and \
           ida_name.get_name(inst.Op2.addr) == struct_label:
            print "{}Processing xref from 0x{:08x}: {}".format(
                ' ' * pad, xref, disasm(xref)
            )
            update_struct_offsets_for_xref(xref, struct_name, pad)
        else:
            print "{}Too hard basket - xref from 0x{:08x}: {}".format(
                ' ' * pad, xref, disasm(xref)
            )
예제 #20
0
    def Anayl_Func_Call(self, func_name, para_num):
        if func_name == "":
            return

        #get start address
        segkind = ['.text', '.init', '.plt']
        #startaddr = idc.SegByName('.rodata')
        startaddr = MinEA()
        #fun_addr = idc.LocByName(func_name)
        # search the address of the pattern text
        while True:
            fun_addr = FindText(startaddr, SEARCH_DOWN, 0, 0, func_name)
            if not (SegName(fun_addr)) in segkind:
                break
            startaddr = NextHead(fun_addr)

        print 'find pattern string addr', hex(fun_addr)

        #byte_str = [hex(y) for y in bytearray(func_name)]
        #print byte_str

        #print hex(fun_addr),idc.GetDisasm(fun_addr)

        call_addrs = idautils.DataRefsTo(fun_addr)
        dic = {}
        for item in call_addrs:
            if (not isCode(GetFlags(item))):
                continue
            #print hex(item),idc.GetDisasm(item)
            CALL_ADDR = item
            while (not ua_mnem(CALL_ADDR) == 'BL'):
                CALL_ADDR = NextHead(CALL_ADDR)
            CALL_ADDR = PrevHead(CALL_ADDR)
            #print 'from addr %s analyses' % (str(hex(CALL_ADDR)))
            para = self.BackForward(CALL_ADDR, para_num)
            xref_funname = GetFunctionName(CALL_ADDR)
            dic[xref_funname] = para
        return dic
예제 #21
0
def Get_Thread_Roots():
    funcNamesList = ['CreateThread', '_beginthreadex', '_beginthread']

    threadStartEaSet = set()
    for funcName in funcNamesList:
        argIndex = 1 if funcName == '_beginthread' else 3
        funcLoc = idc.LocByName(funcName)
        if funcLoc == idc.BADADDR:
            continue

        codeRefs = idautils.CodeRefsTo(funcLoc, 0)
        dataRefs = idautils.DataRefsTo(funcLoc)
        refs = set(codeRefs) | set(dataRefs)

        for refEa in refs:
            if idc.GetMnem(refEa) == 'call':
                mnemEA = Get_Prev_Instruction(refEa, 'push', argIndex, 10)
                if mnemEA == -1:
                    continue

                if idc.GetOpType(mnemEA, 0) == idc.o_reg:
                    reg = idc.GetOpnd(mnemEA, 0)
                    for i in range(0, 5):
                        mnemEA = Get_Prev_Instruction(mnemEA, 'mov', 1, 10)
                        if mnemEA == -1:
                            break
                        if idc.GetOpnd(mnemEA, 0) == reg:
                            rootEa = idc.GetOperandValue(mnemEA, 1)
                            if idc.GetFunctionName(rootEa) != '':
                                threadStartEaSet.add(rootEa)
                            break
                else:
                    rootEa = idc.GetOperandValue(mnemEA, 0)
                    if idc.GetFunctionName(rootEa) != '':
                        threadStartEaSet.add(rootEa)

    return list(threadStartEaSet)
예제 #22
0
def update_locate_protocols_interfaces(guid_labels):
    """
    Find the interface parameter for LocateProtocol function.
    Rename the Interface global variable.
    Update struct offsets for the interface xref

    LocateProtocol call example:
    ----
    mov     rax, cs:gBootServices
    lea     r8, Interface   ; Interface
    lea     rcx, gEfiHiiDatabaseProtocolGuid ; Protocol
    xor     edx, edx        ; Registration
    call    [rax+EFI_BOOT_SERVICES.LocateProtocol
    ----
    """
    print "Populating LocateProtocol interfaces"
    for guid_label, values in guid_labels.iteritems():
        addr, guid_struct = values
        xrefs = list(idautils.DataRefsTo(addr))
        for xref in xrefs:
            if is_locate_protocol_param(xref):
                interface_addr = get_interface_param_addr(xref)
                if interface_addr is not None:
                    protocol_struct = \
                        protocol_struct_from_guid_struct(guid_struct)
                    protocol_label = get_next_unused_label(
                        underscore_to_global(protocol_struct)
                    )
                    ida_name.set_name(interface_addr, protocol_label)
                    print("  - Found interface of type '{}' at 0x{:08x} " +
                          "Updating offsets...").format(
                        protocol_struct, interface_addr
                    )
                    update_struct_offsets(
                        interface_addr, protocol_label, protocol_struct, 6
                    )
    def objc_msgsend_xref(self,
                          call_ea,
                          objc_self,
                          objc_selector,
                          create_xref=True):
        '''
        This function will create a code xref to an objc method
        
        call_ea : location of call/jmp objc_msgsend (regardless of direct/indirect)
        objc_self: ea where RDI is set to static value (or that we find it's from a previous call or the RDI of the current function)
        objc_selector: ea where RSI is set to static value
        
        This ignores the RDI register, which is the `self` argument to objc_msgsend()
        id objc_msgSend(id self, SEL op, ...);
        So far, this seems to be fine as far as the cross-references are concerned.

        '''

        # get instruction mnemonic at address - I guess to check and make sure
        # it's mov rsi, blah
        instruction = idc.GetDisasm(objc_selector)
        if self.debugflag:
            print ">>> objc_msgsend_xref 0x%08x %s" % (objc_selector,
                                                       instruction)

        # get outbound references in the appropriate segment
        # implicit assumption is there is exacltly one
        target_selref = None
        for _ref in idautils.DataRefsFrom(objc_selector):
            if idc.SegName(_ref) == "__objc_selrefs":
                target_selref = _ref

        if not target_selref:
            return False

        # get outbound references in the appropriate segment
        # implicit assumption is there is exacltly one
        target_methname = None
        for _ref in idautils.DataRefsFrom(target_selref):
            if idc.SegName(_ref) == "__objc_methname":
                target_methname = _ref

        if not target_methname:
            return False

        # get inbound references
        # __objc_const
        # must be a __objc2_meth
        # I hope this method is correct to find __objc2_meth structs
        # BUG: when the binary has mutiple objc methods by the same name, this logic fails
        # Track RDI register. have to figure out what instance/class is referenced
        objc2_meth_struct_id = ida_struct.get_struc_id("__objc2_meth")
        meth_struct_found = False
        target_method = None
        for _ref in idautils.DataRefsTo(target_methname):
            # multiple may match
            # we care about the __obj2_meth struct found in references
            if idc.SegName(_ref) == "__objc_const":
                # check the outbound references
                for _meth_ref in idautils.DataRefsFrom(_ref):
                    if _meth_ref == objc2_meth_struct_id:
                        meth_struct_found = True

                if meth_struct_found:
                    # only do this once
                    # TODO: check against RDI here to make sure it's the proper class
                    # meth_struct_found = False

                    for _meth_ref in idautils.DataRefsFrom(_ref):
                        # assumption made on function always being in text segment
                        if idc.SegName(_meth_ref) == "__text":
                            # save the method implementation -- this is the function ptr
                            if self.debugflag:
                                print "0x%08x checking for the proper method -- %s" % (
                                    _meth_ref,
                                    idc.get_name(
                                        idc.get_func_attr(
                                            _meth_ref, idc.FUNCATTR_START)))
                            target_method = _meth_ref

        if not target_method:
            return False

        # After dereferencing across the IDB file, we finally have a target function.
        # In other words, if there isn't a method **in this binary** no xref is made (IDA only loads one binary?)
        # that is referenced from the mov rsi, <selector> instruction
        if self.debugflag: print "Found target method 0x%08x" % target_method
        if create_xref:
            idc.AddCodeXref(objc_selector, target_method, idc.fl_CF)

        return True
예제 #24
0
def main(fileName):
    if fileName is None:
        return
    jsonValue = {}
    jsonValue["names"] = {}
    jsonValue["functions"] = {}
    jsonValue["segments"] = []
    jsonValue["strings"] = {}

    for addr, name in idautils.Names():
        jsonValue["names"][addr] = name

    # Record segment details
    for ea in idautils.Segments():
        cur_seg = {}
        cur_seg["start"] = idc.SegStart(ea)
        cur_seg["end"] = idc.SegEnd(ea)
        cur_seg["name"] = idc.SegName(ea)
        seg = idaapi.getseg(ea)
        cur_seg["r"] = (seg.perm & idaapi.SEGPERM_READ) != 0
        cur_seg["w"] = (seg.perm & idaapi.SEGPERM_WRITE) != 0
        cur_seg["x"] = (seg.perm & idaapi.SEGPERM_EXEC) != 0
        cur_seg["semantics"] = DefaultSectionSemantics
        if seg.type == idaapi.SEG_CODE:
            cur_seg["semantics"] = ReadOnlyCodeSectionSemantics
        elif seg.type == idaapi.SEG_DATA or seg.type == idaapi.SEG_BSS:
            if cur_seg["w"]:
                cur_seg["semantics"] = ReadWriteDataSectionSemantics
            else:
                cur_seg["semantics"] = ReadOnlyDataSectionSemantics

    # Record function details
    for ea in idautils.Functions():
        cur_func = {}
        cur_func["start"] = ea
        cur_func["end"] = idc.GetFunctionAttr(ea, idc.FUNCATTR_END)
        cur_func["comment"] = linearize_comment(ea, True)
        cur_func["comments"] = {}
        for line_ea in idautils.Heads(ea, cur_func["end"]):
            line_comment = linearize_comment(line_ea)
            if line_comment is not None:
                cur_func["comments"][line_comment] = line_ea

        flags = idc.GetFunctionFlags(ea)
        cur_func["can_return"] = (flags & idc.FUNC_NORET) != idc.FUNC_NORET
        cur_func["thunk"] = False
        f = idaapi.get_func(ea)
        blocks = []
        for block in idaapi.FlowChart(f):
            blocks.append([block.startEA, block.endEA])

            # IDA treats thunks as being part of the function they are tunking to
            # Binary Ninja doesn't so only add the first basic block for all thunks
            if flags & idc.FUNC_THUNK != 0:
                cur_func["thunk"] = True
                break
        cur_func["basic_blocks"] = blocks
        jsonValue["functions"][idc.GetFunctionName(ea)] = cur_func

    # Record string details
    for string in idautils.Strings():
        name = ""
        if string.ea in jsonValue["names"]:
            name = jsonValue["names"][string.ea]

        xrefs = list(idautils.DataRefsTo(string.ea))
        jsonValue["strings"][string.ea] = (name, string.length, string.type,
                                           xrefs)

    # TODO: global variable names and types
    # TODO: stack local variable names and types
    # TODO: types and enumerations
    # TODO: non-function comments

    with open(fileName, "wb") as f:
        f.write(json.dumps(jsonValue, indent=4))

    print("Exported idb to {}".format(fileName))
예제 #25
0
 def drefs_to(self):
     """Source addresses of data xrefs to this function."""
     return idautils.DataRefsTo(self.start_ea)
예제 #26
0
 def drefs_to(self):
     """Source addresses of data references from this line."""
     return idautils.DataRefsTo(self.ea)
예제 #27
0
 def getDataRefsTo(self, ea):
     return idautils.DataRefsTo(ea)
import ida_kernwin
import ida_strlist
import idautils
import idc
import json
from collections import defaultdict
import idautils
import os

string_to_function = defaultdict(list)
sc = idautils.Strings()
for s in sc:
    #print "%x: len=%d type=%d -> '%s'" % (s.ea, s.length, s.strtype, str(s))
    for ref in idautils.DataRefsTo(s.ea):
        res = idc.GetFunctionName(ref)
        if res != None and len(res) != 0:
            tbp = idc.demangle_name(res, idc.GetLongPrm(idc.INF_SHORT_DN))

            if tbp != None:
                res = tbp
            string_to_function[str(s)].append(res)

with open('string_to_func_dict', 'w') as f:
    json.dump(dict(string_to_function), f)

print('It\'s over!')
예제 #29
0
def nameAllDispatches(ea):
    '''Using the address of {theQuickTimeDispatcher}, name and tag all discovered dispatch calls in quicktime.qts'''
    for address in idautils.DataRefsTo(ea):
        nameDispatch(address)
    return
예제 #30
0
import binascii
import idaapi  # type: ignore
import idautils  # type: ignore
import ida_hexrays as hr  # type: ignore
import idc  # type: ignore
import os
import struct
import sys
import typing

total = len(list(idautils.DataRefsTo(0x7101CBB200+0x5F20+0x248)))
for i, ea in enumerate(idautils.DataRefsTo(0x7101CBB200+0x5F20+0x248)):
  print(i, total)
  try:
    idaapi.decompile(ea)
  except:
    pass