示例#1
0
 def is_pop(self):
     """
     @brief Tests if the VmInstruction is a 'vpop'.
     If True sets the PseudoInstruction
     """
     for pos, inst in enumerate(self.Instructions):
         if(inst.is_add_basepointer()):
             break
     else : # no break
         return False
     pos_pmov_lst = self.get_previous(Instruction.is_read_stack, pos)
     if len(pos_pmov_lst) == 0:
         return False
     for ppos in pos_pmov_lst:
         pop_inst = self.Instructions[ppos] # get last pop_mov inst in case there are more
     pop_op = make_op(pop_inst, 1, self.catch_value)
     pos_mov_lst = self.get_subsequent(Instruction.is_mov, pos)
     op_pos = ppos
     for pos_mov in pos_mov_lst:
         pos_mov_inst = self.Instructions[pos_mov]
         if(pos_mov_inst.is_write_stack()):
             return False
         if((get_reg_class(pop_inst.get_op_str(1)) ==
               get_reg_class(pos_mov_inst.get_op_str(2))) and
               get_reg_class(pop_inst.get_op_str(1))):  #maybe too weak
             pop_op = make_op(pos_mov_inst, 1, self.catch_value)
             op_pos = pos_mov
     if(not self.Instructions[op_pos].op_is_mem(1)):
         return False
     add_value = self.Instructions[pos].get_op_value(2)
     self.Pseudocode = PseudoInstruction('vpop', self.addr,
                                         [pop_op], add_value)
     #print 'vpop'
     return True
示例#2
0
 def is_push(self):
     """
     @brief Tests if the VmInstruction is a 'vpush'.
     If True sets the PseudoInstruction
     """
     for pos, inst in enumerate(self.Instructions):
         if(inst.is_sub_basepointer()):
             break
         if(get_reg_class(self.catch_reg) == get_reg_class('eax') and
            (inst.is_cwde() or inst.is_cbw() or inst.is_cdqe())):
             self.is_signed = True
     else : # no break
         return False
     pos_pmov_lst = self.get_subsequent(Instruction.is_write_stack, pos)
     if len(pos_pmov_lst) != 1:
         return False
     push_inst = self.Instructions[pos_pmov_lst[0]]
     pos_mov_lst = self.get_previous(Instruction.is_mov, pos)
     push_op = make_op(push_inst, 2, self.catch_value)
     for pos_mov in pos_mov_lst:
         pos_mov_inst = self.Instructions[pos_mov]
         if pos_mov_inst.is_read_stack():
             return False
         if((get_reg_class(push_inst.get_op_str(2)) ==
               get_reg_class(pos_mov_inst.get_op_str(1))) and
               get_reg_class(push_inst.get_op_str(2)) != None): # too strong condition
             push_op = make_op(pos_mov_inst, 2, self.catch_value)
     sub_value = self.Instructions[pos].get_op_value(2)
     self.Pseudocode = PseudoInstruction('vpush', self.addr, [push_op], sub_value)
     return True
示例#3
0
def replace_push_ebp(ps_lst, has_loc):
    """
    @brief Replaces all 'push ebp' or 'push rbp' with array operands
    @param List of PseudoInstructions
    @param has_loc Indicates if there are locals in this function
    @return List of PseudoInstructions
    """
    ret = []
    is_ret = False
    for r_item in ps_lst:
        if r_item.inst_type == PI.RET_T:
            is_ret = True
    for pos, item in enumerate(ps_lst):
        if (item.inst_type == PI.PUSH_T
                and item.op_lst[0].type == PI.REGISTER_T and get_reg_class(
                    item.op_lst[0].register) == get_reg_class('ebp')):
            push_pos = last_rel_push(ps_lst, pos - 1)
            if push_pos == None:
                ret.append(item)
            else:
                push_inst = ps_lst[push_pos]
                if (push_inst.list_len == 0 or push_inst.addr
                        == item.addr):  #need this for saving push ebp
                    ret.append(item)
                    continue
                push_inst_op = ps_lst[push_pos].op_lst[0]
                push_poss = scan_stack(ps_lst, pos)
                val_arr = []
                #all pos should be push so dont need a test here
                for pos in push_poss:
                    val_arr.append(ps_lst[pos].op_lst[0])
                #TODO look for better possibility
                if is_ret:
                    if (((is_mov_ebp(ps_lst, 0, pos))
                         and is_mov_ebp(ps_lst, 0,
                                        len(ps_lst) - 1)) or not has_loc):
                        val_arr.append(
                            PI.PseudoOperand(PI.EXP_T, 'RET_ADDR', 0))
                        val_arr.append(PI.PseudoOperand(PI.EXP_T, 'ARGS', 0))
                else:
                    if (((not is_mov_ebp(ps_lst, 0, pos))
                         and is_mov_ebp(ps_lst, 0,
                                        len(ps_lst) - 1)) or not has_loc):
                        val_arr.append(
                            PI.PseudoOperand(PI.EXP_T, 'RET_ADDR', 0))
                        val_arr.append(PI.PseudoOperand(PI.EXP_T, 'ARGS', 0))
                new_op = PI.ArrayOperand(PI.ARRAY_T, ps_lst[push_poss[0]].size,
                                         len(val_arr), val_arr)
                new_inst = PI.PseudoInstruction(item.mnem, item.addr, [new_op],
                                                item.size, item.inst_type,
                                                item.inst_class)
                #new_inst.comment = comment
                ret.append(new_inst)
        else:
            ret.append(item)
    return ret
示例#4
0
def replace_push_ebp(ps_lst, has_loc):
    """
    @brief Replaces all 'push ebp' or 'push rbp' with array operands
    @param List of PseudoInstructions
    @param has_loc Indicates if there are locals in this function
    @return List of PseudoInstructions
    """
    ret = []
    is_ret = False
    for r_item in ps_lst:
        if r_item.inst_type == PI.RET_T:
            is_ret = True
    for pos, item in enumerate(ps_lst):
        if(item.inst_type == PI.PUSH_T and
           item.op_lst[0].type == PI.REGISTER_T and
           get_reg_class(item.op_lst[0].register) == get_reg_class('ebp')):
            push_pos = last_rel_push(ps_lst, pos-1)
            if push_pos == None:
                ret.append(item)
            else:
                push_inst = ps_lst[push_pos]
                if(push_inst.list_len == 0 or
                   push_inst.addr == item.addr):#need this for saving push ebp 
                    ret.append(item)
                    continue
                push_inst_op = ps_lst[push_pos].op_lst[0]
                push_poss = scan_stack(ps_lst, pos)
                val_arr = []
                #all pos should be push so dont need a test here
                for pos in push_poss:
                    val_arr.append(ps_lst[pos].op_lst[0])
                #TODO look for better possibility
                if is_ret:
                    if (((is_mov_ebp(ps_lst, 0, pos)) and
                        is_mov_ebp(ps_lst, 0, len(ps_lst)-1)) or
                        not has_loc):
                        val_arr.append(PI.PseudoOperand(PI.EXP_T, 'RET_ADDR', 0))
                        val_arr.append(PI.PseudoOperand(PI.EXP_T, 'ARGS', 0))
                else:
                    if (((not is_mov_ebp(ps_lst, 0, pos)) and
                        is_mov_ebp(ps_lst, 0, len(ps_lst)-1)) or
                        not has_loc):
                        val_arr.append(PI.PseudoOperand(PI.EXP_T, 'RET_ADDR', 0))
                        val_arr.append(PI.PseudoOperand(PI.EXP_T, 'ARGS', 0))
                new_op = PI.ArrayOperand(
                            PI.ARRAY_T, ps_lst[push_poss[0]].size,
                            len(val_arr), val_arr)
                new_inst = PI.PseudoInstruction(
                    item.mnem, item.addr,
                    [new_op], item.size,
                    item.inst_type, item.inst_class)
                #new_inst.comment = comment
                ret.append(new_inst)
        else:
            ret.append(item)
    return ret
示例#5
0
 def is_nor(self):
     """
     @brief Tests if the VmInstruction is a 'vnor'.
     If True sets the PseudoInstruction
     """
     # 1. search for and with 2 different registers
     and_found = False
     reg0 = ''
     reg1 = ''
     and_size = 0
     for pos, inst in enumerate(self.Instructions):
         if inst.is_and():
             reg0 = inst.get_reg_name(1)
             reg1 = inst.get_reg_name(2)
             and_size = inst.get_mov_size()
             if reg0 != reg1:
                 and_found = True
                 break
     if not and_found:
         return False
     pos_not = self.get_previous(Instruction.is_not, pos)
     #if len(pos_not) < 1 or len(pos_not) > 2:
     #    return False
     not_size = 0
     for posn in pos_not:
         not_size += (self.Instructions[posn].Instruction.operands[0].size / 8)
     if(not_size != 2 * and_size):
         return False
     pos_mov = self.get_previous(Instruction.is_mov, pos)
     #if len(pos_mov) != 2:
     #    return False
     mov_r0 = False
     mov_r1 = False
     op1 = make_op(self.Instructions[pos], 1, self.catch_value)
     op2 = make_op(self.Instructions[pos], 2, self.catch_value)
     for pos_reg0 in pos_mov:
         if (get_reg_class(reg0) ==
               get_reg_class(self.Instructions[pos_reg0].get_reg_name(1))):
             mov_r0 = True
             break
     for pos_reg1 in pos_mov:
         if (get_reg_class(reg1) ==
               get_reg_class(self.Instructions[pos_reg1].get_reg_name(1))):
             mov_r1 = True
             break
     if mov_r0:
         op1 = make_op(self.Instructions[pos_reg0], 2, self.catch_value)
     if mov_r1:
         op2 = make_op(self.Instructions[pos_reg1], 2, self.catch_value)
     #quick fix correct !!!
     if(op1.register == 'ebp') and (and_size == 2):
         op1 = op1.replace('+0x4', '+0x2')
     self.Pseudocode = PseudoInstruction('vnor', self.addr, [op1, op2], and_size)
     return True
示例#6
0
 def get_scratch_variable(self):
     """
     @brief Replace memory operands from 'vpush' and 'vpop' with
     ScratchOperands
     """
     if (self.inst_type != POP_T and
                 self.inst_type != PUSH_T and self.list_len != 1):
         return
     op0 = self.op_lst[0]
     if (op0.type == MEMORY_T and
                 get_reg_class(op0.register) == get_reg_class('edi')):
         self.op_lst[0] = ScratchOperand(SVARIABLE_T,
                                         op0.displacement, op0.size)
示例#7
0
文件: Util.py 项目: cryzlasm/VMAttack
def get_reg(reg_string, reg_size):
    """
    returns the register name to be used as key with a Traceline.ctx object
    :param reg_string: any string representing a reg, e.g. rax, RAX, eax, ah, al, etc.
    :param reg_size: size in bit of the registers in Traceline.ctx, e.g. 64, 32, 16
    :return: reg_string of the ctx keys, e.g. rax
    """
    return get_reg_by_size(get_reg_class(reg_string), reg_size)
示例#8
0
 def is_write(self):
     """
     @brief Tests if the VmInstruction is a 'vwrite'.
     If True sets the PseudoInstruction
     """
     reg0 = ''
     reg1 = ''
     mov_size = 0
     sub_size = 0
     for pos, inst in enumerate(self.all_instructions):
         if inst.op_is_mem(1) and not inst.is_write_stack():
             reg0 = inst.get_reg_name(1)
             reg1 = inst.get_reg_name(2)
             mov_size = inst.get_mov_size()
             break
     else: # no break
         return False
     for subpos, inst in enumerate(self.Instructions):
         if(inst.is_add_basepointer()):
             sub_size = inst.get_op_value(2)
             break
     else : # no break
         return False
     pos_mov = self.get_previous(Instruction.is_mov, pos)
     mov_r0 = False
     mov_r1 = False
     for pos_reg0 in pos_mov:
         if (get_reg_class(reg0) ==
               get_reg_class(self.Instructions[pos_reg0].get_reg_name(1))):
             mov_r0 = True
             break
     for pos_reg1 in pos_mov:
         if (get_reg_class(reg1) ==
               get_reg_class(self.Instructions[pos_reg1].get_reg_name(1))):
             mov_r1 = True
             break
     if mov_r0 and mov_r1:
         op1_inst =  self.Instructions[pos_reg0]
         op1 = PseudoOperand(PI.REFERENCE_T, op1_inst.get_op_str(2),
                             op1_inst.get_op_size(2), op1_inst.get_reg_name(2))
         op2 = make_op(self.Instructions[pos_reg1], 2, self.catch_value)
         self.Pseudocode = PseudoInstruction('vwrite', self.addr,
                     [op1, op2], mov_size, PI.WRITE_T, PI.IN2_OUT0, sub_size)
         return True
     else:
         return False
示例#9
0
def get_reg(reg_string, reg_size):
    """
    returns the register name to be used as key with a Traceline.ctx object
    :param reg_string: any string representing a reg, e.g. rax, RAX, eax, ah, al, etc.
    :param reg_size: size in bit of the registers in Traceline.ctx, e.g. 64, 32, 16
    :return: reg_string of the ctx keys, e.g. rax
    """
    return get_reg_by_size(get_reg_class(reg_string), reg_size)
示例#10
0
 def is_vcall(self):
     """
     @brief Tests if the VmInstruction is a 'vcall'.
     If True sets the PseudoInstruction
     """
     for pos, inst in enumerate(self.Instructions):
         if(inst.is_call()):
             break
     else : # no break
         return False
     op1 = self.Instructions[pos].get_op_str(1)
     prev_mov = self.get_previous(Instruction.is_mov, pos)
     for prev_pos in prev_mov:
         if (get_reg_class(self.Instructions[pos].get_reg_name(1)) ==
             get_reg_class(self.Instructions[prev_pos].get_reg_name(1))):
                 op1 = make_op(self.Instructions[prev_pos], 2, self.catch_value)
     self.Pseudocode = PseudoInstruction('vcall', self.addr, [op1])
     return True
示例#11
0
 def is_mov_ebp(self):
     """
     @brief Tests if the VmInstruction is a 'vebp_mov'.
     If True sets the PseudoInstruction
     """
     op1 = ''
     op2 = ''
     for pos, inst in enumerate(self.Instructions):
         if(inst.is_mov() and
            get_reg_class(inst.get_reg_name(1)) == get_reg_class('ebp') and
            get_reg_class(inst.get_reg_name(2)) == get_reg_class('ebp')):
             op1 = make_op(inst, 1, self.catch_value)
             op2 = make_op(inst, 2, self.catch_value)
             break
     else : # no break
         return False
     self.Pseudocode = PseudoInstruction('vebp_mov', self.addr, [op1, op2])
     return True
示例#12
0
    def PopulateModel(self):
        self.CleanModel()
        assert isinstance(self.ctx, dict)
        for key in self.ctx.keys():
            if get_reg_class(key) is not None:
                node = QtGui.QStandardItem('Register %s' % key)
                node_brush = set()
                for line in self.ctx[key]:
                    assert isinstance(line, Traceline)
                    tid = QtGui.QStandardItem('%s' % line.thread_id)
                    addr = QtGui.QStandardItem('%x' % line.addr)
                    disasm = QtGui.QStandardItem(line.disasm_str())
                    comment = QtGui.QStandardItem(''.join(
                        c for c in line.comment if line.comment is not None))
                    context = QtGui.QStandardItem(''.join(
                        '%s:%s ' % (c, line.ctx[c]) for c in line.ctx.keys()
                        if line.ctx is not None))
                    ci = 0
                    co = 0
                    for selector in self.selection[
                            'upper']:  # check input values
                        if line.to_str_line().__contains__(
                                selector) or line.to_str_line().__contains__(
                                    selector.lower()):
                            ci = 1

                    for selector in self.selection[
                            'lower']:  # check output values
                        if line.to_str_line().__contains__(
                                selector) or line.to_str_line().__contains__(
                                    selector.lower()):
                            co = 2

                    node_brush.add(ci + co)
                    tid.setBackground(self.brush_map[ci + co])
                    addr.setBackground(self.brush_map[ci + co])
                    disasm.setBackground(self.brush_map[ci + co])
                    comment.setBackground(self.brush_map[ci + co])
                    context.setBackground(self.brush_map[ci + co])

                    node.appendRow([tid, addr, disasm, comment, context])
                try:
                    if len(node_brush) == 3:
                        color = 3
                    else:
                        color = max(node_brush)
                    node.setBackground(self.brush_map[color])
                except:
                    pass
                self.sim.appendRow(node)

        self.treeView.resizeColumnToContents(0)
        self.treeView.resizeColumnToContents(1)
        self.treeView.resizeColumnToContents(2)
        self.treeView.resizeColumnToContents(3)
        self.treeView.resizeColumnToContents(4)
示例#13
0
def rec_find_addr(pp_lst, pos, op, max_rec_depth):
    """
    @brief Recursiv search for finding jmp addresses
    @param pp_lst List of PseudoInstructions push/pop represtentation
    @param pos Index of jump instruction
    @param op Operand of jump instruction
    @param max_rec_depth Maximal recursion depth
    @return List positions which are used to calc jump address
    """
    if max_rec_depth == 0:
        return []
    if (op.type == PI.IMMEDIATE_T
            or (op.type == PI.REGISTER_T
                and get_reg_class(op.register) == get_reg_class('ebp'))):
        return [pos]
    inst_pos = find_last_inst(pp_lst, pos - 1, op)
    if inst_pos == None or inst_pos == 0:
        return []
    curr_inst = pp_lst[inst_pos]
    if curr_inst.inst_type == PI.POP_T:
        push_pos = last_rel_push(pp_lst, inst_pos - 1)
        if push_pos == None:
            return []
        new_op = pp_lst[push_pos].op_lst[0]
        new_pos = push_pos
        return [] + rec_find_addr(pp_lst, new_pos, new_op, max_rec_depth - 1)
    elif (curr_inst.inst_class == PI.ASSIGNEMENT_T
          and curr_inst.list_len == 2):
        new_op = pp_lst[inst_pos].op_lst[1]
        new_pos = inst_pos
        return [] + rec_find_addr(pp_lst, new_pos, new_op, max_rec_depth - 1)
    elif (curr_inst.inst_class == PI.ASSIGNEMENT_T
          and curr_inst.list_len >= 2):
        new_pos = inst_pos
        ret_lst = []
        for new_op in curr_inst.op_lst[1:]:
            ret_lst += rec_find_addr(pp_lst, new_pos, new_op,
                                     max_rec_depth - 1)
        return ret_lst
    else:
        return []
示例#14
0
def rec_find_addr(pp_lst, pos, op, max_rec_depth):
    """
    @brief Recursiv search for finding jmp addresses
    @param pp_lst List of PseudoInstructions push/pop represtentation
    @param pos Index of jump instruction
    @param op Operand of jump instruction
    @param max_rec_depth Maximal recursion depth
    @return List positions which are used to calc jump address
    """
    if max_rec_depth == 0:
        return []
    if(op.type == PI.IMMEDIATE_T or
       (op.type == PI.REGISTER_T and
        get_reg_class(op.register) == get_reg_class('ebp'))):
        return [pos]
    inst_pos = find_last_inst(pp_lst, pos - 1, op)
    if inst_pos == None or inst_pos == 0:
        return []
    curr_inst = pp_lst[inst_pos]
    if curr_inst.inst_type == PI.POP_T:
        push_pos = last_rel_push(pp_lst, inst_pos - 1)
        if push_pos == None:
            return []
        new_op = pp_lst[push_pos].op_lst[0]
        new_pos = push_pos
        return [] + rec_find_addr(pp_lst, new_pos, new_op, max_rec_depth-1)
    elif (curr_inst.inst_class == PI.ASSIGNEMENT_T and
            curr_inst.list_len == 2):
        new_op = pp_lst[inst_pos].op_lst[1]
        new_pos = inst_pos
        return [] + rec_find_addr(pp_lst, new_pos, new_op, max_rec_depth-1)
    elif (curr_inst.inst_class == PI.ASSIGNEMENT_T and
            curr_inst.list_len >= 2):
        new_pos = inst_pos
        ret_lst = []
        for new_op in curr_inst.op_lst[1:]:
            ret_lst += rec_find_addr(pp_lst, new_pos , new_op, max_rec_depth-1)
        return ret_lst
    else:
        return []
示例#15
0
 def is_read(self):
     """
     @brief Tests if the VmInstruction is a 'vread'.
     If True sets the PseudoInstruction
     """
     reg0 = ''
     reg1 = ''
     mov_size = 0
     for pos, inst in enumerate(self.all_instructions):
         if inst.op_is_mem(2) and not inst.is_read_stack():
             reg0 = inst.get_reg_name(1)
             reg1 = inst.get_reg_name(2)
             mov_size = inst.get_mov_size()
             break
     else: # no break
         return False
     prev_mov = self.get_previous(Instruction.is_mov, pos)
     post_mov = self.get_subsequent(Instruction.is_mov, pos)
     for prev_pos in prev_mov:
         if(get_reg_class(reg1) ==
            get_reg_class(self.Instructions[prev_pos].get_reg_name(1))):
             break
     else: # no break
         return False
     for post_pos in post_mov:
         if(get_reg_class(reg0) ==
            get_reg_class(self.Instructions[post_pos].get_reg_name(2))):
             push_size = self.Instructions[post_pos].get_mov_size()
             break
     else: # no break
         return False
     # wta = write to address
     #if mov_size == 1:
     op1 = make_op(self.Instructions[post_pos], 1, self.catch_value)
     op2_inst = self.Instructions[prev_pos]
     op2 = PseudoOperand(PI.REFERENCE_T, op2_inst.get_op_str(2),
                         op2_inst.get_op_size(2), op2_inst.get_reg_name(2))
     self.Pseudocode = PseudoInstruction('vread', self.addr,
                                         [op1, op2], mov_size, PI.READ_T, PI.IN1_OUT1 , push_size)
     return True
示例#16
0
 def is_imul(self):
     """
     @brief Tests if the VmInstruction is a 'vimul'.
     If True sets the PseudoInstruction
     """
     reg0 = ''
     reg1 = ''
     mul_found = False
     for pos, inst in enumerate(self.Instructions):
         if (inst.is_imul() and inst.op_is_reg(1)):
             reg0 = inst.get_reg_name(1)
             if inst.get_reg_name(2) == None:
                 reg1 = get_reg_by_size(get_reg_class('eax'), SV.dissassm_type)
             else:
                 reg1 = inst.get_reg_name(2)
             if reg0 != reg1:
                 mul_found = True
                 break
     if not mul_found:
         return False
     pos_mov = self.get_previous(Instruction.is_mov, pos)
     for pos_reg0 in pos_mov:
         if (get_reg_class(reg0) ==
               get_reg_class(self.Instructions[pos_reg0].get_reg_name(1))):
             mov_r0 = True
             break
     for pos_reg1 in pos_mov:
         if (get_reg_class(reg1) ==
               get_reg_class(self.Instructions[pos_reg1].get_reg_name(1))):
             mov_r1 = True
             break
     if mov_r0 and mov_r1:
         self.Pseudocode = PseudoInstruction('vimul', self.addr,
             [make_op(self.Instructions[pos_reg0], 2, self.catch_value),
              make_op(self.Instructions[pos_reg1], 2, self.catch_value)],
             SV.dissassm_type / 8, PI.IMUL_T, PI.IN2_OUT3)
         return True
     else:
         return False
示例#17
0
def return_push_ebp(ps_lst):
    """
    @brief Replace all array operands, which are not part of an assignement,
    with 'push ebp' or 'push rbp'
    @param ps_lst List of PseudoInstructions
    @remark Just do this after 'replace_push_ebp' and 'reduce_assignements'
    """
    for inst in ps_lst:
        if (inst.inst_type == PI.PUSH_T and inst.op_lst[0].type == PI.ARRAY_T):
            reg_class = get_reg_class('ebp')
            register = get_reg_by_size(reg_class, SV.dissassm_type)
            ebp_op = PI.PseudoOperand(PI.REGISTER_T, register,
                                      SV.dissassm_type, register)
            inst.op_lst[0] = ebp_op
示例#18
0
def get_catch_reg(reg, length):
    """
    @brief Determines the right catch register for further usage
    @param reg Register from x86 code
    @param length Move size of catch instruction in bytes
    @return Register with right size or empty string
    """
    reg_class = get_reg_class(reg)
    if reg_class == None:
        return ''
    catch_reg = get_reg_by_size(reg_class, length * 8)
    if catch_reg == None:
        catch_reg = ''
    return catch_reg
示例#19
0
def return_push_ebp(ps_lst):
    """
    @brief Replace all array operands, which are not part of an assignement,
    with 'push ebp' or 'push rbp'
    @param ps_lst List of PseudoInstructions
    @remark Just do this after 'replace_push_ebp' and 'reduce_assignements'
    """
    for inst in ps_lst:
        if (inst.inst_type == PI.PUSH_T and
            inst.op_lst[0].type == PI.ARRAY_T):
            reg_class = get_reg_class('ebp')
            register = get_reg_by_size(reg_class, SV.dissassm_type)
            ebp_op = PI.PseudoOperand(PI.REGISTER_T, register,
                                      SV.dissassm_type, register)
            inst.op_lst[0] = ebp_op
示例#20
0
    def PopulateModel(self):
        self.CleanModel()
        assert isinstance(self.ctx, dict)
        for key in self.ctx.keys():
            if get_reg_class(key) is not None:
                node = QtGui.QStandardItem('Register %s' % key)
                node_brush = set()
                for line in self.ctx[key]:
                    assert isinstance(line, Traceline)
                    tid = QtGui.QStandardItem('%s' % line.thread_id)
                    addr = QtGui.QStandardItem('%x' % line.addr)
                    disasm = QtGui.QStandardItem(line.disasm_str())
                    comment = QtGui.QStandardItem(''.join(c for c in line.comment if line.comment is not None))
                    context = QtGui.QStandardItem(''.join('%s:%s ' % (c, line.ctx[c]) for c in line.ctx.keys() if line.ctx is not None))
                    ci = 0
                    co = 0
                    for selector in self.selection['upper']:  # check input values
                        if line.to_str_line().__contains__(selector) or line.to_str_line().__contains__(selector.lower()):
                            ci = 1

                    for selector in self.selection['lower']: # check output values
                        if line.to_str_line().__contains__(selector) or line.to_str_line().__contains__(selector.lower()):
                            co = 2

                    node_brush.add(ci+co)
                    tid.setBackground(self.brush_map[ci+co])
                    addr.setBackground(self.brush_map[ci+co])
                    disasm.setBackground(self.brush_map[ci+co])
                    comment.setBackground(self.brush_map[ci+co])
                    context.setBackground(self.brush_map[ci+co])

                    node.appendRow([tid, addr, disasm, comment, context])
                try:
                    if len(node_brush) == 3:
                        color = 3
                    else:
                        color = max(node_brush)
                    node.setBackground(self.brush_map[color])
                except:
                    pass
                self.sim.appendRow(node)

        self.treeView.resizeColumnToContents(0)
        self.treeView.resizeColumnToContents(1)
        self.treeView.resizeColumnToContents(2)
        self.treeView.resizeColumnToContents(3)
        self.treeView.resizeColumnToContents(4)
示例#21
0
 def replace_reg_class(self, rreg, catch_value):
     """
     @brief Replace register of evrey op with catch_value
     if it is in the same register class as rreg
     @param rreg Register to replace
     @param catch_value Value that replaces the register 
     """
     reg_class = get_reg_class(rreg)
     for reg in reversed(get_reg_class_lst(reg_class)):
         for op in self.op_lst:
             if op.type == REGISTER_T and op.register == reg:
                 op.type = IMMEDIATE_T
                 op.val = catch_value
                 op.name = op.name.replace(reg,
                                           '{0:#x}'.format(catch_value))
             elif op.type == MEMORY_T and reg in op.name:
                 op.displacement = catch_value
                 op.name = op.name.replace(reg,
                                           '{0:#x}'.format(catch_value))
示例#22
0
 def is_shift_left(self):
     """
     @brief Tests if the VmInstruction is a 'vshl'.
     If True sets the PseudoInstruction
     """
     # 1. search for and with 2 different registers
     and_found = False
     reg0 = ''
     reg1 = ''
     for pos, inst in enumerate(self.Instructions):
         if inst.is_shl() and inst.op_is_reg(1) and inst.op_is_reg(2):
             reg0 = inst.get_reg_name(1)
             reg1 = inst.get_reg_name(2)
             if reg0 != reg1:
                 and_found = True
                 break
     if not and_found:
         return False
     pos_mov = self.get_previous(Instruction.is_mov, pos)
     if len(pos_mov) != 2:
         return False
     mov_r0 = False
     mov_r1 = False
     for pos_reg0 in pos_mov:
         if (get_reg_class(reg0) ==
               get_reg_class(self.Instructions[pos_reg0].get_reg_name(1))):
             mov_r0 = True
             break
     for pos_reg1 in pos_mov:
         if (get_reg_class(reg1) ==
               get_reg_class(self.Instructions[pos_reg1].get_reg_name(1))):
             mov_r1 = True
             break
     post_mov = self.get_subsequent(Instruction.is_mov, pos)
     for save_mov in post_mov:
         if (get_reg_class(reg0) ==
               get_reg_class(self.Instructions[save_mov].get_reg_name(2))):
             ret_size = self.Instructions[save_mov].get_mov_size()
             break
     else: # no break
         return False
     if mov_r0 and mov_r1:
         # TODO byte word usw...
         self.Pseudocode = PseudoInstruction('vshl', self.addr,
             [make_op(self.Instructions[pos_reg0], 2, self.catch_value),
              make_op(self.Instructions[pos_reg1], 2, self.catch_value)],
             ret_size)
         return True
     else:
         return False
示例#23
0
 def is_shld(self):
     """
     @brief Tests if the VmInstruction is a 'vshld'.
     If True sets the PseudoInstruction
     """
     and_found = False
     reg0 = ''
     reg1 = ''
     reg2 = ''
     for pos, inst in enumerate(self.Instructions):
         if (inst.is_shld() and inst.op_is_reg(1) and inst.op_is_reg(2)
               and inst.op_is_reg(3)):
             reg0 = inst.get_reg_name(1)
             reg1 = inst.get_reg_name(2)
             reg2 = inst.get_reg_name(3)
             if reg0 != reg1:
                 and_found = True
                 break
     if not and_found:
         return False
     prev_mov = self.get_previous(Instruction.is_mov, pos)
     for prev_pos0 in prev_mov:
         if (get_reg_class(reg0) ==
               get_reg_class(self.Instructions[prev_pos0].get_reg_name(1))):
             break
     else: # no break
         return False
     for prev_pos1 in prev_mov:
         if (get_reg_class(reg1) ==
               get_reg_class(self.Instructions[prev_pos1].get_reg_name(1))):
             break
     else: # no break
         return False
     for prev_pos2 in prev_mov:
         if (get_reg_class(reg2) ==
               get_reg_class(self.Instructions[prev_pos2].get_reg_name(1))):
             break
     else: # no break
         return False
     self.Pseudocode = PseudoInstruction('vshld', self.addr,
             [make_op(self.Instructions[prev_pos0], 2, self.catch_value),
              make_op(self.Instructions[prev_pos1], 2, self.catch_value),
              make_op(self.Instructions[prev_pos2], 2, self.catch_value)])
     return True
示例#24
0
 def is_idiv(self):
     """
     @brief Tests if the VmInstruction is a 'vimul'.
     If True sets the PseudoInstruction
     """
     reg0 = ''
     reg1 = ''
     op_name = ''
     div_found = False
     for pos, inst in enumerate(self.Instructions):
         if (inst.is_idiv()):
             reg0 = get_reg_by_size(get_reg_class('eax'), SV.dissassm_type)
             reg1 = get_reg_by_size(get_reg_class('edx'), SV.dissassm_type)
             op_name = inst.get_op_str(1)
             div_found = True
     if not div_found:
         return False
     pos_mov = self.get_previous(Instruction.is_mov, pos)
     for pos_reg0 in pos_mov:
         if (get_reg_class(reg0) ==
               get_reg_class(self.Instructions[pos_reg0].get_reg_name(1))):
             mov_r0 = True
             break
     for pos_reg1 in pos_mov:
         if (get_reg_class(reg1) ==
               get_reg_class(self.Instructions[pos_reg1].get_reg_name(1))):
             mov_r1 = True
             break
     if mov_r0 and mov_r1:
         self.Pseudocode = PseudoInstruction('vidiv', self.addr,
             [make_op(self.Instructions[pos_reg0], 2, self.catch_value),
              make_op(self.Instructions[pos_reg1], 2, self.catch_value),
              make_op(self.Instructions[pos], 1, self.catch_value)],
             SV.dissassm_type / 8, PI.DIV_T, PI.IN3_OUT3)
         return True
     else:
         return False
示例#25
0
 def is_op2_reg(self):
     try:
         return get_reg_class(self._line[2][2]) is not None
     except:
         return False