Beispiel #1
0
    def __parse_unary_expression__(self, symbol_node: jcmuta.SymbolNode,
                                   code: int):
        """
		:param symbol_node: negative, bit_not, logic_not, address_of, dereference
		:param code:
		:return:
		"""
        operator = symbol_node.get_content().get_token_value()
        operand = symbol_node.get_child(1)
        if operator == "negative":
            u_operand = self.__parse__(operand, code)
            return -self.__cast_to_numb__(u_operand)
        elif operator == "bit_not":
            u_operand = self.__parse__(operand, self.__s_code__)
            return ~self.__cast_to_bits__(u_operand)
        elif operator == "logic_not":
            u_operand = self.__parse__(operand, code)
            return z3.Not(self.__cast_to_bool__(u_operand))
        elif operator == "address_of":
            return z3.Const(self.__unique_name__(symbol_node), z3.IntSort())
        else:
            name = self.__unique_name__(symbol_node)
            name = self.__normal_name__(name, symbol_node.get_data_type())
            return self.__new_reference__(name, symbol_node.get_data_type(),
                                          code)
Beispiel #2
0
 def __parse_if_else_expression__(self, symbol_node: jcmuta.SymbolNode,
                                  code: int):
     condition = self.__parse__(symbol_node.get_child(0), code)
     loperand = self.__parse__(symbol_node.get_child(1), code)
     roperand = self.__parse__(symbol_node.get_child(2), code)
     condition = self.__cast_to_bool__(condition)
     return z3.If(condition, loperand, roperand)
Beispiel #3
0
 def __parse_list_expression__(self, symbol_node: jcmuta.SymbolNode,
                               code: int):
     elements = list()
     for child in symbol_node.get_children():
         elements.append(self.__parse__(child, code))
     name = self.__unique_name__(symbol_node)
     return self.__new_reference__(name, symbol_node.get_data_type(), code)
Beispiel #4
0
 def __parse_assign_expression__(self, symbol_node: jcmuta.SymbolNode):
     operator = str(symbol_node.get_content().get_token_value()).strip()
     loperand = self.__parse__(symbol_node.get_child(1))
     roperand = self.__parse__(symbol_node.get_child(2))
     self.__save__(loperand.sexpr(), roperand)
     if operator == "assign":
         return roperand
     else:
         return loperand
Beispiel #5
0
 def __parse_logic_expression__(self, symbol_node: jcmuta.SymbolNode):
     operator = str(symbol_node.get_content().get_token_value()).strip()
     loperand = self.__parse__(symbol_node.get_child(1))
     roperand = self.__parse__(symbol_node.get_child(2))
     loperand = self.__cast_to_bool__(loperand)
     roperand = self.__cast_to_bool__(roperand)
     if operator == "logic_and":
         return z3.And(loperand, roperand)
     else:
         return z3.Or(loperand, roperand)
Beispiel #6
0
    def __parse_identifier__(self, symbol_node: jcmuta.SymbolNode, code: int):
        """
		:param symbol_node:
		:param code:
		:return:
		"""
        name = symbol_node.get_content().get_token_value()
        data_type = symbol_node.get_data_type()
        name = self.__normal_name__(name, data_type)
        return self.__new_reference__(name, data_type, code)
Beispiel #7
0
    def __unique_name__(self, symbol_node: jcmuta.SymbolNode):
        """
		:param symbol_node: the node of which unique name is created
		:return: the unique name of the symbol_node
		"""
        class_name = symbol_node.get_class_name()
        class_id = symbol_node.get_class_id()
        class_flag = 'p'
        if class_id < 0:
            class_id = abs(class_id)
            class_flag = 'n'
        return self.__naming__.format(class_name, class_flag, class_id)
Beispiel #8
0
 def __parse_call_expression__(self, symbol_node: jcmuta.SymbolNode):
     function = symbol_node.get_child(0)
     if function.get_class_name() == "Identifier":
         func_name = function.get_content().get_token_value()
     else:
         func_name = self.__new_default_name__(function)
     arguments = symbol_node.get_child(1).get_children()
     for k in range(0, len(arguments)):
         arg = self.__parse__(arguments[k])
         self.__save__("{}#{}".format(func_name, k), arg)
     return self.__parse_by_name__(
         "{}_{}".format(func_name, symbol_node.get_class_id()),
         symbol_node.get_data_type())
Beispiel #9
0
    def __parse_constant__(self, symbol_node: jcmuta.SymbolNode, code: int):
        """
		:param symbol_node:
		:param code:
		:return: constant of z3 expression
		"""
        return self.__new_constant__(symbol_node.get_content(), code)
Beispiel #10
0
    def __parse__(self, symbol_node: jcmuta.SymbolNode, code: int):
        """
		:param symbol_node:
		:param code:
		:return: it recursively parses the symbolic node to z3.sexpr
		"""
        symbol_class = symbol_node.get_class_name()
        if symbol_class == "Identifier":
            return self.__parse_identifier__(symbol_node, code)
        elif symbol_class == "Constant":
            return self.__parse_constant__(symbol_node, code)
        elif symbol_class == "Literal":
            return self.__parse_literal__(symbol_node)
        elif symbol_class == "UnaryExpression":
            return self.__parse_unary_expression__(symbol_node, code)
        elif symbol_class == "ArithExpression":
            return self.__parse_arith_expression__(symbol_node, code)
        elif symbol_class == "BitwsExpression":
            return self.__parse_bitws_expression__(symbol_node)
        elif symbol_class == "LogicExpression":
            return self.__parse_logic_expression__(symbol_node, code)
        elif symbol_class == "RelationExpression":
            return self.__parse_relation_expression__(symbol_node, code)
        elif symbol_class == "AssignExpression":
            return self.__parse_assign_expression__(symbol_node, code)
        elif symbol_class == "CastExpression":
            return self.__parse_casted_expression__(symbol_node, code)
        elif symbol_class == "FieldExpression":
            return self.__parse_field_expression__(symbol_node, code)
        elif symbol_class == "IfElseExpression":
            return self.__parse_if_else_expression__(symbol_node, code)
        elif symbol_class == "CallExpression":
            return self.__parse_call_expression__(symbol_node, code)
        else:
            return self.__parse_list_expression__(symbol_node, code)
Beispiel #11
0
 def __parse_relation_expression__(self, symbol_node: jcmuta.SymbolNode):
     operator = str(symbol_node.get_content().get_token_value()).strip()
     loperand = self.__parse__(symbol_node.get_child(1))
     roperand = self.__parse__(symbol_node.get_child(2))
     if operator == "greater_tn":
         return loperand > roperand
     elif operator == "greater_eq":
         return loperand >= roperand
     elif operator == "smaller_tn":
         return loperand < roperand
     elif operator == "smaller_eq":
         return loperand <= roperand
     elif operator == "equal_with":
         return loperand == roperand
     else:
         return loperand != roperand
Beispiel #12
0
 def __parse_bitws_expression__(self, symbol_node: jcmuta.SymbolNode):
     operator = str(symbol_node.get_content().get_token_value()).strip()
     self.bitSwitch = True
     loperand = self.__parse__(symbol_node.get_child(1))
     self.bitSwitch = True
     roperand = self.__parse__(symbol_node.get_child(2))
     self.bitSwitch = False
     if operator == "bit_and":
         return loperand & roperand
     elif operator == "bit_or":
         return loperand | roperand
     elif operator == "bit_xor":
         return loperand ^ roperand
     elif operator == "left_shift":
         return loperand << roperand
     else:
         return loperand >> roperand
Beispiel #13
0
    def __parse_arith_expression__(self, symbol_node: jcmuta.SymbolNode):
        """
		:param symbol_node:
		:return:
		"""
        operator = str(symbol_node.get_content().get_token_value()).strip()
        loperand = self.__parse__(symbol_node.get_child(1))
        roperand = self.__parse__(symbol_node.get_child(2))
        if operator == "arith_add":
            return loperand + roperand
        elif operator == "arith_sub":
            return loperand - roperand
        elif operator == "arith_mul":
            return loperand * roperand
        elif operator == "arith_div":
            return loperand / roperand
        else:
            return loperand % roperand
Beispiel #14
0
    def __parse_logic_expression__(self, symbol_node: jcmuta.SymbolNode,
                                   code: int):
        """
		:param symbol_node:
		:param code:
		:return:
		"""
        operator = symbol_node.get_content().get_token_value()
        loperand = self.__cast_to_bool__(
            self.__parse__(symbol_node.get_child(1), code))
        roperand = self.__cast_to_bool__(
            self.__parse__(symbol_node.get_child(2), code))
        if operator == "logic_and":
            return z3.And(loperand, roperand)
        elif operator == "logic_or":
            return z3.Or(loperand, roperand)
        else:
            return z3.Implies(loperand, roperand)
Beispiel #15
0
    def __parse_call_expression__(self, symbol_node: jcmuta.SymbolNode,
                                  code: int):
        """
		:param symbol_node:
		:param code:
		:return:
		"""
        function = symbol_node.get_child(0)
        if function.get_class_name() == "Identifier":
            func_name = function.get_content().get_token_value()
        else:
            func_name = self.__unique_name__(function)
        arguments = symbol_node.get_child(1).get_children()
        for k in range(0, len(arguments)):
            arg = self.__parse__(arguments[k], 0)
            self.__save_state__("{}#{}".format(func_name, k), arg)
        return self.__new_reference__(func_name, symbol_node.get_data_type(),
                                      code)
Beispiel #16
0
 def __parse_constant__(self, symbol_node: jcmuta.SymbolNode):
     constant = symbol_node.get_content().get_token_value()
     if isinstance(constant, bool):
         return z3.BoolVal(constant)
     elif isinstance(constant, int):
         if self.bitSwitch:
             return z3.BitVecVal(constant, self.longSize)
         else:
             return z3.IntVal(constant)
     else:
         return z3.RealVal(constant)
Beispiel #17
0
    def __parse_bitws_expression__(self, symbol_node: jcmuta.SymbolNode):
        """
		:param symbol_node:
		:return:
		"""
        operator = symbol_node.get_content().get_token_value()
        loperand = self.__cast_to_bits__(
            self.__parse__(symbol_node.get_child(1), self.__s_code__))
        roperand = self.__cast_to_bits__(
            self.__parse__(symbol_node.get_child(2), self.__s_code__))
        if operator == "bit_and":
            return loperand & roperand
        elif operator == "bit_or":
            return loperand | roperand
        elif operator == "bit_xor":
            return loperand ^ roperand
        elif operator == "left_shift":
            return loperand << roperand
        else:
            return loperand >> roperand
Beispiel #18
0
    def __parse_arith_expression__(self, symbol_node: jcmuta.SymbolNode,
                                   code: int):
        """
		:param symbol_node: +, -, *, /, %
		:param code:
		:return:
		"""
        operator = symbol_node.get_content().get_token_value()
        loperand = self.__cast_to_numb__(
            self.__parse__(symbol_node.get_child(1), code))
        roperand = self.__cast_to_numb__(
            self.__parse__(symbol_node.get_child(2), code))
        if operator == "arith_add":
            return loperand + roperand
        elif operator == "arith_sub":
            return loperand - roperand
        elif operator == "arith_mul":
            return loperand * roperand
        elif operator == "arith_div":
            return loperand / roperand
        else:
            return loperand % roperand
Beispiel #19
0
    def __parse_unary_expression__(self, symbol_node: jcmuta.SymbolNode):
        """
		:param symbol_node:
		:return: neg, rsv, not, adr, der
		"""
        operator = symbol_node.get_content().get_token_value()
        u_operand = self.__parse__(symbol_node.get_child(1))
        if operator == "negative":
            return -u_operand
        elif operator == "bit_not":
            if isinstance(u_operand, z3.IntNumRef) or isinstance(
                    u_operand, z3.ArithRef):
                return -u_operand - 1
            else:
                return ~u_operand
        elif operator == "logic_not":
            return z3.Not(self.__cast_to_bool__(u_operand))
        elif operator == "address_of":
            return z3.Const(self.__new_default_name__(symbol_node),
                            z3.IntSort())
        else:
            return self.__parse_by_name__(
                self.__new_default_name__(symbol_node),
                symbol_node.get_data_type())
Beispiel #20
0
    def __parse_relation_expression__(self, symbol_node: jcmuta.SymbolNode,
                                      code: int):
        """
		:param symbol_node:
		:param code:
		:return:
		"""
        operator = symbol_node.get_content().get_token_value()
        loperand = self.__cast_to_numb__(
            self.__parse__(symbol_node.get_child(1), code))
        roperand = self.__cast_to_numb__(
            self.__parse__(symbol_node.get_child(2), code))
        if operator == "greater_tn":
            return loperand > roperand
        elif operator == "greater_eq":
            return loperand >= roperand
        elif operator == "smaller_tn":
            return loperand < roperand
        elif operator == "smaller_eq":
            return loperand <= roperand
        elif operator == "equal_with":
            return loperand == roperand
        else:
            return loperand != roperand
Beispiel #21
0
 def __parse_identifier__(self, symbol_node: jcmuta.SymbolNode):
     return self.__parse_by_name__(
         symbol_node.get_content().get_token_value(),
         symbol_node.get_data_type())
Beispiel #22
0
 def __parse_field_expression__(self, symbol_node: jcmuta.SymbolNode):
     return self.__parse_by_name__(self.__new_default_name__(symbol_node),
                                   symbol_node.get_data_type())
Beispiel #23
0
 def __parse_if_else_expression__(self, symbol_node: jcmuta.SymbolNode):
     condition = self.__parse__(symbol_node.get_child(0))
     loperand = self.__parse__(symbol_node.get_child(1))
     roperand = self.__parse__(symbol_node.get_child(2))
     return z3.If(condition, loperand, roperand)
Beispiel #24
0
 def __new_default_name__(self, symbol_node: jcmuta.SymbolNode):
     self.__assume__(None)
     return "{}_{}".format(symbol_node.get_class_name(),
                           abs(symbol_node.get_class_id()))
Beispiel #25
0
 def __parse_field_expression__(self, symbol_node: jcmuta.SymbolNode,
                                code: int):
     name = self.__unique_name__(symbol_node)
     name = self.__normal_name__(name, symbol_node.get_data_type())
     return self.__new_reference__(name, symbol_node.get_data_type(), code)
Beispiel #26
0
 def __parse_casted_expression__(self, symbol_node: jcmuta.SymbolNode,
                                 code: int):
     return self.__parse__(symbol_node.get_child(1), code)
Beispiel #27
0
 def __parse_list_expression__(self, symbol_node: jcmuta.SymbolNode):
     elements = list()
     for child in symbol_node.get_children():
         elements.append(self.__parse__(child))
     return self.__parse_by_name__(self.__new_default_name__(symbol_node),
                                   symbol_node.get_data_type())