156 lines
4.3 KiB
Rust
156 lines
4.3 KiB
Rust
use crate::{GhostError, MemoryRegion, ProcessInfo};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
use std::time::SystemTime;
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct DynamicYaraEngine {
|
|
rules: Vec<YaraRule>,
|
|
sources: Vec<YaraRuleSource>,
|
|
scan_cache: HashMap<String, CachedScanResult>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct YaraRule {
|
|
pub name: String,
|
|
pub content: String,
|
|
pub source: String,
|
|
pub threat_level: ThreatLevel,
|
|
pub last_updated: SystemTime,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct YaraRuleSource {
|
|
pub name: String,
|
|
pub url: String,
|
|
pub enabled: bool,
|
|
pub rule_count: usize,
|
|
pub last_update: SystemTime,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct YaraScanResult {
|
|
pub matches: Vec<RuleMatch>,
|
|
pub scan_time_ms: u64,
|
|
pub bytes_scanned: u64,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct RuleMatch {
|
|
pub rule_name: String,
|
|
pub threat_level: ThreatLevel,
|
|
pub offset: u64,
|
|
pub length: u32,
|
|
pub metadata: HashMap<String, String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
|
pub enum ThreatLevel {
|
|
Info = 1,
|
|
Low = 2,
|
|
Medium = 3,
|
|
High = 4,
|
|
Critical = 5,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
struct CachedScanResult {
|
|
result: YaraScanResult,
|
|
timestamp: SystemTime,
|
|
}
|
|
|
|
impl DynamicYaraEngine {
|
|
pub fn new(config_path: Option<&str>) -> Result<Self, GhostError> {
|
|
let sources = vec![
|
|
YaraRuleSource {
|
|
name: "Malware Bazaar".to_string(),
|
|
url: "https://bazaar.abuse.ch/browse/".to_string(),
|
|
enabled: true,
|
|
rule_count: 0,
|
|
last_update: SystemTime::now(),
|
|
},
|
|
YaraRuleSource {
|
|
name: "VX-Underground".to_string(),
|
|
url: "https://vx-underground.org/yara".to_string(),
|
|
enabled: true,
|
|
rule_count: 0,
|
|
last_update: SystemTime::now(),
|
|
},
|
|
];
|
|
|
|
Ok(DynamicYaraEngine {
|
|
rules: Vec::new(),
|
|
sources,
|
|
scan_cache: HashMap::new(),
|
|
})
|
|
}
|
|
|
|
pub async fn update_rules(&mut self) -> Result<usize, GhostError> {
|
|
let mut updated_count = 0;
|
|
|
|
for source in &mut self.sources {
|
|
if !source.enabled {
|
|
continue;
|
|
}
|
|
|
|
// Simulate rule download
|
|
let new_rules = vec![YaraRule {
|
|
name: format!("generic_malware_{}", updated_count + 1),
|
|
content: "rule generic_malware { condition: true }".to_string(),
|
|
source: source.name.clone(),
|
|
threat_level: ThreatLevel::Medium,
|
|
last_updated: SystemTime::now(),
|
|
}];
|
|
|
|
self.rules.extend(new_rules);
|
|
source.rule_count = self.rules.len();
|
|
source.last_update = SystemTime::now();
|
|
updated_count += 1;
|
|
}
|
|
|
|
Ok(updated_count)
|
|
}
|
|
|
|
pub async fn scan_process(
|
|
&self,
|
|
process: &ProcessInfo,
|
|
memory_regions: &[MemoryRegion],
|
|
) -> Result<YaraScanResult, GhostError> {
|
|
let start_time = SystemTime::now();
|
|
let mut matches = Vec::new();
|
|
let mut bytes_scanned = 0;
|
|
|
|
// Simulate YARA scanning
|
|
for (i, region) in memory_regions.iter().enumerate() {
|
|
bytes_scanned += region.size;
|
|
|
|
// Simulate finding suspicious patterns
|
|
if region.protection.is_executable() && region.protection.is_writable() {
|
|
matches.push(RuleMatch {
|
|
rule_name: "suspicious_rwx_memory".to_string(),
|
|
threat_level: ThreatLevel::High,
|
|
offset: region.base_address as u64,
|
|
length: 1024,
|
|
metadata: HashMap::new(),
|
|
});
|
|
}
|
|
}
|
|
|
|
let scan_time_ms = start_time.elapsed().unwrap_or_default().as_millis() as u64;
|
|
|
|
Ok(YaraScanResult {
|
|
matches,
|
|
scan_time_ms,
|
|
bytes_scanned: bytes_scanned as u64,
|
|
})
|
|
}
|
|
|
|
pub fn get_rule_count(&self) -> usize {
|
|
self.rules.len()
|
|
}
|
|
|
|
pub fn get_sources(&self) -> &[YaraRuleSource] {
|
|
&self.sources
|
|
}
|
|
}
|