Beispiel #1
0
def is_invalid_ea(ea):
  """Returns `True` if `ea` is not valid, i.e. it doesn't point into any
  valid segment."""
  if (idc.BADADDR == ea) or \
    (idc.get_segm_name(ea) == "LOAD"):
    return True

  try:
    idc.get_segm_attr(idc.get_segm_start(ea), idc.SEGATTR_TYPE)
    return False  # If we get here, then it must be a valid ea!
  except:
    return True
Beispiel #2
0
def is_invalid_ea(ea):
    """Returns `True` if `ea` is not valid, i.e. it doesn't point into any
  valid segment."""
    if (idc.BADADDR == ea) or \
      (idc.get_segm_name(ea) == "LOAD"):
        return True

    try:
        idc.get_segm_attr(idc.get_segm_start(ea), idc.SEGATTR_TYPE)
        return False  # If we get here, then it must be a valid ea!
    except:
        return True
Beispiel #3
0
def get_bytes(name_or_addr):
    """
    Obtains 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 name_or_addr: either the name of a segment or an EA within a segment

    :return bytes: bytes which are contained with the segment
    """
    seg_start = get_start(name_or_addr)
    seg_bytes = _cache.get(seg_start)
    if seg_bytes is None:
        seg_end = idc.get_segm_attr(seg_start, idc.SEGATTR_END)

        # This check will make an adjustment to seg_end based on whether the previous address has a value
        # or not.  In some instances, seg_end will throw us into an adjacent section which has data and
        # we'll end up getting bad values here.
        if idc.is_loaded(seg_end) and not idc.is_loaded(seg_end - 1):
            seg_end -= 1

        # Need to find the actual end address of the section data since IDA returns addresses that have
        # no data...
        while not idc.is_loaded(seg_end):
            seg_end -= 1

        seg_bytes = _obtain_bytes(seg_start, seg_end)
        _cache[seg_start] = seg_bytes

    return seg_bytes
Beispiel #4
0
def is_code(ea):
    if is_invalid_ea(ea):
        return False

    seg_ea = idc.get_segm_start(ea)
    seg_type = idc.get_segm_attr(seg_ea, idc.SEGATTR_TYPE)
    return (seg_type == idc.SEG_CODE)
Beispiel #5
0
def processDataSegs():
    funcdata = {}
    datafunc = {}
    for n in xrange(idaapi.get_segm_qty()):
        seg = idaapi.getnseg(n)
        ea = seg.startEA
        segtype = idc.get_segm_attr(ea, idc.SEGATTR_TYPE)
        if segtype in [idc.SEG_DATA, idc.SEG_BSS]:
            start = idc.get_segm_start(ea)
            end = idc.get_segm_end(ea)
            cur = start
            while cur <= end:
                refs = [v for v in DataRefsTo(cur)]
                for fea in refs:
                    name = get_unified_funcname(fea)
                    if len(name) == 0:
                        continue
                    if name not in funcdata:
                        funcdata[name] = [cur]
                    else:
                        funcdata[name].append(cur)
                    if cur not in datafunc:
                        datafunc[cur] = [name]
                    else:
                        datafunc[cur].append(name)
                cur = NextHead(cur)
    return funcdata, datafunc
Beispiel #6
0
def get_all_func():
    num = 0
    content = []
    for func in idautils.Functions():
        seg_perm = idc.get_segm_attr(func,SEGATTR_PERM)         # 段属性
        if(5 !=seg_perm):
            continue
        seg_name = idc.get_segm_name(func)                      # 段名
        if(".plt" == seg_name):
            continue
        
        func_name = idc.get_func_name(func)                     # 函数名
        func_flags = hex(idc.get_func_attr(func,FUNCATTR_FLAGS))# 函数信息
        func_head = hex(idc.get_func_attr(func,FUNCATTR_START)) # 函数头
        func_end = hex(idc.get_func_attr(func,FUNCATTR_END))    # 函数尾

        l = []
        l.append(num)
        l.append(seg_name)
        l.append(seg_perm)
        l.append(func_name)
        l.append(func_flags)
        l.append(func_head)
        l.append(func_end)
        content.append(l)
        
        num += 1
        #print(l)
    return content
Beispiel #7
0
def is_code(ea):
  if is_invalid_ea(ea):
    return False

  seg_ea = idc.get_segm_start(ea)
  seg_type = idc.get_segm_attr(seg_ea, idc.SEGATTR_TYPE)
  return (seg_type == idc.SEG_CODE)
Beispiel #8
0
def _is_extern_seg(seg):
    """Returns `True` if `seg` refers to a segment with external variable or
    function declarations."""
    if not seg:
        return False

    seg_type = idc.get_segm_attr(seg.start_ea, idc.SEGATTR_TYPE)
    return seg_type == idc.SEG_XTRN
Beispiel #9
0
 def _get_memory(self):
     result = bytearray()
     segment_starts = [ea for ea in idautils.Segments()]
     offsets = []
     start_len = 0
     for start in segment_starts:
         end = idc.get_segm_attr(start, idc.SEGATTR_END)
         result += ida_bytes.get_bytes(start, end - start)
         offsets.append((start, start_len, len(result)))
         start_len = len(result)
     return bytes(result), offsets
Beispiel #10
0
def getx86CodeSize_ida7(ea=None):
    '''
    For a given EA, finds the code size. Returns 16 for-16bit, 32 for 32-bit, or 64 for 64-bit.
    If no EA is given, searches through all segments for a code segment to use.
    '''
    if ea is None:
        for seg in idautils.Segments():
            if idc.get_segm_attr(seg, idc.SEGATTR_TYPE) == idc.SEG_CODE:
                ea = seg
                break
    if ea is None:
        raise RuntimeError('Could not find code segment to use for getx86CodeSize')
    bitness = idc.get_segm_attr(ea, idc.SEGATTR_BITNESS)
    if bitness == 0:
        return 16
    elif bitness == 1:
        return 32
    elif bitness == 2:
        return 64
    raise RuntimeError('Bad bitness')
Beispiel #11
0
def getx86CodeSize_ida7(ea=None):
    '''
    For a given EA, finds the code size. Returns 16 for-16bit, 32 for 32-bit, or 64 for 64-bit.
    If no EA is given, searches through all segments for a code segment to use.
    '''
    if ea is None:
        for seg in idautils.Segments():
            if idc.get_segm_attr(seg, idc.SEGATTR_TYPE) == idc.SEG_CODE:
                ea = seg
                break
    if ea is None:
        raise RuntimeError(
            'Could not find code segment to use for getx86CodeSize')
    bitness = idc.get_segm_attr(ea, idc.SEGATTR_BITNESS)
    if bitness == 0:
        return 16
    elif bitness == 1:
        return 32
    elif bitness == 2:
        return 64
    raise RuntimeError('Bad bitness')
Beispiel #12
0
def main():
    print("[*] loading crypto constants")
    for const in non_sparse_consts:
        const["byte_array"] = convert_to_byte_array(const)

    for start in idautils.Segments():
        print("[*] searching for crypto constants in %s" % idc.get_segm_name(start))
        ea = start
        while ea < idc.get_segm_end(start):
            bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4)))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if map(lambda x:ord(x), idc.get_bytes(ea, len(const["byte_array"]))) == const["byte_array"]:
                    print(("0x%0" + str(digits) + "X: found const array %s (used in %s)") % (ea, const["name"], const["algorithm"]))
                    idc.set_name(ea, const["name"])
                    if const["size"] == "B":
                        idc.create_byte(ea)
                    elif const["size"] == "L":
                        idc.create_dword(ea)
                    elif const["size"] == "Q":
                        idc.create_qword(ea)
                    idc.make_array(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4

        ea = start
        if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == 2:
            while ea < idc.get_segm_end(start):
                d = ida_bytes.get_dword(ea)
                for const in sparse_consts:
                    if d != const["array"][0]:
                        continue
                    tmp = ea + 4
                    for val in const["array"][1:]:
                        for i in range(8):
                            if ida_bytes.get_dword(tmp + i) == val:
                                tmp = tmp + i + 4
                                break
                        else:
                            break
                    else:
                        print(("0x%0" + str(digits) + "X: found sparse constants for %s") % (ea, const["algorithm"]))
                        cmt = idc.get_cmt(idc.prev_head(ea), 0)
                        if cmt:
                            idc.set_cmt(idc.prev_head(ea), cmt + ' ' + const["name"], 0)
                        else:
                            idc.set_cmt(idc.prev_head(ea), const["name"], 0)
                        ea = tmp
                        break
                ea += 1
    print("[*] finished")
Beispiel #13
0
def is_external_segment_by_flags(ea):
  """Returns `True` if IDA believes that `ea` belongs to an external segment."""
  try:
    seg_ea = idc.get_segm_start(ea)
    seg_type = idc.get_segm_attr(seg_ea, idc.SEGATTR_TYPE)
    if seg_type == idc.SEG_XTRN:
      _EXTERNAL_SEGMENTS.add(seg_ea)
      return True
    else:
      return False
  except:
    return False
Beispiel #14
0
def is_external_segment_by_flags(ea):
    """Returns `True` if IDA believes that `ea` belongs to an external segment."""
    try:
        seg_ea = idc.get_segm_start(ea)
        seg_type = idc.get_segm_attr(seg_ea, idc.SEGATTR_TYPE)
        if seg_type == idc.SEG_XTRN:
            _EXTERNAL_SEGMENTS.add(seg_ea)
            return True
        else:
            return False
    except:
        return False
Beispiel #15
0
def _is_executable_seg(seg):
    """Returns `True` a segment's data is executable."""
    if 0 != (seg.perm & ida_segment.SEGPERM_EXEC):
        return True

    seg_type = idc.get_segm_attr(seg.start_ea, idc.SEGATTR_TYPE)
    if seg_type in (idc.SEG_CODE, idc.SEG_XTRN):
        return True

    sclass = ida_segment.get_segm_class(seg)
    if sclass:
        return "CODE" in sclass or "XTRN" in sclass

    return False
Beispiel #16
0
    def _get_segments(self, attr):
        segments = []
        start = idc.BADADDR
        end = idc.BADADDR
        seg = idc.get_first_seg()

        while seg != idc.BADADDR:
            if idc.get_segm_attr(seg, idc.SEGATTR_TYPE) == attr:
                start = idc.get_segm_start(seg)
                end = idc.get_segm_end(seg)
                segments.append((start, end))
            seg = idc.get_next_seg(seg)

        return segments
Beispiel #17
0
def get_start(name_or_addr):
    """
    Retrieves the starting address for the segment containing the given name or address.

    :param string|int name_or_addr: either the name of a segment or an EA within a segment
    """
    if isinstance(name_or_addr, str):
        segment = ida_segment.get_segm_by_name(name_or_addr)
        if segment is None:
            raise AssertionError(
                "could not find segment for {}".format(name_or_addr))
        return segment.start_ea
    elif isinstance(name_or_addr, numbers.Number):
        return idc.get_segm_attr(name_or_addr, idc.SEGATTR_START)
    else:
        raise ValueError("Invalid value: {}".format(name_or_addr))
Beispiel #18
0
    def segment_start(self, val):
        """
        Retrieves the start EA for given name or EA within a segment.

        :param string|int val: either the name of a segment or an EA within a segment
        """
        if isinstance(val, str):
            segment = idaapi.get_segm_by_name(val)
            if segment is None:
                raise AssertionError(
                    "could not find segment for {}".format(val))
            return segment.start_ea
        elif isinstance(val, numbers.Number):
            return idc.get_segm_attr(val, idc.SEGATTR_START)
        else:
            raise ValueError('Invalid value: {}'.format(val))
Beispiel #19
0
def processExternalSegs():
    funcdata = {}
    datafunc = {}
    for n in xrange(idaapi.get_segm_qty()):
        seg = idaapi.getnseg(n)
        ea = seg.startEA
        segtype = idc.get_segm_attr(ea, idc.SEGATTR_TYPE)
        if segtype in [idc.SEG_XTRN]:
            start = idc.get_segm_start(ea)  #idc.SegStart(ea)
            end = idc.get_segm_end(ea)  #idc.SegEnd(ea)
            cur = start
            while cur <= end:
                name = get_unified_funcname(cur)
                funcdata[name] = hex(cur)
                cur = idc.next_head(cur)
    return funcdata
Beispiel #20
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
        """
        seg_start = self.segment_start(val)
        seg_bytes = self.segments.get(seg_start)
        if seg_bytes is None:
            seg_end = idc.get_segm_attr(seg_start, idc.SEGATTR_END)
            seg_bytes = self._get_segment_bytes(seg_start, seg_end)
            self.segments[seg_start] = seg_bytes

        return seg_bytes
Beispiel #21
0
def get_bytes(name_or_addr):
    """
    Obtains 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 name_or_addr: either the name of a segment or an EA within a segment

    :return bytes: bytes which are contained with the segment
    """
    seg_start = get_start(name_or_addr)
    seg_bytes = _cache.get(seg_start)
    if seg_bytes is None:
        seg_end = idc.get_segm_attr(seg_start, idc.SEGATTR_END)
        seg_bytes = _obtain_bytes(seg_start, seg_end)
        _cache[seg_start] = seg_bytes

    return seg_bytes
Beispiel #22
0
def dostuff():
	count = 0
	adr = idaapi.get_imagebase()
	end = idc.get_segm_attr(adr, idc.SEGATTR_END)
	while(adr < end):

		ins = idc.GetMnem(adr)
		ln = idc.GetOpnd(adr, 1)[1:]
		if ins == "MOV" and idc.GetOpnd(adr, 0) == "W8" and int(ln, 16) < 0xFFF and int(ln, 16) > 0xA and "AA" not in ln:
																				#there are comments at top rite?	#-ftrivial-auto-var-init=pattern
			SetColor(adr, CIC_ITEM, LINE_COLOR)

		if ins == "MOVE":
			hash = (idc.GetOpnd(adr, 1)[1:])
			if len(str(hash)) >= 16 and len(str(hash)) < 20 and hash > 0xF000000000000000:
					file = decodehash(hash)
					if file != -1:
						isn = "WMSA            "+file
						set_manual_insn(adr, isn)
						SetColor(adr, CIC_ITEM, FILE_COLOR)
						count+=1
		adr+=4

	print "[WMSA] Total hashes decoded (non-unique) : " + str(count)
Beispiel #23
0
def load_file(fd, neflags, format):
    global prologues
    global br_flag
    size = 0
    base_addr = 0
    ea = 0
    nfunc = 0

    idaapi.set_processor_type("arm", ida_idp.SETPROC_LOADER_NON_FATAL)
    idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT

    if (neflags & idaapi.NEF_RELOAD) != 0:
        return 1

    fd.seek(0, idaapi.SEEK_END)
    size = fd.tell()

    segm = idaapi.segment_t()
    segm.bitness = 2  # 64-bit
    segm.start_ea = 0
    segm.end_ea = size

    if br_flag == false:
        idaapi.add_segm_ex(segm, "iBoot", "CODE", idaapi.ADDSEG_OR_DIE)
    else:
        idaapi.add_segm_ex(segm, "SecureROM", "CODE", idaapi.ADDSEG_OR_DIE)

    fd.seek(0)
    fd.file2base(0, 0, size, false)

    idaapi.add_entry(0, 0, "start", 1)
    ida_funcs.add_func(ea)

    print("[+] Marked as code")

    # heuristic
    while (true):
        mnemonic = idc.print_insn_mnem(ea)

        if "LDR" in mnemonic:
            base_str = idc.print_operand(ea, 1)
            base_addr = int(base_str.split("=")[1], 16)

            break

        ea += 4

    print("[+] Rebasing to address 0x%x" % (base_addr))
    idaapi.rebase_program(base_addr, idc.MSF_NOFIX)

    segment_start = base_addr
    segment_end = idc.get_segm_attr(segment_start, idc.SEGATTR_END)

    ea = segment_start

    print("[+] Searching and defining functions")

    for prologue in prologues:
        while ea != ida_idaapi.BADADDR:
            ea = ida_search.find_binary(ea, segment_end, prologue, 16,
                                        ida_search.SEARCH_DOWN)

            if ea != ida_idaapi.BADADDR:
                if len(prologue) < 8:
                    ea = ea - 2

                if (ea % 4) == 0 and ida_bytes.get_full_flags(ea) < 0x200:
                    # print("[+] Defining a function at 0x%x" % (ea))
                    ida_funcs.add_func(ea)
                    nfunc = nfunc + 1

                ea = ea + 4

    idc.plan_and_wait(segment_start, segment_end)

    print("[+] Identified %d new functions" % (nfunc))

    print("[+] Looking for interesting functions")
    find_interesting(segment_start, segment_end)

    return 1
Beispiel #24
0
def is_code_segment(ea):
    return idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == idc.SEG_CODE
def get_bitness_bytes(addr):
    if idc.get_segm_attr(addr, idc.SEGATTR_BITNESS) == 2:
        return 8
    return 4
Beispiel #26
0
def is_read_only_segment(ea):
  mask_perms = idaapi.SEGPERM_WRITE | idaapi.SEGPERM_READ
  perms = idc.get_segm_attr(ea, idc.SEGATTR_PERM)
  return idaapi.SEGPERM_READ == (perms & mask_perms)
Beispiel #27
0
 def segment_filter(self, s_ea):
   """ Discard extern segments """
   if idc.get_segm_attr(s_ea, idc.SEGATTR_TYPE) != idc.SEG_XTRN and \
    idc.get_segm_name(s_ea) != self.config.entropy['segm_name']:
     return True
   return False
Beispiel #28
0
def is_read_only_segment(ea):
    mask_perms = idaapi.SEGPERM_WRITE | idaapi.SEGPERM_READ
    perms = idc.get_segm_attr(ea, idc.SEGATTR_PERM)
    return idaapi.SEGPERM_READ == (perms & mask_perms)
Beispiel #29
0
def main():
    print("[*] loading crypto constants")
    for const in non_sparse_consts:
        const["byte_array"] = convert_to_byte_array(const)

    for start in idautils.Segments():
        print("[*] searching for crypto constants in %s" %
              idc.get_segm_name(start))
        ea = start
        while ea < idc.get_segm_end(start):
            bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4)))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if map(lambda x: ord(x),
                       idc.get_bytes(ea, len(
                           const["byte_array"]))) == const["byte_array"]:
                    print(("0x%0" + str(digits) +
                           "X: found const array %s (used in %s)") %
                          (ea, const["name"], const["algorithm"]))
                    idc.set_name(ea, const["name"])
                    if const["size"] == "B":
                        idc.create_byte(ea)
                    elif const["size"] == "L":
                        idc.create_dword(ea)
                    elif const["size"] == "Q":
                        idc.create_qword(ea)
                    idc.make_array(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4

        ea = start
        if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == 2:
            while ea < idc.get_segm_end(start):
                d = ida_bytes.get_dword(ea)
                for const in sparse_consts:
                    if d != const["array"][0]:
                        continue
                    tmp = ea + 4
                    for val in const["array"][1:]:
                        for i in range(8):
                            if ida_bytes.get_dword(tmp + i) == val:
                                tmp = tmp + i + 4
                                break
                        else:
                            break
                    else:
                        print(("0x%0" + str(digits) +
                               "X: found sparse constants for %s") %
                              (ea, const["algorithm"]))
                        cmt = idc.get_cmt(idc.prev_head(ea), 0)
                        if cmt:
                            idc.set_cmt(idc.prev_head(ea),
                                        cmt + ' ' + const["name"], 0)
                        else:
                            idc.set_cmt(idc.prev_head(ea), const["name"], 0)
                        ea = tmp
                        break
                ea += 1
    print("[*] finished")
Beispiel #30
0
    idc.plan_and_wait(segment_start, segment_end)

    print("[+] Identified %d new functions" % (nfunc))

    print("[+] Looking for interesting functions")
    find_interesting(segment_start, segment_end)

    return 1


# for easy testing
if __name__ == "__main__":
    print("[+] find_interesting():")

    for seg in idautils.Segments():
        st = ida_segment.getseg(seg)
        name = idaapi.get_segm_name(st)

        if name == "iBoot" or name == "SecureROM" or name == "iBEC" \
                or name == "BootRom" or name == "LLB":

            segm_start = st.start_ea
            segm_end = idc.get_segm_attr(segm_start, idc.SEGATTR_END)
            find_interesting(segm_start, segm_end)
            break

    # ida_pro.qexit()

# EOF
Beispiel #31
0
def get_segm_attr(seg_ea, attr):
    if idaapi.IDA_SDK_VERSION <= 699:
        retval = idc.GetSegmentAttr(seg_ea, attr)
    else:
        retval = idc.get_segm_attr(seg_ea, attr)
    return retval
Beispiel #32
0
def filter_writable_segment(ea):
    return not idc.get_segm_attr(ea, idc.SEGATTR_PERM) & 2
Beispiel #33
0
import idautils
import idc

# Locate function signatures.
#
# based on: https://reverseengineering.stackexchange.com/a/14726

# func_sigs maps from function address to a record of the function's name and
# type.
func_sigs = {}
func_addrs = []
for seg in idautils.Segments():
    # Skip extern segment; as used by IDA for external functions.
    if idc.get_segm_attr(seg, SEGATTR_TYPE) == idc.SEG_XTRN:
        #print("skipping segment ", idc.get_segm_name(seg))
        continue
    for fn in idautils.Functions(seg, idc.get_segm_end(seg)):
        func_addr = fn
        func_name = idc.get_name(func_addr)
        if func_name is None:
            func_name = ""
        func_type = idc.get_type(func_addr)
        if func_type is None:
            func_type = ""
        func_sig = {"func_name": func_name, "func_type": func_type}
        func_sigs[func_addr] = func_sig
        func_addrs.append(func_addr)

# Sort function addresses to be used as key.
func_addrs.sort()
Beispiel #34
0
def main():
    print("[*] loading crypto constants")
    for const in non_sparse_consts:
        const["byte_array"] = convert_to_byte_array(const)

    for start in idautils.Segments():
        print("[*] searching for crypto constants in %s" %
              idc.get_segm_name(start))
        ea = start
        while ea < idc.get_segm_end(start):
            bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4)))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if list(
                        map(lambda x: x if type(x) == int else ord(x),
                            idc.get_bytes(ea, len(
                                const["byte_array"])))) == const["byte_array"]:
                    print(("0x%0" + str(digits) +
                           "X: found const array %s (used in %s)") %
                          (ea, const["name"], const["algorithm"]))
                    idc.set_name(ea, const["name"], ida_name.SN_FORCE)
                    if const["size"] == "B":
                        idc.create_byte(ea)
                    elif const["size"] == "L":
                        idc.create_dword(ea)
                    elif const["size"] == "Q":
                        idc.create_qword(ea)
                    idc.make_array(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4

        ea = start
        if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == idc.SEG_CODE:
            while ea < idc.get_segm_end(start):
                d = ida_bytes.get_dword(ea)
                for const in sparse_consts:
                    if d != const["array"][0]:
                        continue
                    tmp = ea + 4
                    for val in const["array"][1:]:
                        for i in range(8):
                            if ida_bytes.get_dword(tmp + i) == val:
                                tmp = tmp + i + 4
                                break
                        else:
                            break
                    else:
                        print(("0x%0" + str(digits) +
                               "X: found sparse constants for %s") %
                              (ea, const["algorithm"]))
                        cmt = idc.get_cmt(idc.prev_head(ea), 0)
                        if cmt:
                            idc.set_cmt(idc.prev_head(ea),
                                        cmt + ' ' + const["name"], 0)
                        else:
                            idc.set_cmt(idc.prev_head(ea), const["name"], 0)
                        ea = tmp
                        break
                ea += 1

    print("[*] searching for crypto constants in immediate operand")
    funcs = idautils.Functions()
    for f in funcs:
        flags = idc.get_func_flags(f)
        if (not flags & (idc.FUNC_LIB | idc.FUNC_THUNK)):
            ea = f
            f_end = idc.get_func_attr(f, idc.FUNCATTR_END)
            while (ea < f_end):
                imm_operands = []
                insn = ida_ua.insn_t()
                ida_ua.decode_insn(insn, ea)
                for i in range(len(insn.ops)):
                    if insn.ops[i].type == ida_ua.o_void:
                        break
                    if insn.ops[i].type == ida_ua.o_imm:
                        imm_operands.append(insn.ops[i].value)
                if len(imm_operands) == 0:
                    ea = idc.find_code(ea, idc.SEARCH_DOWN)
                    continue
                for const in operand_consts:
                    if const["value"] in imm_operands:
                        print(("0x%0" + str(digits) +
                               "X: found immediate operand constants for %s") %
                              (ea, const["algorithm"]))
                        cmt = idc.get_cmt(ea, 0)
                        if cmt:
                            idc.set_cmt(ea, cmt + ' ' + const["name"], 0)
                        else:
                            idc.set_cmt(ea, const["name"], 0)
                        break
                ea = idc.find_code(ea, idc.SEARCH_DOWN)
    print("[*] finished")
Beispiel #35
0
def get_bitness(addr):
    ptr = bits32
    if idc.get_segm_attr(addr, idc.SEGATTR_BITNESS) == 2:
        ptr = bits64
    return ptr
Beispiel #36
0
def def_functions(s_start):

    num_added_functions = 0

    s_addr = s_start
    s_end = idc.get_segm_attr(s_start, SEGATTR_END)  #idc.SegEnd(segm)
    print("0x%08x 0x%08x" % (s_start, s_end))

    while (s_addr < s_end):

        print("Testing address 0x%08x" % s_addr)

        #optimization assumes that function chunks are consecutive (no "function-in-function" monkey business)
        if (idaapi.get_func(s_addr)):

            next_func = idc.get_next_func(s_addr)

            ea = s_addr
            for c in idautils.Chunks(s_addr):
                #only use chunks in lookahead that do not jump over the next function and that are not smaller than where we are atm.
                if (c[1] > ea) and (c[1] <= next_func):
                    ea = c[1]
            if ea == s_addr:
                s_addr += 2
            else:
                s_addr = ea
            #s_addr += 4
            continue

        else:
            #This is not a good optimization, there WILL be data refs to function start addresses sometimes.
            '''
            if sum(1 for _ in (CodeRefsTo(s_addr, 1))) != 0:
                s_addr += 4
                continue
            '''
            #also add STMFD
            if ((idc.print_insn_mnem(s_addr) == "STM") and
                ("SP!" in idc.print_operand(s_addr, 0)) and
                ("LR" in idc.print_operand(s_addr, 1))) or (
                    ((idc.print_insn_mnem(s_addr) == "PUSH") or
                     (idc.print_insn_mnem(s_addr) == "PUSH.W") or
                     (idc.print_insn_mnem(s_addr) == "STR.W")) and
                    ("LR" in idc.print_operand(s_addr, 0))):
                print("Found function at 0x%08x" % s_addr)
                ida_funcs.add_func(s_addr)
                f = idaapi.get_func(s_addr)
                if (type(f) == type(None)):
                    print("Failed to create function! Undefined instructions?")
                    s_addr += 2
                else:
                    num_added_functions += 1
                    ea = -1
                    for c in idautils.Chunks(s_addr):
                        if c[1] > ea:
                            ea = c[1]
                    if ea != -1:
                        s_addr = ea
                    #failed?
                    else:
                        s_addr += 2
            else:
                s_addr += 2

    print("finished segment")
    return num_added_functions