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)
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)
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)
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)
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
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)
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)
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)
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)
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