コード例 #1
0
def main():
    idaapi.auto_wait()
    base = idaapi.get_imagebase()
    tif = idaapi.tinfo_t()

    f = open(os.environ.get("DESTPATH", "functype_"), 'w')

    for ea in Segments():
        # only code segment
        if idaapi.segtype(ea) != idaapi.SEG_CODE:
            continue

        for fva in Functions(get_segm_start(ea), get_segm_end(ea)):
            func_name = get_func_name(fva)
            has_type = idaapi.get_tinfo(tif, fva) or idaapi.guess_tinfo(
                tif, fva)

            if not has_type:
                continue

            info = serialize(tif)
            if info is None:
                continue

            print(
                hex(fva - base)[:-1], "|", func_name, "|", tif, "|",
                len(info['args']))
            f.write("0x%x|%s|%s\n" % (fva - base, func_name, json.dumps(info)))

    f.close()
    idaapi.qexit(0)
コード例 #2
0
ファイル: ida.py プロジェクト: veryblack/bap-ida-python
def output_segments(out):
    """Dump binary segmentation."""
    info = idaapi.get_inf_structure()
    size = "r32" if info.is_32bit else "r64"
    out.writelines(('(', info.get_proc_name()[1], ' ', size, ' ('))
    for seg in idautils.Segments():
        out.write("\n({} {} {:d} ({:#x} {:d}))".format(
            get_segm_name(seg),
            "code" if idaapi.segtype(seg) == idaapi.SEG_CODE else "data",
            idaapi.get_fileregion_offset(seg),
            seg, idaapi.getseg(seg).size()))
    out.write("))\n")
コード例 #3
0
ファイル: ida.py プロジェクト: chubbymaggie/bap-ida-python
def output_segments(out):
    """Dump binary segmentation."""
    info = idaapi.get_inf_structure()
    size = "r32" if info.is_32bit else "r64"
    out.writelines(('(', info.get_proc_name()[1], ' ', size, ' ('))
    for seg in idautils.Segments():
        out.write("\n({} {} {:d} ({:#x} {:d}))".format(
            idaapi.get_segm_name(seg),
            "code" if idaapi.segtype(seg) == idaapi.SEG_CODE else "data",
            idaapi.get_fileregion_offset(seg),
            seg, idaapi.getseg(seg).size()))
    out.write("))\n")
コード例 #4
0
ファイル: ida.py プロジェクト: rvantonder/bap-ida-python
def dump_loader_info(output_filename):
    """Dump information for BAP's loader into output_filename."""
    from idautils import Segments
    import idc

    idaapi.autoWait()

    with open(output_filename, 'w+') as out:
        info = idaapi.get_inf_structure()
        size = "r32" if info.is_32bit else "r64"
        out.write("(%s %s (" % (info.get_proc_name()[1], size))
        for seg in Segments():
            out.write("\n(%s %s %d (0x%X %d))" % (
                idaapi.get_segm_name(seg),
                "code" if idaapi.segtype(seg) == idaapi.SEG_CODE else "data",
                idaapi.get_fileregion_offset(seg),
                seg, idaapi.getseg(seg).size()))
        out.write("))\n")
コード例 #5
0
def dump_loader_info(output_filename):
    """Dump information for BAP's loader into output_filename."""
    from idautils import Segments
    import idc

    idaapi.autoWait()

    with open(output_filename, 'w+') as out:
        info = idaapi.get_inf_structure()
        size = "r32" if info.is_32bit else "r64"
        out.write("(%s %s (" % (info.get_proc_name()[1], size))
        for seg in Segments():
            out.write("\n(%s %s %d (0x%X %d))" % (
                idaapi.get_segm_name(seg),
                "code" if idaapi.segtype(seg) == idaapi.SEG_CODE else "data",
                idaapi.get_fileregion_offset(seg),
                seg, idaapi.getseg(seg).size()))
        out.write("))\n")
コード例 #6
0
 def type(self):
     return idaapi.segtype(self.ea)
コード例 #7
0
def scan_for_stacks():
    def preceeding_call(ea):
        p = idautils.DecodePreviousInstruction(ea)
        if p and "BL" in idc.GetMnem(p.ea):
            return str(idc.GetOpnd(p.ea, 0))
        else:
            return ""

    def jumps_to(f, t):
        f_ea = idc.LocByName(f)
        t_ea = idc.LocByName(t)

        for start, end in idautils.Chunks(f_ea):
            ea = start
            while (ea < end):
                i = idautils.DecodeInstruction(ea)

                #Functions have data chunks in them, these are offsets and dwords. skipping 4 ahead seems like a safe choice.
                if type(i) == type(None):
                    ea += 4
                    continue

                #detect if instruction is a jump to t_ea
                m = idc.GetMnem(ea)
                if idc.GetMnem(ea) == "LDR" and idc.GetOpnd(
                        ea, 0) == "PC" and t in idc.GetOpnd(ea, 1):
                    return True
                elif idc.GetMnem(ea) == "BX" and idc.GetOpnd(ea, 0) == t:
                    return True

                try:
                    ea += i.size
                except:
                    print "0x%08x" % ea
                    print "DecodeInstruction failed!"
                    print i.size

        return False

    #return True if the function at ea has an indirect jump, like BX Reg
    #    (This is not so simple, e.g. we don't want to include jumptables etc... for now it is just this simple implementation.)
    def jumps_to_reg(ea):
        return False

    stack_addrs = []
    for s in idautils.Segments():
        if idaapi.segtype(s) != idaapi.SEG_CODE:
            print "starting scanning segment at 0x%08x" % s
            addrs = find_ret_addrs(s)
            print "found %d return addresses in segment" % len(addrs)
            stack_addrs += addrs

    log_stack_addrs(stack_addrs)

    print "okay, stored all occurences. let's find viable call chains."

    chain = []
    chains = []

    for i in range(len(stack_addrs)):

        #if this is the last one, just add to chain if had to and finish.
        if (i == (len(stack_addrs) - 1)):
            if len(chain) > 0:
                chain.append(addr)
                chains.append(chain)
            continue

        addr = stack_addrs[i]
        ret_addr = Dword(addr) & 0xFFFFFFFE  #adjust Thumb addresses
        to_f = str(idc.GetFunctionName(ret_addr))

        next_ret_addr = Dword(
            stack_addrs[i + 1]) & 0xFFFFFFFE  #adjust Thumb addresses

        pre_f = preceeding_call(next_ret_addr)
        if pre_f == to_f:
            chain.append(addr)

        elif jumps_to(pre_f, to_f):
            chain.append("direct jump")
            chain.append(addr)

        elif jumps_to_reg(pre_f):
            chain.append("indirect_jump?")
            chain.append(addr)

        #no bonus, need to start a new chain at next_ret_addr

        else:
            # if there is an existing chain, that means this addr was connected to the previous, so can be added into the chain.
            if len(chain) > 0:
                chain.append(addr)
                chains.append(chain)

            chain = []

    print "found all chains, logging..."

    log_stack_chains(chains)

    print "... and done!"
コード例 #8
0
                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


num_total_added_functions = 0
for s in idautils.Segments():
    s_start = s
    if idaapi.segtype(s_start) == idaapi.SEG_CODE:
        print "starting segment at 0x%08x" % s_start
        num_total_added_functions += def_functions(s)

print "Added %d functions in total" % num_total_added_functions
コード例 #9
0
                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
 

num_total_added_functions = 0
for s in idautils.Segments():
    s_start = s   
    if idaapi.segtype(s_start) == idaapi.SEG_CODE:
        print "starting segment at 0x%08x" % s_start
        num_total_added_functions += def_functions(s)

print "Added %d functions in total" % num_total_added_functions
コード例 #10
0
ファイル: stackscan.py プロジェクト: Comsecuris/shannonRE
def scan_for_stacks():

	def preceeding_call(ea):
		p = idautils.DecodePreviousInstruction(ea)
		if p and "BL" in idc.GetMnem(p.ea):
			return str(idc.GetOpnd(p.ea, 0))
		else:
			return ""

	def jumps_to(f, t):
		f_ea = idc.LocByName(f)
		t_ea = idc.LocByName(t)

		for start,end in idautils.Chunks(f_ea):
			ea = start
			while (ea < end):
				i = idautils.DecodeInstruction(ea)

				#Functions have data chunks in them, these are offsets and dwords. skipping 4 ahead seems like a safe choice.
				if type(i) == type(None):
					ea += 4
					continue

				#detect if instruction is a jump to t_ea
				m = idc.GetMnem(ea)
				if idc.GetMnem(ea) == "LDR" and idc.GetOpnd(ea, 0) == "PC" and t in idc.GetOpnd(ea, 1):
					return True
				elif idc.GetMnem(ea) == "BX" and idc.GetOpnd(ea, 0) == t:
					return True

				try:
					ea += i.size
				except:
					print "0x%08x" % ea
					print "DecodeInstruction failed!"
					print i.size

		return False

	#return True if the function at ea has an indirect jump, like BX Reg
	#    (This is not so simple, e.g. we don't want to include jumptables etc... for now it is just this simple implementation.)
	def jumps_to_reg(ea):
		return False

	stack_addrs = []
	for s in idautils.Segments():
		if idaapi.segtype(s) != idaapi.SEG_CODE:
			print "starting scanning segment at 0x%08x" % s
			addrs = find_ret_addrs(s)
			print "found %d return addresses in segment" % len(addrs)
			stack_addrs += addrs

	log_stack_addrs(stack_addrs)

	print "okay, stored all occurences. let's find viable call chains."

	chain = []
	chains = []

	for i in range(len(stack_addrs)):

		#if this is the last one, just add to chain if had to and finish.
		if (i == (len(stack_addrs) - 1) ):
			if len(chain) > 0:
				chain.append(addr)
				chains.append(chain)
			continue

		addr = stack_addrs[i]
		ret_addr = Dword(addr) & 0xFFFFFFFE #adjust Thumb addresses
		to_f = str(idc.GetFunctionName(ret_addr))

		next_ret_addr = Dword(stack_addrs[i+1]) & 0xFFFFFFFE #adjust Thumb addresses

		pre_f = preceeding_call(next_ret_addr)
		if pre_f == to_f:
			chain.append(addr)

		elif jumps_to(pre_f, to_f):
			chain.append("direct jump")
			chain.append(addr)

		elif jumps_to_reg(pre_f):
			chain.append("indirect_jump?")
			chain.append(addr)
 
		#no bonus, need to start a new chain at next_ret_addr

		else:
			# if there is an existing chain, that means this addr was connected to the previous, so can be added into the chain.
			if len(chain) > 0:
				chain.append(addr)
				chains.append(chain)
			
			chain = []

	print "found all chains, logging..."

	log_stack_chains(chains)

	print "... and done!"
コード例 #11
0
def load_cro(li, is_crs):
    if is_crs:
        base = 0
    else:
        base = 0x00100000  # arbitrary

    li.seek(0x80)
    (Magic, NameOffset, NextCRO, PreviousCRO, FileSize, BssSize, FixedSize,
     UnknownZero, UnkSegmentTag, OnLoadSegmentTag, OnExitSegmentTag,
     OnUnresolvedSegmentTag, CodeOffset, CodeSize, DataOffset, DataSize,
     ModuleNameOffset, ModuleNameSize, SegmentTableOffset, SegmentNum,
     ExportNamedSymbolTableOffset, ExportNamedSymbolNum,
     ExportIndexedSymbolTableOffset, ExportIndexedSymbolNum,
     ExportStringsOffset, ExportStringsSize, ExportTreeTableOffset,
     ExportTreeNum, ImportModuleTableOffset, ImportModuleNum,
     ExternalPatchTableOffset, ExternalPatchNum, ImportNamedSymbolTableOffset,
     ImportNamedSymbolNum, ImportIndexedSymbolTableOffset,
     ImportIndexedSymbolNum, ImportAnonymousSymbolTableOffset,
     ImportAnonymousSymbolNum, ImportStringsOffset, ImportStringsSize,
     StaticAnonymousSymbolTableOffset, StaticAnonymousSymbolNum,
     InternalPatchTableOffset, InternalPatchNum, StaticPatchTableOffset,
     StaticPatchNum) = struct.unpack(
         "<IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII",
         li.read(0x138 - 0x80))

    if not is_crs:
        li.file2base(0, base, base + FileSize, 0)
        idaapi.add_segm(0, base, base + 0x80, "header", "RODATA")
        idaapi.add_segm(0, base + SegmentTableOffset, base + DataOffset,
                        "tables", "RODATA")

    # set segments
    li.seek(SegmentTableOffset)
    segmentDic = [("CODE", ".text"), ("DATA", ".rodata"), ("DATA", ".data"),
                  ("BSS", ".bss")]
    segmentAddress = []
    for i in range(SegmentNum):
        SegmentOffset, SegmentSize, SegmentType = struct.unpack(
            "<III", li.read(12))
        if SegmentType == 3:
            SegmentOffset = 0x08000000
            idaapi.enable_flags(base + SegmentOffset,
                                base + SegmentOffset + SegmentSize,
                                idaapi.STT_VA)

        segmentAddress.append(base + SegmentOffset)
        if SegmentSize:
            idaapi.add_segm(0, segmentAddress[i],
                            segmentAddress[i] + SegmentSize,
                            segmentDic[SegmentType][1],
                            segmentDic[SegmentType][0])

    # do internal relocations
    li.seek(InternalPatchTableOffset)
    for i in range(InternalPatchNum):
        target, patch_type, source, _, _, shift = struct.unpack(
            "<IBBBBI", li.read(12))
        target_offset = DecodeTag(segmentAddress, target)
        source_offset = segmentAddress[source] + shift
        if patch_type == 2:
            value = source_offset
        elif patch_type == 3:
            rel = source_offset - target_offset
            if rel < 0:
                rel += 0x100000000
            value = rel
        idaapi.patch_long(target_offset, value)
        f = idaapi.fixup_data_t()
        f.type = idaapi.FIXUP_OFF32
        f.off = value
        idaapi.set_fixup(target_offset, f)

    # import
    li.seek(ImportNamedSymbolTableOffset)
    importNamedSymbolTable = []
    for i in range(ImportNamedSymbolNum):
        importNamedSymbolTable.append(struct.unpack('<II', li.read(8)))

    for importNamedSymbol in importNamedSymbolTable:
        nameOffset, batchOffset = importNamedSymbol
        li.seek(nameOffset)
        name = ""
        while True:
            c = li.read(1)
            if c == '\0':
                break
            name += c
        do_import_batch(li, segmentAddress, batchOffset, name)

    li.seek(ImportModuleTableOffset)
    module = []
    for i in range(ImportModuleNum):
        module.append(struct.unpack('<IIIII', li.read(20)))

    for m in module:
        moduleNameOffset, indexed, indexedNum, anonymous, anonymousNum = m
        li.seek(moduleNameOffset)
        mname = ""
        while True:
            c = li.read(1)
            if c == '\0':
                break
            mname += c

        indexeds = []
        li.seek(indexed)
        for i in range(indexedNum):
            indexeds.append(struct.unpack('<II', li.read(8)))

        anonymouses = []
        li.seek(anonymous)
        for i in range(anonymousNum):
            anonymouses.append(struct.unpack('<II', li.read(8)))

        for i in indexeds:
            index, batchOffset = i
            do_import_batch(li, segmentAddress, batchOffset,
                            "%s_%d" % (mname, index))

        for i in anonymouses:
            tag, batchOffset = i
            do_import_batch(li, segmentAddress, batchOffset,
                            "%s_%08X" % (mname, tag))

    # export
    li.seek(ExportNamedSymbolTableOffset)
    exportNamedSymbolTable = []
    for i in range(ExportNamedSymbolNum):
        exportNamedSymbolTable.append(struct.unpack('<II', li.read(8)))

    for exportNamedSymbol in exportNamedSymbolTable:
        nameOffset, target = exportNamedSymbol
        target_offset = DecodeTag(segmentAddress, target)
        li.seek(nameOffset)
        name = ""
        while True:
            c = li.read(1)
            if c == '\0':
                break
            name += c
        if idaapi.segtype(target_offset) == idaapi.SEG_CODE:
            target_offset &= ~1
        idaapi.add_entry(target_offset, target_offset, name,
                         idaapi.segtype(target_offset) == idaapi.SEG_CODE)
        idaapi.make_name_public(target_offset)

    li.seek(ExportIndexedSymbolTableOffset)
    for i in range(ExportIndexedSymbolNum):
        target, = struct.unpack('<I', li.read(4))
        target_offset = DecodeTag(segmentAddress, target)
        if idaapi.segtype(target_offset) == idaapi.SEG_CODE:
            target_offset &= ~1
        idaapi.add_entry(i, target_offset, "indexedExport_%d" % i,
                         idaapi.segtype(target_offset) == idaapi.SEG_CODE)
        idaapi.make_name_public(target_offset)
コード例 #12
0
ファイル: cro.py プロジェクト: JamePeng/IDA_plugin_CRO
def load_cro(li, is_crs):
    if is_crs:
        base = 0
    else:
        base = 0x00100000 # arbitrary

    li.seek(0x80)
    (Magic,
    NameOffset,
    NextCRO,
    PreviousCRO,
    FileSize,
    BssSize,
    FixedSize,
    UnknownZero,
    UnkSegmentTag,
    OnLoadSegmentTag,
    OnExitSegmentTag,
    OnUnresolvedSegmentTag,

    CodeOffset,
    CodeSize,
    DataOffset,
    DataSize,
    ModuleNameOffset,
    ModuleNameSize,
    SegmentTableOffset,
    SegmentNum,

    ExportNamedSymbolTableOffset,
    ExportNamedSymbolNum,
    ExportIndexedSymbolTableOffset,
    ExportIndexedSymbolNum,
    ExportStringsOffset,
    ExportStringsSize,
    ExportTreeTableOffset,
    ExportTreeNum,

    ImportModuleTableOffset,
    ImportModuleNum,
    ExternalPatchTableOffset,
    ExternalPatchNum,
    ImportNamedSymbolTableOffset,
    ImportNamedSymbolNum,
    ImportIndexedSymbolTableOffset,
    ImportIndexedSymbolNum,
    ImportAnonymousSymbolTableOffset,
    ImportAnonymousSymbolNum,
    ImportStringsOffset,
    ImportStringsSize,

    StaticAnonymousSymbolTableOffset,
    StaticAnonymousSymbolNum,
    InternalPatchTableOffset,
    InternalPatchNum,
    StaticPatchTableOffset,
    StaticPatchNum) = struct.unpack("<IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII", li.read(0x138 - 0x80))

    if not is_crs:
        li.file2base(0, base, base + FileSize, 0)

    # set segments
    li.seek(SegmentTableOffset)
    segmentDic = [
        ("CODE", ".text"),
        ("DATA", ".rodata"),
        ("DATA", ".data"),
        ("BSS", ".bss")
    ]
    segmentAddress = []
    for i in range(SegmentNum):
        SegmentOffset, SegmentSize, SegmentType = struct.unpack("<III", li.read(12))
        if SegmentType == 3:
            SegmentOffset = 0x08000000
            idaapi.enable_flags(base + SegmentOffset, base + SegmentOffset + SegmentSize, idaapi.STT_VA)

        segmentAddress.append(base + SegmentOffset)
        if SegmentSize :
            idaapi.add_segm(0, segmentAddress[i], segmentAddress[i] + SegmentSize, segmentDic[SegmentType][1], segmentDic[SegmentType][0])

    # do internal relocations
    li.seek(InternalPatchTableOffset)
    for i in range(InternalPatchNum):
        target, patch_type, source, _, _, shift = struct.unpack("<IBBBBI", li.read(12))
        target_offset = DecodeTag(segmentAddress, target)
        source_offset = segmentAddress[source] + shift
        if patch_type == 2:
            value = source_offset
        elif patch_type == 3:
            rel = source_offset - target_offset
            if rel < 0:
                rel += 0x100000000
            value = rel
        idaapi.patch_long(target_offset, value)
        f = idaapi.fixup_data_t()
        f.type = idaapi.FIXUP_OFF32
        f.off = value
        idaapi.set_fixup(target_offset, f)

    # import
    li.seek(ImportNamedSymbolTableOffset)
    importNamedSymbolTable = []
    for i in range(ImportNamedSymbolNum):
        importNamedSymbolTable.append(struct.unpack('<II', li.read(8)))

    for importNamedSymbol in importNamedSymbolTable:
        nameOffset, batchOffset = importNamedSymbol
        li.seek(nameOffset)
        name = ""
        while True:
            c = li.read(1)
            if c == '\0':
                break
            name += c
        do_import_batch(li, segmentAddress, batchOffset, name)

    li.seek(ImportModuleTableOffset)
    module = []
    for i in range(ImportModuleNum):
        module.append(struct.unpack('<IIIII', li.read(20)))

    for m in module:
        moduleNameOffset, indexed, indexedNum, anonymous, anonymousNum = m
        li.seek(moduleNameOffset)
        mname = ""
        while True:
            c = li.read(1)
            if c == '\0':
                break
            mname += c

        indexeds = []
        li.seek(indexed)
        for i in range(indexedNum):
            indexeds.append(struct.unpack('<II', li.read(8)))

        anonymouses = []
        li.seek(anonymous)
        for i in range(anonymousNum):
            anonymouses.append(struct.unpack('<II', li.read(8)))

        for i in indexeds:
            index, batchOffset = i
            do_import_batch(li, segmentAddress, batchOffset, "%s_%d"%(mname, index))

        for i in anonymouses:
            tag, batchOffset = i
            do_import_batch(li, segmentAddress, batchOffset, "%s_%08X"%(mname, tag))

    # export
    li.seek(ExportNamedSymbolTableOffset)
    exportNamedSymbolTable = []
    for i in range(ExportNamedSymbolNum):
        exportNamedSymbolTable.append(struct.unpack('<II', li.read(8)))

    for exportNamedSymbol in exportNamedSymbolTable:
        nameOffset, target = exportNamedSymbol
        target_offset = DecodeTag(segmentAddress, target)
        li.seek(nameOffset)
        name = ""
        while True:
            c = li.read(1)
            if c == '\0':
                break
            name += c
        idaapi.add_entry(target_offset, target_offset, name, idaapi.segtype(target_offset) == idaapi.SEG_CODE)
        idaapi.make_name_public(target_offset)

    li.seek(ExportIndexedSymbolTableOffset)
    for i in range(ExportIndexedSymbolNum):
        target, = struct.unpack('<I', li.read(4))
        target_offset = DecodeTag(segmentAddress, target)
        idaapi.add_entry(i, target_offset, "indexedExport_%d" % i, idaapi.segtype(target_offset) == idaapi.SEG_CODE)
        idaapi.make_name_public(target_offset)