def visit_AndExpression(self, 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: return yaramod.bool_val(left_bool.value and right_bool.value).get() # Only left-hand side is boolean constant elif left_bool: # F and X = F # T and X = X return yaramod.bool_val(False).get() if not left_bool.value else expr.right_operand # Only right-hand side is boolean constant elif right_bool: # X and F = F # X and T = X return yaramod.bool_val(False).get() if not right_bool.value else expr.left_operand return self.default_handler(expr, left_expr, right_expr)
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_OrExpression(self, 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: return yaramod.bool_val(left_bool.value or right_bool.value).get() # Only left-hand side is boolean constant elif left_bool: # T or X = T # F or X = X return yaramod.bool_val(True).get() if left_bool.value else expr.right_operand # Only right-hand side is boolean constant elif right_bool: # X or T = T # X or F = X return yaramod.bool_val(True).get() if right_bool.value else expr.left_operand return self.default_handler(expr, left_expr, right_expr)
def visit_ParenthesesExpression(self, 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: return yaramod.bool_val(bool_val.value).get() return self.default_handler(expr, new_expr)
def visit_NotExpression(self, 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: return yaramod.bool_val(not bool_val.value).get() return self.default_handler(expr, new_expr)
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 delete_pe_iconhash(self, yara_file): pe_symbol = yara_file.find_symbol('pe') if not pe_symbol: return for rule in yara_file.rules: rule.condition = self.modify( rule.condition, when_deleted=yaramod.bool_val(False).get())
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 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 remove_disabled_rules(self, yara_file: yaramod.YaraFile) -> None: for rule in yara_file.rules: if rule.name.startswith('delete'): self.rules_for_remove.add(rule.name) yara_file.remove_rules( lambda r: r.name in self.rules_for_remove) for rule in yara_file.rules: rule.condition = self.modify( rule.condition, when_deleted=yaramod.bool_val(False).get())
def main(): if len(sys.argv) != 2: sys.exit('Usage: {} YARA_FILE'.format(sys.argv[0])) simplifier = BoolSimplifier() yara_file = yaramod.parse_file(sys.argv[1]) for rule in yara_file.rules: print('==== RULE: {}'.format(rule.name)) print('==== BEFORE') print(rule.text) rule.condition = simplifier.modify(rule.condition, when_deleted=yaramod.bool_val(False).get()) print('==== AFTER') print(rule.text)
def replace_functions(self, yara_file): cuckoo_symbol = yara_file.find_symbol('cuckoo') if not cuckoo_symbol: return if not self.filesystem_symbol and not self.registry_symbol: self.filesystem_symbol = yara_file.find_symbol( 'cuckoo').get_attribute('network').get_attribute( 'http_request') for rule in yara_file.rules: rule.condition = self.modify( rule.condition, when_deleted=yaramod.bool_val(False).get())
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
def visit_BoolLiteralExpression(self, expr): # Lift up boolean value return yaramod.bool_val(expr.value).get()