最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Swift - YARA Malware Detection for any file macOS or iOS - Stack Overflow

programmeradmin1浏览0评论

I am writing a logic to detect whether selected file contains malware threaten file or now. Currently by using below code, I am always getting malware detected results even success case. Please help me on this

rules.yara

rule TestMalware {
strings:
    $malware = "malicious pattern"
condition:
    $malware  // Match only if the string is found
}

ViewController.swift

import Cocoa

class ViewController: NSViewController {

private var yaraRules: UnsafeMutablePointer<YR_RULES>?

override func viewDidLoad() {
    super.viewDidLoad()
    if !initializeYARA() {
        handleError("YARA initialization failed.")
    }
}

deinit {
    cleanupYARA()
}

private func initializeYARA() -> Bool {
    // Initialize YARA library
    guard yr_initialize() == ERROR_SUCCESS else {
        handleError("Failed to initialize YARA.")
        return false
    }
    
    // Get the rule file path from the bundle
    guard let ruleFilePath = Bundle.main.path(forResource: "rules", ofType: "yara") else {
        handleError("Could not find YARA rule file in bundle.")
        yr_finalize()
        return false
    }
    
    print("Rule file path: \(ruleFilePath)")
    
    // Open the rules file
    guard let cString = ruleFilePath.cString(using: .utf8),
          let fileHandle = fopen(cString, "r") else {
        handleError("Failed to open rules file.")
        yr_finalize()
        return false
    }
    
    defer {
        fclose(fileHandle)
    }
    
    // Create the YARA compiler
    var compiler: UnsafeMutablePointer<YR_COMPILER>?
    guard yr_compiler_create(&compiler) == ERROR_SUCCESS else {
        handleError("Failed to create YARA compiler.")
        yr_finalize()
        return false
    }
    
    defer {
        yr_compiler_destroy(compiler)
    }
    
    // Add rules file to compiler
    if yr_compiler_add_file(compiler, fileHandle, nil, nil) != ERROR_SUCCESS {
        handleError("Failed to compile YARA rules.")
        yr_finalize()
        return false
    }
    
    // Get compiled rules
    guard yr_compiler_get_rules(compiler, &yaraRules) == ERROR_SUCCESS else {
        handleError("Failed to load compiled YARA rules.")
        yr_finalize()
        return false
    }
    
    print("YARA rules successfully loaded.")
    return true
}

@IBAction func actionYARAScanButtonTapped(_ sender: Any) {
    guard yaraRules != nil else {
        handleError("YARA rules not initialized. Please initialize first.")
        return
    }
    runMalwareScan()
}
}

extension ViewController {

private func runMalwareScan() {
    let openPanel = NSOpenPanel()
    openPanel.message = "Select a file to scan for malware"
    openPanel.canChooseFiles = true
    openPanel.canChooseDirectories = false
    openPanel.allowsMultipleSelection = false
    
    openPanel.begin { [weak self] result in
        guard result == .OK, let filePath = openPanel.url?.path else { return }
        print("Selected file for scanning: \(filePath)")
        
        if let isMalicious = self?.scanFile(at: filePath), isMalicious {
            self?.showScanResult("⚠️ Malware Detected!", "The selected file has a suspicious extension.")
        } else {
            self?.showScanResult("✅ File Clean", "No suspicious extensions were detected in the selected file.")
        }
    }
}

func scanFile(at path: String) -> Bool {
    guard let rules = yaraRules else {
        handleError("YARA rules not initialized")
        return false
    }
    
    // Read file content into memory
    guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: path)) else {
        handleError("Failed to read file content at path: \(path)")
        return false
    }
    
    // Print file content for debugging
    if let fileContent = String(data: fileData, encoding: .utf8) {
        print("File content: \(fileContent)")
    }
    
    var matchFound = false
    
    let callback: YR_CALLBACK_FUNC = { context, message, rule, userData in
        guard let userData = userData else { return CALLBACK_ERROR }
        let matchFoundPtr = userData.assumingMemoryBound(to: Bool.self)
        matchFoundPtr.pointee = true
        
        if let rule = rule {
            let rulePointer = rule.assumingMemoryBound(to: YR_RULE.self)
            let ruleIdentifier = String(cString: rulePointer.pointee.identifier)
            print("[YARA Match] Rule matched: \(ruleIdentifier)")  // Debugging matched rule
        }
        
        return CALLBACK_CONTINUE
    }
    
    let result = fileData.withUnsafeBytes { bytes in
        yr_rules_scan_mem(
            rules,
            bytes.baseAddress,
            fileData.count,
            SCAN_FLAGS_FAST_MODE,
            callback,
            &matchFound,
            0
        )
    }
    
    guard result == ERROR_SUCCESS else {
        handleError("Scan failed with error: \(result)")
        return false
    }
    
    print("Match found: \(matchFound)")  // Debugging match result
    return matchFound
}

private func cleanupYARA() {
    if let rules = yaraRules {
        yr_rules_destroy(rules)
    }
    yr_finalize()
}

private func showScanResult(_ title: String, _ message: String) {
    DispatchQueue.main.async {
        let alert = NSAlert()
        alert.messageText = title
        alert.informativeText = message
        alert.alertStyle = .informational
        alert.addButton(withTitle: "OK")
        alert.runModal()
    }
}
}

extension ViewController {
private func handleError(_ message: String) {
    print("[YARA Error] \(message)")
    let alert = NSAlert()
    alert.messageText = "YARA Error"
    alert.informativeText = message
    alert.alertStyle = .warning
    alert.addButton(withTitle: "OK")
    alert.runModal()
}
}
发布评论

评论列表(0)

  1. 暂无评论