Exemple #1
0
def XCHG(cpu_context, ip, mnem, opvalues):
    """ Exchange two values """
    opvalue1 = opvalues[0].value
    opvalue2 = opvalues[1].value
    cpu_logger.debug("XCHG 0x{:X} :: exchange {} and {}".format(ip, opvalue1, opvalue2))
    set_operand_value(cpu_context, ip, opvalue1, idc.GetOpnd(ip, 1), idc.GetOpType(ip, 1))
    set_operand_value(cpu_context, ip, opvalue2, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0))
Exemple #2
0
 def parse_STR(self, addr, regs):
     src = idc.GetOpnd(addr, 0)
     des = idc.GetOpnd(addr, 1)[1:-1]
     if src in regs:
         regs[des] = regs[src]
     else:
         regs[des] = 'Unknown'
Exemple #3
0
 def function(ea, taintSet):
     Opnd = idc.GetOpnd(ea, 0)
     #print format(ea, '04x'), Opnd, taintSet
     if Opnd in source and Opnd not in sink:
         #print 'source function %s is called, tainting operand %d' %(Opnd, source[Opnd]),
         taintSet.add('R' + str(source[Opnd]))
         #print taintSet
         #return True
     elif Opnd in source and 'R' + str(sink[Opnd]) in taintSet:
         sourceOpnd = 'R' + str(source[Opnd])
         while (idc.GetOpnd(ea, 0) != sourceOpnd):
             ea -= 2
         taintTarget = idc.GetOpnd(ea, 1)
         taintSet.add(taintTarget)
         #print 'Target %s of sink function %s tainted by operand %d' %(taintTarget, Opnd, sink[Opnd]+1), taintSet
         #return True
     elif Opnd in sink and 'R' + str(sink[Opnd]) in taintSet:
         sinkOpnd = 'R' + str(sink[Opnd])
         while (idc.GetOpnd(ea, 0) != sinkOpnd):
             ea -= 2
         taintSource = idc.GetOpnd(ea, 1)
         #print 'operand %d of sink function %s tainted by source %s' %(sink[Opnd], Opnd, taintSource)
         #return True
     else:
         #pass
         func_ea = getFunctionWithName(Opnd)
         f = get_func(func_ea)
         taintFunction(Opnd, f.startEA, 0, taintSet)
Exemple #4
0
 def one2two(ea, taintSet):
     if idc.GetOpnd(ea, 0) in taintSet:
         taintSet.add(idc.GetOpnd(ea, 1))
         #return True
     if idc.GetOpnd(ea, 1) in taintSet and idc.GetOpnd(ea,
                                                       0) not in taintSet:
         taintSet.remove(idc.GetOpnd(ea, 1))
Exemple #5
0
def IMUL(cpu_context, ip, mnem, opvalues):
    """ Signed Multiplication

    ; Single operand form
    imul    ecx     ; Signed multiply the value in ecx with the value in eax (et.al)
                    ; IDA will identify 2 operands, but only operand 1 will contain a value so 0 and 2 will be None

    ; Two operand form
    imul    edi, edx    ; Signed multiply the destination operand (op 0) with the source operand (op 1)
                        ; IDA will identify 3 operands, but operand 2 will be None

    ; Three operand form
    imul    eax, edi, 5 ; Signed multiple source operand (op 1) with the immediate value (op 2) and store in
                        ; the destination operand (op 0)

    """

    # IDA is awesome in the fact that it isn't consistent as to what operands are assigned values.  One instance it
    # may be operand 0 and 1, another might be 0 and 2, etc...However, since we are assigning a None to operands where
    # idc.GetOpnd returns "" (an empty string), then we can just remove all the opvalue list items which have a value
    # of None and this will give us our number of operands.
    RAX_REG_SIZE_MAP = {8: "RAX", 4: "EAX", 2: "AX", 1: "AL"}
    width = get_max_operand_size(opvalues)
    opvalues = [opvalue for opvalue in opvalues if opvalue.value is not None]
    op_count = len(opvalues)
    if op_count == 1:
        # if opvalues[0].value is None and opvalues[2].value is None: # Single operand form
        _mul(cpu_context, ip, mnem, opvalues)
        return
    # else:
    #    if opvalues[0].value and opvalues[1].value and opvalues[2].value is None: # Two operand form
    elif op_count == 2:
        destination = idc.GetOpnd(ip, 0)
        multiplier1 = opvalues[0].value
        multiplier2 = opvalues[1].value
        # elif opvalues[0].value and opvalues[1].value and opvalues[2].value: # Three operand form
    elif op_count == 3:
        destination = idc.GetOpnd(ip, 0)
        multiplier1 = opvalues[1].value
        multiplier2 = opvalues[2].value
    else:
        raise Exception("0x{:X}: Invalid sequence for IMUL instruction".format(ip))

    mask = utils.get_mask(width)
    result = multiplier1 * multiplier2

    cpu_context.registers.cf = int(not (
            (not utils.sign_bit(multiplier1, width) and multiplier2 & mask == 0)
            or (utils.sign_bit(multiplier1, width) and multiplier2 & mask == mask)
    ))
    cpu_context.registers.of = cpu_context.registers.cf
    cpu_context.registers.zf = int(multiplier1 & mask == 0)
    cpu_context.registers.sf = utils.sign_bit(multiplier1, width)
    cpu_context.registers.pf = get_parity(multiplier1)

    cpu_logger.debug("IMUL 0x{:X} :: {} * {} = {}".format(ip, multiplier1, multiplier2, result))
    # Notably, IDA knows that EAX is the destination for the single operand form, and properly returns
    # idc.o_reg for idc.GetOpType (though for IMUL the destination MUST be a register, so it could technically
    # be hard coded here...
    set_operand_value(cpu_context, ip, result, destination, idc.GetOpType(ip, 0))
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
Exemple #7
0
def get_args(addr):
    """ Retreives the passed arguments to the decryption function. We are only interested in the key
        and offset to the encrypted string.

        addr: (int) Address at which the decryption function was called.

        Returns:
        key: (int) The key used to decrypt the string.
        enc_str: (list) Byte array of encrypted string.
        ins_addr: (int) Address at which the encrypted byte array is referenced.

    """
    found = False
    foundstr = False
    foundkey = False
    while not found:
        addr = idc.PrevHead(addr)
        if idc.GetMnem(addr) == "mov" and "r8d" in idc.GetOpnd(addr,0):
            #print "[+] Found key: 0x%08x at 0x%016x" % (idc.GetOperandValue(addr,1)& 0xffffffff, addr)
            key = idc.GetOperandValue(addr,1) & 0xffffffff
            foundkey = True

        if idc.GetMnem(addr) == "lea" and "rdx" in idc.GetOpnd(addr,0):
            #print "[+] Found str: 0x%016x at 0x%016x" % (idc.GetOperandValue(addr,1), addr)
            enc_str_addr = idc.GetOperandValue(addr,1)
            enc_str = get_encoded_string(enc_str_addr)
            ins_addr = addr
            foundstr = True
        
        if foundkey and foundstr:
            found = True
    
    return key, enc_str, ins_addr
Exemple #8
0
def check_second_instruction(inst):
    mnem = idc.GetMnem(inst)
    if mnem != 'mov':
        return False
    if idc.GetOpnd(inst, 0) == 'r10' or idc.GetOpnd(inst, 1) == 'rcx':
        return True
    return False
Exemple #9
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)
Exemple #10
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
Exemple #11
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
Exemple #12
0
    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
Exemple #13
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")
Exemple #14
0
 def iter_fn(self, startAddr):
     """
     Generator function designed to walk all instructions within a function, parse and yield them.
     """
     endAddr = idc.GetFunctionAttr(startAddr, idc.FUNCATTR_END)
     for head in idautils.Heads(startAddr, endAddr):
         yield head, idc.GetDisasm(head).split()[0], idc.GetOpnd(head, 0), idc.GetOpnd(head, 1)
Exemple #15
0
 def disasm(self):
     l = []
     for n in self.body:
         di = "0x%08x %s %s %s" % (n, idc.GetMnem(n), idc.GetOpnd(
             n, 0), idc.GetOpnd(n, 1))
         l.append(di)
     return "\n".join(l)
Exemple #16
0
def check_operand(opnd, call_arguments, heads):
    if is_argument(opnd, call_arguments):
        return True

    for head in heads:
        if is_jump(head):
            return False

        if is_return_value(opnd) and idc.GetMnem(
                head) == 'call' and ida_funcs.func_does_return(head):
            return check_eax(head, call_arguments)

        if idc.GetMnem(head) == 'call' and is_used(head, opnd):
            return False

        if opnd != idc.GetOpnd(head, 0):
            continue

        if should_check_second_opnd(head):
            if is_number(idc.GetOpnd(head, 1)):
                return is_argument(idc.GetOpnd(head, 1), call_arguments)
            opnd = idc.GetOpnd(head, 1)

        elif (not is_number(idc.GetOpnd(head, 1))) and check_next_opnd(
                head, call_arguments):
            return True

        if is_argument(opnd, call_arguments):
            return True

    return False
Exemple #17
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)
Exemple #18
0
def parse_register_value(register, start_addr, end_addr):
    print "start find register: %s from 0x%x to 0x%x" % (register, start_addr,
                                                         end_addr)
    _addr = start_addr
    while _addr > end_addr:
        _addr = idc.PrevHead(_addr)
        _opnd_first = idc.GetOpnd(_addr, 0)
        if _opnd_first == register:
            _op_code = idc.GetMnem(_addr)
            second_opnd_type = idc.GetOpType(_addr, 1)
            print 'find register( 0x%x ) -> %s,  type1: %d,  type2: %d' % (
                _addr, idc.GetDisasm(_addr), second_opnd_type,
                idc.GetOpType(_addr, 2))
            if _op_code.startswith('LDR'):
                return parse_opnd_value(_addr, end_addr, 1)
            elif _op_code.startswith('ADD'):
                if (idc.GetOpType(_addr, 2) == 0):
                    if idc.GetOpnd(_addr, 1) == 'PC':
                        # todo: check last _op  =>  LDR             R6, =(_GLOBAL_OFFSET_TABLE_ - 0xAEB6)
                        return 0x00021DB4
                    else:
                        return parse_register_value(
                            register, _addr, end_addr) + parse_opnd_value(
                                _addr, end_addr, 1)
                else:
                    return parse_opnd_value(_addr, end_addr,
                                            1) + parse_opnd_value(
                                                _addr, end_addr, 2)
            elif _op_code.startswith('MOV'):
                return parse_register_value(idc.GetOpnd(_addr, 1), _addr,
                                            end_addr)
Exemple #19
0
def build_gcc():
    for item in class_list:
        attribute = idc.Dword(class_list[item]["addr"] + 0x10)
        num = idc.Dword(class_list[item]["addr"] + 0x14)
        if (0 <= attribute <= 4) and (0 < num < 100):
            i = 0
            while i < num:
                symbol = idc.GetOpnd(
                    class_list[item]["addr"] + 0x18 + i * 0x10, 0)
                symbol = re.sub(r'^offset ', '', symbol)
                class_list[item]["base"].append(symbol)
                virtual_attri = idc.Qword(class_list[item]["addr"] + 0x18 +
                                          i * 0x10 + 8)

                if struct.unpack('q', struct.pack('Q', virtual_attri))[0] < 0:
                    if "virtual_inherit" in class_list[item]:
                        class_list[item]["virtual_inherit"].append(symbol)
                    else:
                        class_list[item]["virtual_inherit"] = list()
                        class_list[item]["virtual_inherit"].append(symbol)
                i += 1
        else:
            symbol = idc.GetOpnd(class_list[item]["addr"] + 0x10, 0)
            symbol = re.sub(r'^offset ', '', symbol)
            addr = idc.Qword(class_list[item]["addr"] + 0x10)
            # 排除类定义到其他文件的  extern
            if (symbol[:4] == "_ZTI") and ((addr < extern_start) or
                                           (addr > extern_end)):
                class_list[item]["base"].append(symbol)
Exemple #20
0
    def __init__(self):
        print "Naming saved register locations...",

        for ea in idautils.Functions():
            mea = ea
            named_regs = []
            last_iteration = False

            while mea < (ea + (self.INSIZE * self.SEARCH_DEPTH)):
                mnem = idc.GetMnem(mea)

                if mnem in ['sw', 'sd']:
                    reg = idc.GetOpnd(mea, 0)
                    dst = idc.GetOpnd(mea, 1)

                    if reg in self.ARCH['savedregs'] and reg not in named_regs and dst.endswith('($sp)') and 'var_' in dst:
                        offset = int(dst.split('var_')[1].split('(')[0], 16)
                        idc.MakeLocal(ea, idc.FindFuncEnd(ea), "[sp-%d]" % offset, "saved_%s" % reg[1:])
                        named_regs.append(reg)

                if last_iteration:
                    break
                elif mnem.startswith('j') or mnem.startswith('b'):
                    last_iteration = True

                mea += self.INSIZE

        print "done."
Exemple #21
0
    def DeepSearch(self, function_name, line, max_deep, current_deep=0):

        data = {}
        opcode_offset = 0
        function_start = idc.LocByName(function_name)
        function_end = idc.GetFunctionAttr(function_start, idc.FUNCATTR_END)
        while function_start + opcode_offset < function_end:

            opcode_index = function_start + opcode_offset
            dline = idc.GetDisasm(opcode_index)
            if idc.GetMnem(opcode_index) == "call":
                if current_deep >= max_deep:
                    return
                elif idc.GetOpnd(opcode_index, 0)[:4] == "sub_":
                    deep = self.DeepSearchWithRgx(idc.GetOpnd(opcode_index,
                                                              0), line,
                                                  max_deep, current_deep + 1)
                    if deep:
                        data.update(deep)

            if dline == line:
                data["%x" % opcode_index] = dline

            opcode_offset += idc.ItemSize(opcode_index)

        return data
Exemple #22
0
 def __init__(self, *args):
     if len(args) == 1:
         idc.op_hex(args[0], 0)
         idc.op_hex(args[0], 1)
         op1 = idc.GetOpnd(args[0], 0)
         op2 = idc.GetOpnd(args[0], 1)
         if op1 == '':
             op1 = False
         if op2 == '':
             op2 = False
         self.ea = args[0]
         self.mnem = idc.GetMnem(args[0])
         self.op1 = op1
         self.op2 = op2
         self.extend = 0
     elif len(args) == 4:
         self.ea = args[0]
         self.mnem = args[1]
         self.op1 = args[2]
         self.op2 = args[3]
         self.extend = 0
     elif len(args) == 5:
         self.ea = args[0]
         self.mnem = args[1]
         self.op1 = args[2]
         self.op2 = args[3]
         self.extend = args[4]
Exemple #23
0
 def function(ea, taintSet):
     Opnd = idc.GetOpnd(ea, 0)
     #print format(ea, '04x'), Opnd
     if Opnd in source and Opnd not in sink:
         print 'source function %s is called, tainting operand %d' % (
             Opnd, source[Opnd])
         taintSet.add('R' + str(source[Opnd]))
         return True
     elif Opnd in source and 'R' + str(sink[Opnd]) in taintSet:
         sourceOpnd = 'R' + str(source[Opnd])
         while (idc.GetOpnd(ea, 0) != sourceOpnd):
             ea -= 2
         taintTarget = idc.GetOpnd(ea, 1)
         taintSet.add(taintTarget)
         print 'Target %s of sink function %s tainted by operand %d' % (
             taintTarget, Opnd, sink[Opnd] + 1)
         return True
     elif Opnd in sink and 'R' + str(sink[Opnd]) in taintSet:
         sinkOpnd = 'R' + str(sink[Opnd])
         while (idc.GetOpnd(ea, 0) != sinkOpnd):
             ea -= 2
         taintSource = idc.GetOpnd(ea, 1)
         print 'operand %d of sink function %s tainted by source %s' % (
             sink[Opnd], Opnd, taintSource)
         return True
     else:
         pass
     return False
        def ext_instruction(file_name, addr_start, addr_end):
            name_fun = GetFunctionName(addr_start)
            row = ''
            for addr in Heads(addr_start, addr_end):

                ins = ''
                thisOperand = idc.GetMnem(addr)
                oPtype1 = idc.GetOpType(addr, 0)
                oPtype2 = idc.GetOpType(addr, 1)
                # assemblydata = parametertype(oPtype1)+' '+parametertype(oPtype2)
                if (oPtype1 == 1 or oPtype1 == 4):
                    oPtype1 = idc.GetOpnd(addr, 0)
                if (oPtype2 == 1 or oPtype2 == 4):
                    oPtype2 = idc.GetOpnd(addr, 1)
                if thisOperand == "call":
                    call_fun_name = GetOpnd(addr, 0)
                    keyInstr = LocByName(call_fun_name)
                    fflags = idc.get_func_flags(keyInstr)
                    if (fflags & idc.FUNC_LIB) or (fflags & idc.FUNC_THUNK):
                        ins = thisOperand + '_' + idc.GetOpnd(addr, 0) + '_0'
                        row = row + ' ' + ins
                        continue
                ins = str(thisOperand)+'_'+tran(str(oPtype1)) + \
                    '_'+tran(str(oPtype2))
                row = row + ' ' + ins
            return row
Exemple #25
0
def get_opnd(address):
    opnd = idc.GetOpnd(address, 1)

    if opnd == '':
        opnd = idc.GetOpnd(address, 0)

    return opnd
Exemple #26
0
def is_used(call, opnd):
    addresses = get_args_addresses(call)

    for address in addresses:
        if idc.GetOpnd(address, 0) == opnd or idc.GetOpnd(address, 1) == opnd:
            return True

    return False
Exemple #27
0
 def two2one(ea, taintSet):
     if idc.GetOpnd(ea, 1) in taintSet:
         taintSet.add(idc.GetOpnd(ea, 0))
         return True
     if idc.GetOpnd(ea, 0) in taintSet and idc.GetOpnd(ea,
                                                       1) not in taintSet:
         taintSet.remove(idc.GetOpnd(ea, 0))
     return False
Exemple #28
0
def MOVAPD(cpu_context, ip, mnem, opvalues):
    """ 
    Move Aligned Packed Double-Precision Floating-Point Values 
    """
    opvalues = [opvalue for opvalue in opvalues if opvalue.value is not None]
    opvalue2 = opvalues[1].value
    cpu_logger.debug("{} 0x{:X} :: Copy {} into {}".format(mnem, ip, opvalue2, idc.GetOpnd(ip, 0)))
    set_operand_value(cpu_context, ip, opvalue2, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0), width=opvalues[1].width)
Exemple #29
0
def find_WdfDriverCreate():
    function_offset = OFFSET_WdfDriverCreate

    # If the XREF to wdfFunctions + function_offset exists.. then we're in case 1!
    try:
        call_pfnWdfDriverCreate = idautils.XrefsTo(g_vars["_WDFFUNCTIONS"]+function_offset).next().frm
    except StopIteration:
        # this is case 2!
        call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("mov", 1,function_offset)
        if call_pfnWdfDriverCreate != None:
            idc.OpStroffEx(call_pfnWdfDriverCreate,1,(idaapi.get_struc_id("_WDFFUNCTIONS")),0)
        else:
            call_pfnWdfDriverCreate = find_wdf_callback_through_immediate("call", 0, function_offset)
            idc.OpStroffEx(call_pfnWdfDriverCreate,0,(idaapi.get_struc_id("_WDFFUNCTIONS")),0)

    if call_pfnWdfDriverCreate != None:
        # First identify the RealDriverEntry :)
        current_func = idaapi.get_func(call_pfnWdfDriverCreate)
        idc.MakeName(current_func.startEA, "_DriverEntry_")

        argument_DriverConfig_addr = find_function_arg_with_operand_value(call_pfnWdfDriverCreate, "mov", "rsp", 0x20, 0)
        register_DriverConfig = idc.GetOpnd(argument_DriverConfig_addr, 1)
        lea_DriverConfig_addr = find_function_arg(argument_DriverConfig_addr, "lea", register_DriverConfig, 0)

        # Get stack and the stack operand offset
        current_func = idaapi.get_func(lea_DriverConfig_addr)
        stack_id = idc.GetFrame(current_func)
        opnd = idc.GetOpnd(lea_DriverConfig_addr, 1)
        if "rsp" in opnd:
            stack_member_offset = idc.GetOperandValue(lea_DriverConfig_addr, 1)
        elif "rbp" in opnd:
            var_x = opnd.split("+")[-1][:-1] # [rbp+57h+var_80] -> var_80
            members, _ = retrieve_stack_members(current_func)
            inverted_members = {v:k for k, v in members.items()}
            try:
                stack_member_offset = inverted_members[var_x]
            except KeyError as msg:
                print msg
                return

        else:
            print("+] WdfDriverCreate() Unidentified register stack layout")
            return

        #idc.SetMemberName(stack_id, stack_member_offset, "_DriverConfig")
        struct_id = idaapi.get_struc_id("_WDF_DRIVER_CONFIG")
        struct_size = idc.GetStrucSize(struct_id)

        # First check if we have already touch this function stack before
        #if function_stack_erased(current_func):
            # need to take care of the already defined structs
        #    pass
        #else:
        delete_all_function_stack_members(current_func, force=True)
        idc.AddStrucMember(stack_id, "driver_config",
                           stack_member_offset, idc.FF_BYTE|idc.FF_DATA,
                           -1, struct_size)
        idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, struct_id, 1)
Exemple #30
0
def _mov_lea(cpu_context, ip, mnem, opvalues):
    """
    Handle the MOV, MOVZX, and LEA instructions in the same manner.

    MOVZX is a zero extend, but this logic makes no real sense in python.
    """
    opvalue2 = opvalues[1].value
    width = opvalues[0].width
    cpu_logger.debug("{} 0x{:X} :: Copy {} into {}".format(mnem, ip, opvalue2, idc.GetOpnd(ip, 0)))
    set_operand_value(cpu_context, ip, opvalue2, idc.GetOpnd(ip, 0), idc.GetOpType(ip, 0), width=width)