Beispiel #1
0
    def visit_AndExpression(self, expr):
        context = yaramod.TokenStreamContext(expr)

        left_expr = expr.left_operand.accept(self)
        right_expr = expr.right_operand.accept(self)

        left_bool = left_expr if (left_expr and isinstance(left_expr, yaramod.BoolLiteralExpression)) else None
        right_bool = right_expr if (right_expr and isinstance(right_expr, yaramod.BoolLiteralExpression)) else None

        # If both sides of AND are boolean constants then determine the value based on truth table of AND
        # T and T = T
        # T and F = F
        # F and T = F
        # F and F = F
        if left_bool and right_bool:
            output = yaramod.bool_val(left_bool.value and right_bool.value).get()
            self.cleanup_tokenstreams(context, output)
            return output
        # Only left-hand side is boolean constant
        elif left_bool:
            # F and X = F
            # T and X = X
            output = yaramod.bool_val(False).get() if not left_bool.value else yaramod.YaraExpressionBuilder(right_expr if right_expr else expr.right_operand).get()
            self.cleanup_tokenstreams(context, output)
            return output
        # Only right-hand side is boolean constant
        elif right_bool:
            # X and F = F
            # X and T = X
            output = yaramod.bool_val(False).get() if not right_bool.value else yaramod.YaraExpressionBuilder(left_expr if left_expr else expr.left_operand).get()
            self.cleanup_tokenstreams(context, output)
            return output

        return self.default_handler(context, expr, left_expr, right_expr)
Beispiel #2
0
 def _visit_string_manipulation_ops(self, expr):
     context = yaramod.TokenStreamContext(expr)
     index_result = None
     if expr.index_expr:
         index_result = expr.index_expr.accept(self)
         if index_result == yaramod.VisitAction.Delete:
             return yaramod.VisitAction.Delete
     return self.default_handler(context, expr, index_result)
Beispiel #3
0
 def _visit_binary_ops(self, expr):
     context = yaramod.TokenStreamContext(expr)
     left_result = expr.left_operand.accept(self)
     right_result = expr.right_operand.accept(self)
     if left_result == yaramod.VisitAction.Delete or right_result == yaramod.VisitAction.Delete:
         return yaramod.VisitAction.Delete
     else:
         self.default_handler(context, expr, left_result,
                              right_result)
Beispiel #4
0
 def _visit_logical_ops(self, expr):
     context = yaramod.TokenStreamContext(expr)
     left_context = yaramod.TokenStreamContext(expr.left_operand)
     right_context = yaramod.TokenStreamContext(expr.right_operand)
     left_result = expr.left_operand.accept(self)
     right_result = expr.right_operand.accept(self)
     if left_result == yaramod.VisitAction.Delete or right_result == yaramod.VisitAction.Delete:
         if left_result == yaramod.VisitAction.Delete:
             new_operand = yaramod.bool_val(False).get()
             self.cleanup_tokenstreams(left_context, new_operand)
             expr.left_operand = new_operand
         if right_result == yaramod.VisitAction.Delete:
             new_operand = yaramod.bool_val(False).get()
             self.cleanup_tokenstreams(right_context, new_operand)
             expr.right_operand = new_operand
     else:
         return self.default_handler(context, expr, left_result,
                                     right_result)
Beispiel #5
0
            def visit_EqExpression(self, expr: yaramod.Expression):
                context = yaramod.TokenStreamContext(expr)
                expr.left_operand.accept(self)
                expr.right_operand.accept(self)
                output = (yaramod.YaraExpressionBuilder(expr.right_operand) !=
                          yaramod.YaraExpressionBuilder(
                              expr.left_operand)).get()

                self.cleanUpTokenStreams(context, output)
                return output
Beispiel #6
0
    def visit_ParenthesesExpression(self, expr):
        context = yaramod.TokenStreamContext(expr)
        new_expr = expr.enclosed_expr.accept(self)

        # Remove parentheses around boolean constants and lift their value up
        bool_val = new_expr if (new_expr and isinstance(new_expr, yaramod.BoolLiteralExpression)) else None
        if bool_val:
            output = yaramod.bool_val(bool_val.value).get()
            self.cleanup_tokenstreams(context, output)
            return output

        return self.default_handler(context, expr, new_expr)
Beispiel #7
0
    def visit_NotExpression(self, expr):
        context = yaramod.TokenStreamContext(expr)
        new_expr = expr.operand.accept(self)

        # Negate the value of boolean constant
        bool_val = new_expr if (new_expr and isinstance(new_expr, yaramod.BoolLiteralExpression)) else None
        if bool_val:
            output = yaramod.bool_val(not bool_val.value).get()
            self.cleanup_tokenstreams(context, output)
            return output

        return self.default_handler(context, expr, new_expr)
Beispiel #8
0
    def visit_OrExpression(self, expr):
        context = yaramod.TokenStreamContext(expr)

        left_expr = expr.left_operand.accept(self)
        right_expr = expr.right_operand.accept(self)

        left_bool = left_expr if (left_expr and isinstance(
            left_expr, yaramod.BoolLiteralExpression)) else None
        right_bool = right_expr if (right_expr and isinstance(
            right_expr, yaramod.BoolLiteralExpression)) else None

        # If both sides of OR are boolean constants then determine the value based on truth table of OR
        # T or T = T
        # T or F = T
        # F or T = T
        # F or F = F
        if left_bool and right_bool:
            output = yaramod.bool_val(left_bool.value
                                      or right_bool.value).get()
            self.cleanUpTokenStreams(context, output)
            return output
        # Only left-hand side is boolean constant
        elif left_bool:
            # T or X = T
            # F or X = X
            output = yaramod.bool_val(True).get(
            ) if left_bool.value else yaramod.YaraExpressionBuilder(
                right_expr if right_expr else expr.right_operand).get()
            self.cleanUpTokenStreams(context, output)
            return output
        # Only right-hand side is boolean constant
        elif right_bool:
            # X or T = T
            # X or F = X
            output = yaramod.bool_val(True).get(
            ) if right_bool.value else yaramod.YaraExpressionBuilder(
                left_expr if left_expr else expr.left_operand).get()
            self.cleanUpTokenStreams(context, output)
            return output

        return self.default_handler(context, expr, left_expr, right_expr)
Beispiel #9
0
            def insert_rule(self, yara_file):
                rule_cond = yaramod.conjunction(
                    [yaramod.id('first_file'),
                     yaramod.id('second_file')])

                another_rule = yaramod.YaraRuleBuilder() \
                    .with_modifier(yaramod.RuleModifier.Private) \
                    .with_name('ANOTHER_RULE') \
                    .with_condition(rule_cond.get()) \
                    .get()

                for rule in yara_file.rules:
                    if not rule.is_private:
                        context = yaramod.TokenStreamContext(rule.condition)
                        output = yaramod.conjunction([
                            yaramod.id(another_rule.name),
                            yaramod.paren(yaramod.YaraExpressionBuilder(
                                rule.condition),
                                          linebreaks=True)
                        ]).get()
                        self.cleanup_tokenstreams(context, output)
                        rule.condition = output

                yara_file.insert_rule(0, another_rule)
Beispiel #10
0
 def visit_BoolLiteralExpression(self, expr):
     # Lift up boolean value
     context = yaramod.TokenStreamContext(expr)
     output = yaramod.bool_val(expr.value).get()
     self.cleanup_tokenstreams(context, output)
     return output