Skip to content

Commit 432ce2a

Browse files
committed
feat: implement ETW-based real-time monitoring for process and registry
1 parent ea55d86 commit 432ce2a

File tree

9 files changed

+1847
-342
lines changed

9 files changed

+1847
-342
lines changed

Cargo.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ resolver = "2"
33
members = ["actions", "bus", "engine", "engine_core", "rules"]
44

55
[workspace.package]
6-
version = "0.1.2"
6+
version = "0.1.3"
77
edition = "2024"
88
authors = ["Your Name"]
99
license = "MIT"

README.md

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,18 @@ A universal event automation system for Windows built in Rust. Monitor file syst
1010
### Event Sources
1111
- **File System Watcher** - Monitor file creation, modification, deletion with pattern matching
1212
- **Window Event Monitor** - Track window focus, creation, destruction using Win32 API
13-
- **Process Monitor** - Detect process start/stop events with filtering
14-
- **Registry Monitor** - Watch registry key changes in real-time
13+
- **Process Monitor** - Kernel-level ETW process monitoring with real-time events (process, thread, file I/O, network)
14+
- **Requires Administrator privileges**
15+
- Process start/stop events with full details (PID, parent PID, command line, session ID)
16+
- Thread creation/destruction monitoring
17+
- File I/O operations per process
18+
- Network connections per process
19+
- **Registry Monitor** - Kernel-level ETW registry monitoring with real-time events
20+
- **Requires Administrator privileges**
21+
- Registry key creation, deletion, modification
22+
- Registry value set, delete, modify operations
23+
- Process context for each operation
24+
- Filter by registry hive and path
1525

1626
### Rule Engine
1727
- Pattern-based matching using glob syntax (`*.txt`, `**/*.log`)
@@ -115,7 +125,10 @@ enabled = false
115125
[[sources]]
116126
name = "process_monitor"
117127
type = "process_monitor"
118-
poll_interval_seconds = 2
128+
process_name = "chrome"
129+
monitor_threads = false
130+
monitor_files = false
131+
monitor_network = false
119132
enabled = false
120133

121134
# Registry monitor - watch for system changes
@@ -227,8 +240,8 @@ engine.exe --uninstall
227240
│ Event Sources: │
228241
│ ├── File Watcher (notify crate) │
229242
│ ├── Window Watcher (Win32 API) │
230-
│ ├── Process Monitor (EnumProcesses)
231-
│ └── Registry Monitor (RegNotifyChangeKeyValue)
243+
│ ├── Process Monitor (ETW - kernel-level real-time)
244+
│ └── Registry Monitor (ETW - kernel-level real-time)
232245
│ │
233246
│ Event Bus (tokio mpsc channels) │
234247
│ │
@@ -302,11 +315,29 @@ The engine supports the following event types:
302315
- `WindowUnfocused` - Window lost focus
303316

304317
### Process Events
305-
- `ProcessStarted` - New process launched
306-
- `ProcessStopped` - Process terminated
307-
308-
### Registry Events
309-
- `RegistryChanged` - Registry value modified
318+
- `ProcessStarted` - New process launched (includes PID, parent PID, name, path, command line, session ID, user)
319+
- `ProcessStopped` - Process terminated (includes PID, name, exit code)
320+
321+
### Thread Events
322+
- `ThreadCreated` - New thread created in a process (includes PID, TID, start address)
323+
- `ThreadDestroyed` - Thread terminated (includes PID, TID)
324+
325+
### File I/O Events (Process Context)
326+
- `FileAccessed` - File accessed by a process (includes PID, path, access mask)
327+
- `FileIoRead` - File read operation (includes PID, path, bytes read)
328+
- `FileIoWrite` - File write operation (includes PID, path, bytes written)
329+
- `FileIoDelete` - File deleted by a process (includes PID, path)
330+
331+
### Network Events
332+
- `NetworkConnectionCreated` - New network connection (includes PID, local/remote addresses, protocol)
333+
- `NetworkConnectionClosed` - Network connection closed (includes PID, addresses)
334+
335+
### Registry Events (via ETW - includes process context)
336+
- `RegistryChanged` - Registry operation detected with change type:
337+
- **Created** - New registry key created
338+
- **Modified** - Registry value modified or set
339+
- **Deleted** - Registry key or value deleted
340+
- **Event metadata includes**: Process name, Process ID, Registry path, Value name (if applicable)
310341

311342
## Development
312343

engine/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ tracing = "0.1"
1818
tracing-subscriber = { version = "0.3", features = ["fmt"] }
1919
notify = "6"
2020
clap = { version = "4", features = ["derive"] }
21-
windows = { version = "0.52", features = ["Win32_Foundation", "Win32_UI_WindowsAndMessaging", "Win32_UI_Accessibility", "Win32_System_Threading", "Win32_System_ProcessStatus", "Win32_System_Registry", "Win32_System_Services", "Win32_Security"] }
21+
windows = { version = "0.52", features = ["Win32_Foundation", "Win32_UI_WindowsAndMessaging", "Win32_UI_Accessibility", "Win32_System_Threading", "Win32_System_ProcessStatus", "Win32_System_Registry", "Win32_System_Services", "Win32_Security", "Win32_System_Diagnostics_Etw", "Win32_Storage_FileSystem", "Win32_System_Time", "Win32_System_Diagnostics_ToolHelp"] }
2222
windows-service = "0.8"
2323
lazy_static = "1.4"
2424
regex = "1"

engine/src/config.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,12 @@ pub enum SourceType {
7171
ProcessMonitor {
7272
#[serde(default)]
7373
process_name: Option<String>,
74-
#[serde(default = "default_poll_interval")]
75-
poll_interval_seconds: u64,
74+
#[serde(default)]
75+
monitor_threads: bool,
76+
#[serde(default)]
77+
monitor_files: bool,
78+
#[serde(default)]
79+
monitor_network: bool,
7680
},
7781
RegistryMonitor {
7882
root: String,
@@ -86,10 +90,6 @@ fn default_true() -> bool {
8690
true
8791
}
8892

89-
fn default_poll_interval() -> u64 {
90-
2
91-
}
92-
9393
#[derive(Debug, Clone, Deserialize, Serialize)]
9494
pub struct RuleConfig {
9595
pub name: String,

engine/src/engine.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,14 @@ impl Engine {
165165
}
166166
SourceType::ProcessMonitor {
167167
process_name,
168-
poll_interval_seconds,
168+
monitor_threads,
169+
monitor_files,
170+
monitor_network,
169171
} => {
170172
let mut plugin = ProcessMonitorPlugin::new(&config.name)
171-
.with_poll_interval(*poll_interval_seconds);
173+
.with_thread_monitoring(*monitor_threads)
174+
.with_file_monitoring(*monitor_files)
175+
.with_network_monitoring(*monitor_network);
172176

173177
if let Some(name) = process_name {
174178
plugin = plugin.with_name_filter(name);
@@ -288,14 +292,19 @@ impl Engine {
288292
TriggerConfig::ProcessStarted { process_name: _ } => Box::new(EventKindMatcher {
289293
kind: EventKind::ProcessStarted {
290294
pid: 0,
295+
parent_pid: 0,
291296
name: String::new(),
297+
path: String::new(),
292298
command_line: String::new(),
299+
session_id: 0,
300+
user: String::new(),
293301
},
294302
}),
295303
TriggerConfig::ProcessStopped { process_name: _ } => Box::new(EventKindMatcher {
296304
kind: EventKind::ProcessStopped {
297305
pid: 0,
298306
name: String::new(),
307+
exit_code: None,
299308
},
300309
}),
301310
TriggerConfig::RegistryChanged { value_name: _ } => Box::new(EventKindMatcher {

0 commit comments

Comments
 (0)