def find_unusual_xors(functions):
    # TODO find xors in tight loops
    candidate_functions = []
    for fva in functions:
        cva = fva
        while cva != idaapi.BADADDR and cva < idc.FindFuncEnd(fva):
            if idc.GetMnem(cva) == "xor":
                if idc.GetOpnd(cva, 0) != idc.GetOpnd(cva, 1):
                    g_logger.debug(
                        "suspicious XOR instruction at 0x%08X in function 0x%08X: %s",
                        cva, fva, idc.GetDisasm(cva))
                    ph = idc.PrevHead(cva)
                    nh = idc.NextHead(cva)
                    ip = idc.GetDisasm(ph)
                    ia = idc.GetDisasm(nh)
                    if ip and ia:
                        g_logger.debug("Instructions: %s;  %s;  %s", ip,
                                       idc.GetDisasm(cva), ia)
                    if ph or nh:
                        if is_security_cookie(cva, ph, nh):
                            g_logger.debug(
                                "XOR related to security cookie: %s",
                                idc.GetDisasm(cva))
                        else:
                            g_logger.debug("unusual XOR: %s",
                                           idc.GetDisasm(cva))
                            candidate_functions.append(fva)
                            break
            cva = idc.NextHead(cva)
    return candidate_functions
示例#2
0
    def hex_ray(self, start, end):
        contents = ''

        current = start
        self.last_branch = start
        while current < end:
            #			if current != start:
            # Write reference addresses
            contents = self.AppendRefAddr(current, self.func_ref_list,
                                          contents)

            # assmbly dispatch
            line, n_addr = self.asm.dispatch(current, self.reg, self.func)

            # apply dispatch result
            contents = self.AppendNewLine(line, contents)

            if n_addr:
                current = idc.NextHead(n_addr, end)
            else:
                current = idc.NextHead(current, end)

        self.bmgr.InsertRegStatus(self.last_branch, self.reg)

        return contents
def find_suspicous_movs(functions):
    candidate_functions = []
    regs = ["esp", "ebp", "rsp", "rbp"]
    for fva in functions:
        for (loopStart, loopEnd) in find_tight_loops(fva):
            cva = loopStart
            while cva <= loopEnd:
                if idc.GetMnem(cva) == "mov":
                    if is_list_item_in_s(regs, idc.GetOpnd(cva, 0)):
                        cva = idc.NextHead(cva)
                        continue
                    # identify register dereferenced writes to memory, e.g. mov [eax], cl
                    if idc.GetOpType(cva, 0) == OP_TYPE.BASE_INDEX.value:
                        if idc.GetOpType(cva, 1) not in [
                                OP_TYPE.IMMEDIATE.value,
                                OP_TYPE.IMMEDIATE_FAR.value,
                                OP_TYPE.IMMEDIATE_NEAR.value
                        ]:
                            g_logger.debug(
                                "suspicious MOV instruction at 0x%08X in function 0x%08X: %s",
                                cva, fva, idc.GetDisasm(cva))
                            candidate_functions.append(fva)
                            break
                cva = idc.NextHead(cva)
    return candidate_functions
示例#4
0
def _split_basic_block(start_ea, end_ea):
    """
    IDA Pro's ``idaapi.Flowchart`` does not consider function calls as basic
    block boundaries. This function takes an address range and splits the
    basic blocks found within that range so that function calls are considered
    basic block boundaries.
    """
    split_bbs = []
    func_name = idc.GetFunctionName(start_ea)
    demangled_name = idc.Demangle(func_name, idc.GetLongPrm(idc.INF_SHORT_DN))
    if demangled_name:
        func_name = demangled_name

    bb_start_addr = start_ea
    block = idautils.Heads(start_ea, end_ea)

    for inst in block:
        mnem = idc.GetMnem(inst)
        if mnem == 'call' and inst != end_ea:
            split_bbs.append(
                dict(start_addr=bb_start_addr,
                     end_addr=idc.NextHead(inst, end_ea + 1) - 1,
                     function=func_name))
            bb_start_addr = idc.NextHead(inst, end_ea + 1)

    if bb_start_addr < end_ea:
        split_bbs.append(
            dict(start_addr=bb_start_addr,
                 end_addr=end_ea - 1,
                 function=func_name))

    return split_bbs
    def functionDummyTracer(self, addr, debug=False):
        idx = 0
        depth = self.depth
        result = []
        ep = addr

        dummy = False

        while idx < depth:
            idx = idx + 1
            #print( 'DUMMY : {0} {1} {2} {3}'.format(idx, hex(addr).rstrip('L'), idc.GetDisasm(addr), hex(get_operand_value(addr,0)) ))
            if debug is True:
                print('{0} {1} {2} {3}'.format(idx,
                                               hex(addr).rstrip('L'),
                                               idc.GetDisasm(addr),
                                               hex(get_operand_value(addr,
                                                                     0))))

            #dummy = self.findDummyGadget(addr)

            if idc.GetDisasm(addr)[:4] == "retn":
                break

            elif idc.GetDisasm(addr)[:3] == "jmp" or idc.GetDisasm(
                    addr)[:4] == "call":
                #print get_operand_value(addr,0)
                addr = get_operand_value(addr, 0)

            elif self.findFirstDummyGadget(addr) == True:
                #print "MATCH FIRST"
                if len(result) > 0:
                    result = []
                result.append(self.getGadget(addr, ep, 1))
                addr = idc.NextHead(addr)

            elif len(result) == 1 and self.findSecondDummyGadget(
                    addr, result[0]['reg']) == True:
                #input gadget
                result.append(self.getGadget(addr, ep, 2))
                addr = idc.NextHead(addr)

            elif len(result) == 2 and self.findThirdDummyGadget(
                    addr, result[0]['reg']) == True:
                result.append(self.getGadget(addr, ep, 3))
                addr = idc.NextHead(addr)

            else:
                addr = idc.NextHead(addr)

        if debug is True and len(result) > 0:
            for x in result:
                print("{0} : {1} {2} ".format(
                    hex(x['addr']).rstrip('L'), hex(x['const']), x['gadget']))

        print ""
        if len(result) == 3:
            return result
        else:
            return False
示例#6
0
def add_xrefs(addr, end=idc.BADADDR):
    """
        https://github.com/xyzz/vita-ida-physdump/blob/master/vita_phys_dump.py
        Searches for MOV / MOVT pair, probably separated by few instructions,
        and adds xrefs to things that look like addresses
    """
    while addr < end and addr != BADADDR:
        addr = idc.NextHead(addr)
        if idc.GetMnem(addr) in ["MOV", "MOVW"]:
            reg = idc.GetOpnd(addr, 0)
            if idc.GetOpnd(addr, 1)[0] != "#":
                continue
            val = idc.GetOperandValue(addr, 1)
            found = False
            next_addr = addr
            for x in range(16):
                next_addr = idc.NextHead(next_addr)
                if idc.GetMnem(next_addr) in ["B", "BX"]:
                    break
                # TODO: we could handle a lot more situations if we follow branches, but it's getting complicated
                # if there's a function call and our register is scratch, it will probably get corrupted, bail out
                if idc.GetMnem(next_addr) in ["BL", "BLX"] and reg in [
                        "R0", "R1", "R2", "R3"
                ]:
                    break
                # if we see a MOVT, do the match!
                if idc.GetMnem(next_addr) in ["MOVT",
                                              "MOVT.W"] and idc.GetOpnd(
                                                  next_addr, 0) == reg:
                    if idc.GetOpnd(next_addr, 1)[0] == "#":
                        found = True
                        val += idc.GetOperandValue(next_addr, 1) * (2**16)
                    break
                # if we see something other than MOVT doing something to the register, bail out
                if idc.GetOpnd(next_addr, 0) == reg or idc.GetOpnd(
                        next_addr, 1) == reg:
                    break
            if val & 0xFFFF0000 == 0:
                continue
            if found:
                # pair of MOV/MOVT
                try:
                    idc.OpOffEx(addr, 1, idc.REF_LOW16, val, 0, 0)
                    idc.OpOffEx(next_addr, 1, idc.REF_HIGH16, val, 0, 0)
                except:
                    print "Failed xref @ %x next_addr %x val %x" % (
                        addr, next_addr, val)
            else:
                # a single MOV instruction
                try:
                    idc.OpOff(addr, 1, 0)
                except:
                    print "Failed xref at addr %x" % (addr)
def nextProcName(startAddr, endAddr):
    addr = startAddr
    while addr < endAddr:
        mnem = idc.GetMnem(addr)
        if mnem == 'push':
            optype = idc.GetOpType(addr, 0)
            if optype == 5:
                procaddr = idc.GetOperandValue(addr, 0)
                procname = idc.GetString(procaddr, -1, idc.ASCSTR_C)
                return (procname, idc.NextHead(addr))
        addr = idc.NextHead(addr)
    return ('', addr)
示例#8
0
def _find_force_end(loc):
    """
    Locate the first "ret" instruction down from the input location

    :param loc: Location a function is needed at

    :return: ItemEnd of the return location.
    """
    loc = idc.NextHead(loc)
    while not idc.isAlign(idc.GetFlags(loc)) and not idaapi.get_func(loc):
        if "ret" in idc.GetMnem(loc):
            return idc.ItemEnd(loc)
        loc = idc.NextHead(loc)
    return idc.ItemEnd(idc.PrevHead(loc))
def nextProcAddr(startAddr, endAddr):
    addr = startAddr
    while addr < endAddr:
        mnem = idc.GetMnem(addr)
        if mnem == 'mov':
            op1type = idc.GetOpType(addr, 0)
            op2type = idc.GetOpType(addr, 1)
            if op1type == 4 and op2type == 1:
                regname = idc.GetOpnd(addr, 1)
                if regname == 'eax':
                    offset = idc.GetOperandValue(addr, 0)
                    return (IMPORTS_START + offset, idc.NextHead(addr))
        addr = idc.NextHead(addr)
    return (-1, addr)
示例#10
0
    def _find_leafs(self):
        # Loop through every function
        for func_ea in idautils.Functions():
            # Count the number of xrefs to this function
            func = idaapi.get_func(func_ea)
            if func:
                leaf_function = True
                ea = func.startEA

                # Loop through all instructions in this function looking
                # for call instructions; if found, then this is not a leaf.
                while ea <= func.endEA:
                    idaapi.decode_insn(ea)
                    if idaapi.is_call_insn(ea):
                        leaf_function = False
                        break

                    ea = idc.NextHead(ea)

                if leaf_function:
                    self.functions.append(
                        Function(start=func.startEA,
                                 end=func.endEA,
                                 leaf=True,
                                 loop=self.has_loop(func),
                                 argc=self.argp.argc(func)))

        # Sort leafs by xref count, largest first
        self.functions.sort(key=lambda f: f.xrefs, reverse=True)
示例#11
0
	def GetBranchList(self, start=None, end=None):
		branch_list = list()

		current = start
		if self.arc == ARCHITECTURE['MIPS']:
			branch_obj = self.asm.mips_asm_class['branch']
			jump_obj = self.asm.mips_asm_class['jump']

			while current <= end:
				method = 'do_' + idc.GetMnem(current)
				if hasattr(branch_obj, method) or hasattr(jump_obj, method):
					if idc.GetOpType(current, 0) == ASM_TYPE['Imm_Near_Addr']:
						opr = idc.LocByName(idc.GetOpnd(current, 0))
						if opr in self.func_ref_list:
							branch_list.append(hex(opr))
					elif idc.GetOpType(current, 1) == ASM_TYPE['Imm_Near_Addr']:
						opr = idc.LocByName(idc.GetOpnd(current, 1))
						if opr in self.func_ref_list:
							branch_list.append(hex(opr))
					elif idc.GetOpType(current, 2) == ASM_TYPE['Imm_Near_Addr']:
						opr = idc.LocByName(idc.GetOpnd(current, 2))
						if opr in self.func_ref_list:
							branch_list.append(hex(opr))

				current = idc.NextHead(current, end)

		branch_list = list(set(branch_list))
		branch_list.sort()

		return branch_list
示例#12
0
def search_function():
    curr_addr = MinEA()
    end = MaxEA()
    current_func_name = ""
    while curr_addr < end:
        if curr_addr == idc.BADADDR:
            break
        elif idc.GetMnem(curr_addr) == 'call':
            if idc.GetOpnd(curr_addr, 0) in FUNCTIONS_REGISTERS.keys():
                func_name_addr = get_string_for_function(
                    curr_addr, FUNCTIONS_REGISTERS[idc.GetOpnd(curr_addr,
                                                               0)].lower())
                if func_name_addr:
                    try:
                        function_start = idc.GetFunctionAttr(
                            curr_addr, idc.FUNCATTR_START)
                        new_filename = get_fixed_source_filename(
                            func_name_addr)
                        current_func_name = idc.GetFunctionName(function_start)
                        if is_function_name(current_func_name):
                            idaapi.set_name(function_start, new_filename,
                                            idaapi.SN_FORCE)
                        else:
                            print "Function:", current_func_name, "was not changed"
                    except:
                        print "failed at address " + hex(curr_addr), \
                            "function:", current_func_name, "call:", idc.GetOpnd(curr_addr, 0)
        curr_addr = idc.NextHead(curr_addr)
示例#13
0
def ChunkMovePart(inner_start, inner_end_ex, function_address):
    # maybe the given range covers multiple chunks
    result = []
    fn_print("MACRO move 0x%x-0x%x to 0x%x" %
             (inner_start, inner_end_ex, function_address))

    DisableAutoAnalysis()

    current_inner_start = inner_start
    while current_inner_start < inner_end_ex:
        chunk_start = idc.GetFchunkAttr(current_inner_start,
                                        idc.FUNCATTR_START)
        chunk_end_ex = idc.GetFchunkAttr(current_inner_start, idc.FUNCATTR_END)

        new_inner_end_ex = inner_end_ex
        if chunk_end_ex < inner_end_ex:
            new_inner_end_ex = chunk_end_ex

        result.extend(
            _ChunkMovePart(current_inner_start, new_inner_end_ex,
                           function_address))

        current_inner_start = idc.GetFchunkAttr(current_inner_start,
                                                idc.FUNCATTR_END)
        while not InsIsCode(current_inner_start):
            current_inner_start = idc.NextHead(current_inner_start)
            assert current_inner_start != BADADDR
        #endwhile
    #endwhile

    EnableAutoAnalysis()

    return result
示例#14
0
def FunctionAppendChunk(function_address, A, B_ex):
    # CAVEAT this function also adds successor hanging instructions!
    if idaapi.get_func(A) is not None:
        fn_print("0x%x-0x%x already in function" % (A, B_ex))
        return False

    fn_print("append chunk 0x%x-0x%x to function 0x%x" %
             (A, B_ex, function_address))

    # watch out with hanging instructions
    if (idaapi.get_func(A) is None) and (idaapi.get_func(idc.PrevHead(B_ex))
                                         is not None):
        fn_print("chunk 0x%x-0x%x is part hanging, only moving hanging part" %
                 (A, B_ex))
        B_ex = A
        while idaapi.get_func(B_ex) is None:
            B_ex = idc.NextHead(B_ex)
        fn_print("  ... instead moving 0x%x-0x%x" % (A, B_ex))

    result = idc.AppendFchunk(function_address, A, B_ex)
    if do_wait:
        idc.Wait()

    fn_print("append-chunk 0x%x-0x%x to 0x%x: %d" %
             (A, B_ex, function_address, result))

    if result:
        now_address = idc.GetFunctionAttr(A, idc.FUNCATTR_START)
        f2 = idc.GetFunctionAttr(function_address, idc.FUNCATTR_START)
        assert f2 == now_address, "0x%x/0x%x/0x%x" % (function_address,
                                                      now_address, f2)
    return result
示例#15
0
    def GetBranchList(self, start=None, end=None):
        self.branch_list = list()

        current = start
        if self.arc == ARCHITECTURE['MIPS']:
            o_iasm = mips_iasm.MIPS_IAsm()
            branch_obj = o_iasm.mips_asm_class['branch']
            jump_obj = o_iasm.mips_asm_class['jump']

            while current <= end:
                method = 'do_' + idc.GetMnem(current)
                if hasattr(branch_obj, method) or hasattr(jump_obj, method):
                    if self.isNearAddr(idc.GetOpType(current, 0)):
                        opr = idc.LocByName(idc.GetOpnd(current, 0))
                        if opr in self.func_ref_list:
                            self.branch_list.append(hex(opr))
                    elif self.isNearAddr(idc.GetOpType(current, 1)):
                        opr = idc.LocByName(idc.GetOpnd(current, 1))
                        if opr in self.func_ref_list:
                            self.branch_list.append(hex(opr))
                    elif self.isNearAddr(idc.GetOpType(current, 2)):
                        opr = idc.LocByName(idc.GetOpnd(current, 2))
                        if opr in self.func_ref_list:
                            self.branch_list.append(hex(opr))

                current = idc.NextHead(current, end)

        self.branch_list = list(set(self.branch_list))
        self.branch_list.sort()

        return self.branch_list
示例#16
0
def NthHead(ea, dist):
    if dist == 0:
        return ea
    elif dist < 0:
        return NthHead(idc.PrevHead(ea), dist + 1)
    elif dist > 0:
        return NthHead(idc.NextHead(ea), dist - 1)
示例#17
0
    def run(self):
        self.loadInstructionList()
        self.loadInstructionGroups()
        functionNamesToEA = {}

        ea = idc.BeginEA()
        count = 0
        for funcea in Functions(idc.SegStart(ea), idc.SegEnd(ea)):
            functionInstructions = copy.deepcopy(self.instructions)
            functionGroups = copy.deepcopy(self.groups)
            sum = 0
            allGroupSum = 0
            functionName = idc.GetFunctionName(funcea)
            functionNamesToEA[functionName] = funcea
            originalfuncea = funcea
            currentea = funcea
            while currentea != idc.BADADDR and currentea < idc.FindFuncEnd(
                    funcea):
                currentInstruction = idc.GetMnem(currentea)
                if currentInstruction in self.instructions.keys():
                    functionInstructions[currentInstruction] += 1
                    sum += 1

                for group in self.groups.keys():
                    if currentInstruction in self.groups[group][0].keys():
                        functionGroups[group][1] += 1
                        functionGroups[group][0][currentInstruction] += 1
                        allGroupSum += 1

                currentea = idc.NextHead(currentea)
            self.writeInstructionFeatures(self.instructions, sum,
                                          functionInstructions, functionName)
            self.writeInstructionGroupFeatures(self.groups, allGroupSum,
                                               functionGroups, functionName)
        return functionNamesToEA
示例#18
0
def calBasicBlockFeature_gemini(block):
    numericNum = 0
    stringNum = 0
    transferNum = 0
    callNum = 0
    InstrNum = 0
    arithNum = 0
    logicNum = 0
    curEA = block.startEA
    while curEA <= block.endEA:
        #	数值常量 , 字符常量的数量
        numer, stri = calConstantNumber(curEA)
        numericNum = numericNum + numer
        stringNum = stringNum + stri
        #	转移指令的数量
        if idc.GetMnem(curEA) in config_for_feature.Gemini_allTransferInstr:
            transferNum = transferNum + 1
        # 调用的数量
        if idc.GetMnem(curEA) == 'call':
            callNum = callNum + 1
        # 指令的数量
        InstrNum = InstrNum + 1
        #	算术指令的数量
        if idc.GetMnem(curEA) in config_for_feature.Gemini_arithmeticInstr:
            arithNum = arithNum + 1
        #  逻辑指令
        if idc.GetMnem(curEA) in config_for_feature.Gemini_logicInstr:
            logicNum = logicNum + 1

        curEA = idc.NextHead(curEA, block.endEA)

    fea_str = str(numericNum) + "," + str(stringNum) + "," + str(
        transferNum) + "," + str(callNum) + "," + str(InstrNum) + "," + str(
            arithNum) + "," + str(logicNum) + ","
    return fea_str
示例#19
0
def BackwardAnalysis(target_addr, target_reg, start_addr=None, state_cache={}):
    possible_vals = []

    # Obtain backward path
    # print("calculate the backward path")
    target_bbl = GetBBLFromEA(target_addr)
    backward_path = SampleBackwardPath(target_bbl.startEA, start_addr)
    backward_path = backward_path[1:]
    backward_path.reverse()

    # Prepate state
    # print("pre-execute")
    state = ExecuteSymbolicBBLeas(backward_path, state_cache=state_cache)
    # print("execute ok")
    # state = ExecuteSymbolicBBLs(backward_path)

    addr = target_bbl.startEA
    if start_addr != None and target_bbl.startEA <= start_addr and start_addr < target_bbl.endEA:
        addr = start_addr
    while addr < target_addr:
        state = ExecuteSymbolicSingleStep(addr, state)
        addr = idc.NextHead(addr)
    possible_val = None
    if target_reg in state:
        possible_val = state[target_reg]
        # Minimalize
        while possible_val in state.keys():
            possible_val = state[possible_val]
    return [possible_val]
示例#20
0
def gen_skeleton_and_eas(reg):
    ea = idc.ScreenEA()
    start = idc.GetFunctionAttr(ea, idc.FUNCATTR_START)
    end = idc.GetFunctionAttr(ea, idc.FUNCATTR_END)
    ea = start
    eas = []
    skeleton = {}
    while ea <= end:
        if idaapi.decode_insn(ea) == 0:
            print 'error in {0}'.format(GetDisasm(ea))
        else:
            for opn in (0, 1):
                op = idaapi.cmd.Operands[opn]
                offset = 0
                if op.type == idaapi.o_idpspec3:
                    continue
                if op.type in (idaapi.o_phrase,
                               idaapi.o_displ) and op.phrase == phrase[reg]:
                    skeleton[op.addr] = ('field_{0}'.format(hex(op.addr)),
                                         dtyp[op.dtyp])
                    eas.append((ea, opn, offset))
        ea = idc.NextHead(ea)
    skeleton = [(elem[0], elem[1][0], elem[1][1])
                for elem in sorted(skeleton.items(), key=lambda x: x[0])]
    return [skeleton, eas]
示例#21
0
    def revBlock(self):
        cur_addr = idc.GetRegValue(self.PC)
        f = idaapi.get_func(cur_addr)
        if f is None:
            print(
                'Ida analysis sees no function, cannot perform this function')
            return
        fc = idaapi.FlowChart(f)
        block_start = None
        prev_addr = None
        prev_block = None
        for block in fc:
            block_start = block.startEA
            #print('block_start 0x%x, cur_addr is 0x%x' % (block_start, cur_addr))
            if block_start > cur_addr:
                break
            prev_addr = block_start
            prev_block = block

        if prev_addr == cur_addr:
            self.doRevStepInto()
        elif prev_addr is not None:
            next_addr = idc.NextHead(prev_addr)
            if next_addr == cur_addr:
                ''' reverse two to get there? '''
                print('revBlock rev two?')
                self.doRevStepInto()
                self.doRevStepInto()
            else:
                print('revBlock rev to 0x%x' % prev_addr)
                self.doRevToAddr(prev_addr, extra_back=0)
        else:
            print('must have been top, uncall')
            self.doRevFinish()
示例#22
0
 def find_interesting_xors(self):
     next_xor = idc.FindText(idc.MinEA(), idc.SEARCH_DOWN | idc.SEARCH_NEXT,
                             0, 0, "xor")
     while next_xor != idc.BADADDR:
         if idc.GetOpnd(next_xor, 0) != idc.GetOpnd(next_xor, 1):
             entry = {
                 "func": "",
                 "addr": next_xor,
                 "loop": False,
                 "disasm": idc.GetDisasm(next_xor)
             }
             func = idaapi.get_func(next_xor)
             if func:
                 entry["func"] = idaapi.get_name(idc.BADADDR, func.startEA)
                 heads = idautils.Heads(next_xor, func.endEA)
                 lxors = []
                 for head in heads:
                     if idc.GetMnem(head).startswith('j'):
                         jmp_addr = idc.GetOperandValue(head, 0)
                         if jmp_addr < next_xor and jmp_addr > func.startEA:
                             entry["loop"] = True
                             break
             self._interesting_xors.append(entry)
         next_xor = idc.FindText(idc.NextHead(next_xor),
                                 idc.SEARCH_DOWN | idc.SEARCH_NEXT, 0, 0,
                                 "xor")
示例#23
0
    def revise_syscall(rename=False):
        if not rename:
            print(
                'Change the function name with `CGCHeler.revise_syscall(True)`.'
            )

        # visit all instructions
        start_ea, end_ea = utils.get_seg_range('.text')
        eax = -1
        ip = start_ea
        while ip < end_ea and ip != idaapi.BADADDR:
            if 'int' in idc.GetMnem(ip) and '80h' == idc.GetOpnd(ip, 0):
                if eax != -1:
                    # fix comment and function name
                    print('{}: {}'.format(hex(ip), syscall_table[eax]))
                    idc.MakeComm(ip,
                                 'CGC syscall: {}'.format(syscall_table[eax]))
                    if rename:
                        print('Change {} to {}'.format(idc.GetFunctionName(ip),
                                                       syscall_table[eax]))
                        idc.MakeName(
                            idc.GetFunctionAttr(ip, idc.FUNCATTR_START),
                            syscall_table[eax])
            elif 'mov' in idc.GetMnem(ip) and 'eax' == idc.GetOpnd(
                    ip, 0) and 5 == idc.GetOpType(ip, 1):
                value = idc.GetOpnd(ip, 1)
                if re.search('^[0-9]+$', value) != None:
                    eax = int(value)
                if eax > 7 or eax < 1:
                    eax = -1

            ip = idc.NextHead(ip)
示例#24
0
def SetAllConditionBpt():
    ea = 0x2C13000
    while ea < 0x357D000:
        mnem = idc.GetMnem(ea)
        if mnem == 'retn':
            idc.add_bpt(ea)
        ea = idc.NextHead(ea)
示例#25
0
def DelAllConditionBpt():
    ea = 0x2C13000
    while ea < 0x357D000:
        mnem = idc.GetMnem(ea)
        if mnem == 'jmp' or mnem == 'retn':
            idc.DelBpt(ea)
        ea = idc.NextHead(ea)
示例#26
0
def extract_smi_number(emu, start, end, start_pseudo_taint,
                       dispatch_proto_offset):
    """
    Find call(s) to Register(). Since we are dealing with 64-bit binaries and
    the address of Register() is the first member of a struct, a call to it
    will require a dereferencement of the struct pointer with a 'qword ptr'
    instruction.  Here we are looking for which register contains the address
    of the struct and then identify all the 'qword ptr' on that register
    (before any other modifications are made to it).
    """

    reg_called = ""
    call_to_register = ""
    nb_calls = 0
    addr_tmp = start_pseudo_taint

    while addr_tmp <= end:
        addr_tmp = idc.NextHead(addr_tmp)

        # Exit when 'reg_called' is being modified a second time (it doesn't
        # contains the address we are looking for anymore.
        if GetOpnd(addr_tmp, 0) == reg_called:
            reg_called = ""
        # A register is being set with the interface's address
        if GetOpnd(addr_tmp, 1) == dispatch_proto_offset:
            reg_called = GetOpnd(addr_tmp, 0)
        # This is what we are looking for
        elif reg_called != "" and GetMnem(addr_tmp) == "call" and GetOpnd(
                addr_tmp, 0) == "qword ptr [{}]".format(reg_called):
            next_call = addr_tmp
            f.write("  [+] Register() is called at : {}\n".format(
                hex(addr_tmp)))
            nb_calls += 1

            # Get SMI input value
            f.write("  [+] Starting emulation from {} to {}\n".format(
                hex(start), hex(addr_tmp)))
            #emu.hook_add(UC_HOOK_CODE, hook_debug)
            emu.hook_add(UC_HOOK_CODE, hook_skip_calls)
            emu.hook_add(
                UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED,
                hook_mem_invalid)
            emu.emu_start(start, addr_tmp)

            r8 = emu.reg_read(UC_X86_REG_R8)
            if r8 == 0xffffffff:
                f.write("  [-] SMI number unknown (-1).\n")
                continue
            if r8 > STACK_ADDR and r8 < STACK_ADDR + STACK_SIZE:
                smi_number = emu.mem_read(r8, 1)
            else:
                smi_number = r8
            f.write("  [+] SMI number : {}.\n".format(hex(ord(smi_number))))

            # If there is another call to Register() we will start the emulation
            # from here
            start = addr_tmp

    return nb_calls
示例#27
0
 def decode_here_clicked(self):
     inst = idc.here()
     if not idc.isCode(idc.GetFlags(inst)):
         print "Not code instruction"
     else:
         raw = idc.GetManyBytes(inst, idc.NextHead(inst) - inst)
         s = to_hex(raw)
         self.decode_ir(s)
示例#28
0
def cls_split_block(fp, startEA, endEA):
    curName = GetFunctionName(startEA)
    dem = idc.Demangle(curName, idc.GetLongPrm(INF_SHORT_DN))
    if dem != None:
        curName = dem

    first = startEA
    h = idautils.Heads(startEA, endEA)
    for i in h:
        mnem = idc.GetMnem(i)
        if mnem == "call" and i != endEA:
            print >> fp, "%#010x %#010x %s" % (
                first, idc.NextHead(i, endEA + 1) - 1, curName)
            first = idc.NextHead(i, endEA + 1)

    if first < endEA:
        print >> fp, "%#010x %#010x %s" % (first, endEA - 1, curName)
示例#29
0
	def __init__(self, addr, dispatch, o_reg, o_func):
		super(MIPS_Asm_Branch, self).__init__(addr)

		self.branch_reg = o_reg.copy()
		self.next_addr = idc.NextHead(addr)
		self.next_result, n_addr = dispatch(self.next_addr, self.branch_reg, o_func)
		# check_assert("[-] address({0}), dispatch error in branch".format(hex(self.next_addr)), result is None)
		check_assert("[-] address({0}), dispatch error in branch".format(hex(self.next_addr)), n_addr is None)
示例#30
0
def add_xrefs():
    """
        Searches for MOV / MOVT pair, probably separated by few instructions,
        and adds xrefs to things that look like addresses
    """
    addr = 0
    while addr != idc.BADADDR:
        addr = idc.NextHead(addr)
        if idc.GetMnem(addr) in ["MOV", "MOVW"]:
            reg = idc.GetOpnd(addr, 0)
            if idc.GetOpnd(addr, 1)[0] != "#":
                continue
            val = idc.GetOperandValue(addr, 1)
            found = False
            next_addr = addr
            for x in range(16):
                next_addr = idc.NextHead(next_addr)
                if idc.GetMnem(next_addr) in ["B", "BX"]:
                    break
                # TODO: we could handle a lot more situations if we follow branches, but it's getting complicated
                # if there's a function call and our register is scratch, it will probably get corrupted, bail out
                if idc.GetMnem(next_addr) in ["BL", "BLX"] and reg in [
                        "R0", "R1", "R2", "R3"
                ]:
                    break
                # if we see a MOVT, do the match!
                if idc.GetMnem(next_addr) in ["MOVT",
                                              "MOVT.W"] and idc.GetOpnd(
                                                  next_addr, 0) == reg:
                    if idc.GetOpnd(next_addr, 1)[0] == "#":
                        found = True
                        val += idc.GetOperandValue(next_addr, 1) * (2**16)
                    break
                # if we see something other than MOVT doing something to the register, bail out
                if idc.GetOpnd(next_addr, 0) == reg or idc.GetOpnd(
                        next_addr, 1) == reg:
                    break
            if val & 0xFFFF0000 == 0:
                continue
            if found:
                # pair of MOV/MOVT
                idc.OpOffEx(next_addr, 1, idc.REF_HIGH16, val, 0, 0)
            else:
                # a single MOV instruction
                idc.OpOff(addr, 1, 0)