Exemplo n.º 1
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]
Exemplo n.º 2
0
def removeStackVarUsages(self_ea, end_ea):
    madeChanges = False
    for func_ea in idautils.Functions(self_ea, end_ea):
        changedStackVar = False
        if Function.hasStackVars(func_ea):
            stackVars = Function.getStackVars(func_ea)
            # traverse data items of function and op_bin all
            ea = func_ea
            while ea < func_ea + Function.Function(func_ea).getSize(
                    withPool=False):
                d = Data.Data(ea)
                for name, off in stackVars:
                    if name != ' s' and name in d.getOrigDisasm():
                        changedStackVar = True
                        if not madeChanges: madeChanges = True
                        idc.op_hex(d.ea, 1)
                ea += d.getSize()
            if changedStackVar:
                print('%07X: stackvars op -> hex' % func_ea)
    if madeChanges:
        print("Removed all stack variable usages!")
    else:
        print("No stack variable usages to remove!")
Exemplo n.º 3
0
    def parse_phrase(o, ida_operand_str, addr, op_num):

        # IDA does not give us an API to get the content of the phrase
        # => we have to parse the string :/
        if isinstance(__builtin__.REGISTERS, RegistersX64):

            # DEBUG
            #print("phrase: ida_operand_str: %s" % ida_operand_str)

            # Example: [rdx+rcx] or [rax+rdx*8] or byte ptr [rsi+rdx]
            # Remove "[" and "]"
            start = ida_operand_str.find("[") + 1
            end = len(ida_operand_str) - 1
            temp_str = ida_operand_str[start:end]
            memory_elements = temp_str.split("+")

            # DEBUG
            #print("phrase: Memory elements: %d" % len(memory_elements))
            #print(memory_elements)

            # Example: [rdx+rcx] => rdx or [rax+rdx*8] => rax
            base_str = memory_elements[0]
            try:
                base_reg = __builtin__.REGISTERS.to_idx(base_str)
            except:
                # In cases such as [rsp-50h+arg_48] our
                # string parsing fails. However, we can normalize this
                # to [rsp] and retry.
                if op_hex(addr, op_num):
                    new_str = GetOpnd(addr, op_num)
                    if ida_operand_str != new_str:
                        return parse_phrase(o, new_str, addr, op_num)

                raise NotImplementedError("Do not know how to " +
                                          "handle o_phrase '%s'." %
                                          ida_operand_str)

            index_reg = None
            index_factor = None

            if len(memory_elements) == 2:
                index_split = memory_elements[1].split("*")

                # DEBUG
                #print("phrase: Index split: " + str(index_split))

                # Example: [rdx+rcx] => rcx or [rax+rdx*8] => rdx
                # Example: [rsp+0] => rsp
                index_str = index_split[0]
                factor_str = None
                if len(index_split) == 2:
                    # Example [rax+rdx*8] => 8
                    factor_str = index_split[1]
                elif len(index_split) > 1:

                    # In cases such as [rsp+0B0h+lbarray+78h] our
                    # string parsing fails. However, we can normalize this
                    # to [rsp] and retry.
                    if op_hex(addr, op_num):
                        new_str = GetOpnd(addr, op_num)
                        if ida_operand_str != new_str:
                            return parse_phrase(o, new_str, addr, op_num)

                    raise NotImplementedError("Do not know how to " +
                                              "handle o_phrase '%s'." %
                                              ida_operand_str)

                # Example: [rsp+0]
                # Example: [rsp+s2] with r2 = 0
                try:
                    index_reg = __builtin__.REGISTERS.to_idx(index_str)
                except:
                    # DEBUG
                    #print("NOTE: phrase index string '%s' ignored."
                    #      % index_str)
                    index_reg = None

                if factor_str:
                    index_factor = int(factor_str)

                # Example: [rsp+0]
                if index_reg is None:
                    return operands.Memory(operands.Register(base_reg))
                # Example: [rax+rdx*8]
                elif factor_str:
                    return operands.Memory(
                        operands.Register(base_reg),
                        index=operands.Register(index_reg),
                        index_factor=operands.Constant(index_factor))
                # Example: [rdx+rcx]
                else:
                    return operands.Memory(operands.Register(base_reg),
                                           index=operands.Register(index_reg))

            # Example: [rsp+40h+var_40] => [rsp]
            # Example: [rsp+8+var_8] => [rsp]
            # Example: [rsp+rcx*2+var_s0] => [rsp+rcx*2]
            elif len(memory_elements) == 3:
                # IDA defines o_phrase as the following:
                # Memory Ref [Base Reg + Index Reg]
                # Therefore, a phrase does not have an offset.
                # The string construct built by IDA always adds up to 0.
                possible_number = memory_elements[1]
                has_hex_ending = possible_number[-1:] == "h"
                is_hex = bool(re.match(r'^[a-fA-F0-9]+$',
                                       possible_number[:-1]))
                is_number = bool(re.match(r'^[0-9]+$', possible_number))

                # Example: [rsp+40h+var_40] => [rsp]
                if has_hex_ending and is_hex:
                    return operands.Memory(operands.Register(base_reg))

                # Example: [rsp+8+var_8] => [rsp]
                elif is_number:
                    return operands.Memory(operands.Register(base_reg))

                # Example: [rsp+rcx*2+var_s0] => [rsp+rcx*2]
                else:

                    index_split = memory_elements[1].split("*")

                    # Example: [rsp+rcx*2+var_s0] => rcx
                    index_str = index_split[0]
                    factor_str = None
                    if len(index_split) == 2:
                        # Example [rax+rdx*8] => 8
                        factor_str = index_split[1]
                    elif len(index_split) > 1:

                        # In cases such as [rsp+0B0h+lbarray+78h] our
                        # string parsing fails. However, we can normalize this
                        # to [rsp] and retry.
                        if op_hex(addr, op_num):
                            new_str = GetOpnd(addr, op_num)
                            if ida_operand_str != new_str:
                                return parse_phrase(o, new_str, addr, op_num)

                        raise NotImplementedError("Do not know how to " +
                                                  "handle o_phrase '%s'." %
                                                  ida_operand_str)

                    try:
                        index_reg = __builtin__.REGISTERS.to_idx(index_str)
                    except:

                        # In cases such as [rsp+0B0h+lbarray+78h] our
                        # string parsing fails. However, we can normalize this
                        # to [rsp] and retry.
                        if op_hex(addr, op_num):
                            new_str = GetOpnd(addr, op_num)
                            if ida_operand_str != new_str:
                                return parse_phrase(o, new_str, addr, op_num)

                        raise NotImplementedError("Do not know how to " +
                                                  "handle o_phrase '%s'." %
                                                  ida_operand_str)

                    if factor_str:
                        index_factor = int(factor_str)

                    # Example: [rsp+rcx*2+var_s0]
                    if factor_str:
                        return operands.Memory(
                            operands.Register(base_reg),
                            index=operands.Register(index_reg),
                            index_factor=operands.Constant(index_factor))
                    # Example: [rsp+rcx+var_s0]
                    else:
                        return operands.Memory(
                            operands.Register(base_reg),
                            index=operands.Register(index_reg))

            # Example: [rsp+rdx*8+98h+var_98] => [rsp+rdx*8]
            elif len(memory_elements) == 4:
                # IDA defines o_phrase as the following:
                # Memory Ref [Base Reg + Index Reg]
                # Therefore, a phrase does not have an offset.
                # The string construct built by IDA always adds up to 0.
                possible_number = memory_elements[2]
                has_hex_ending = possible_number[-1:] == "h"
                is_hex = bool(re.match(r'^[a-fA-F0-9]+$',
                                       possible_number[:-1]))

                if has_hex_ending and is_hex:
                    new_op_str = "[" + \
                                 memory_elements[0] + \
                                 "+" + \
                                 memory_elements[1] + \
                                 "]"
                    return parse_phrase(o, new_op_str, addr, op_num)
                else:

                    # In cases such as [rsp+0B0h+lbarray+78h] our
                    # string parsing fails. However, we can normalize this
                    # to [rsp] and retry.
                    if op_hex(addr, op_num):
                        new_str = GetOpnd(addr, op_num)
                        if ida_operand_str != new_str:
                            return parse_phrase(o, new_str, addr, op_num)

                    raise NotImplementedError("Do not know how to " +
                                              "handle o_phrase '%s'." %
                                              ida_operand_str)

            elif len(memory_elements) > 4:

                # In cases such as [rsp+0B0h+lbarray+78h] our
                # string parsing fails. However, we can normalize this
                # to [rsp] and retry.
                if op_hex(addr, op_num):
                    new_str = GetOpnd(addr, op_num)
                    if ida_operand_str != new_str:
                        return parse_phrase(o, new_str, addr, op_num)

                raise NotImplementedError("Do not know how to handle " +
                                          "o_phrase '%s'." % ida_operand_str)

            return operands.Memory(operands.Register(base_reg))

        else:

            raise NotImplementedError(
                "Do not know how to handle o_phrase for architecture.")