iflow-mcp_bethington-cheat-engine-server-python 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. iflow_mcp_bethington_cheat_engine_server_python-0.1.0.dist-info/METADATA +16 -0
  2. iflow_mcp_bethington_cheat_engine_server_python-0.1.0.dist-info/RECORD +40 -0
  3. iflow_mcp_bethington_cheat_engine_server_python-0.1.0.dist-info/WHEEL +5 -0
  4. iflow_mcp_bethington_cheat_engine_server_python-0.1.0.dist-info/entry_points.txt +2 -0
  5. iflow_mcp_bethington_cheat_engine_server_python-0.1.0.dist-info/licenses/LICENSE +21 -0
  6. iflow_mcp_bethington_cheat_engine_server_python-0.1.0.dist-info/top_level.txt +1 -0
  7. server/cheatengine/__init__.py +19 -0
  8. server/cheatengine/ce_bridge.py +1670 -0
  9. server/cheatengine/lua_interface.py +460 -0
  10. server/cheatengine/table_parser.py +1221 -0
  11. server/config/__init__.py +20 -0
  12. server/config/settings.py +347 -0
  13. server/config/whitelist.py +378 -0
  14. server/gui_automation/__init__.py +43 -0
  15. server/gui_automation/core/__init__.py +8 -0
  16. server/gui_automation/core/integration.py +951 -0
  17. server/gui_automation/demos/__init__.py +8 -0
  18. server/gui_automation/demos/basic_demo.py +754 -0
  19. server/gui_automation/demos/notepad_demo.py +460 -0
  20. server/gui_automation/demos/simple_demo.py +319 -0
  21. server/gui_automation/tools/__init__.py +8 -0
  22. server/gui_automation/tools/mcp_tools.py +974 -0
  23. server/main.py +519 -0
  24. server/memory/__init__.py +0 -0
  25. server/memory/analyzer.py +0 -0
  26. server/memory/reader.py +0 -0
  27. server/memory/scanner.py +0 -0
  28. server/memory/symbols.py +0 -0
  29. server/process/__init__.py +16 -0
  30. server/process/launcher.py +608 -0
  31. server/process/manager.py +185 -0
  32. server/process/monitors.py +202 -0
  33. server/process/permissions.py +131 -0
  34. server/process_whitelist.json +119 -0
  35. server/pyautogui/__init__.py +0 -0
  36. server/utils/__init__.py +37 -0
  37. server/utils/data_types.py +368 -0
  38. server/utils/formatters.py +430 -0
  39. server/utils/validators.py +340 -0
  40. server/window_automation/__init__.py +59 -0
@@ -0,0 +1,185 @@
1
+ """
2
+ Process Manager Module
3
+ Handles process enumeration, attachment, and management
4
+ Cross-platform version supporting both Windows and Linux
5
+ """
6
+
7
+ import psutil
8
+ import logging
9
+ import platform
10
+ from typing import Dict, List, Optional, Any
11
+ from dataclasses import dataclass
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ # Detect platform
16
+ IS_WINDOWS = platform.system() == 'Windows'
17
+
18
+ # Windows-specific imports
19
+ if IS_WINDOWS:
20
+ import ctypes
21
+ import ctypes.wintypes
22
+
23
+ # Windows API constants
24
+ PROCESS_QUERY_INFORMATION = 0x0400
25
+ PROCESS_VM_READ = 0x0010
26
+ PROCESS_VM_WRITE = 0x0020
27
+ PROCESS_VM_OPERATION = 0x0008
28
+ PROCESS_ALL_ACCESS = 0x1F0FFF
29
+
30
+ @dataclass
31
+ class ProcessInfo:
32
+ """Process information structure"""
33
+ pid: int
34
+ name: str
35
+ exe_path: str
36
+ architecture: str
37
+ memory_usage: int
38
+ handle: Optional[int] = None
39
+ access_level: str = "none"
40
+
41
+ class ProcessManager:
42
+ """Manages process attachment and operations"""
43
+
44
+ def __init__(self):
45
+ self.current_process: Optional[ProcessInfo] = None
46
+ if IS_WINDOWS:
47
+ self.kernel32 = ctypes.windll.kernel32
48
+ else:
49
+ self.kernel32 = None
50
+
51
+ def list_processes(self) -> List[Dict[str, Any]]:
52
+ """Enumerate all running processes"""
53
+ processes = []
54
+
55
+ try:
56
+ for proc in psutil.process_iter(['pid', 'name', 'exe', 'memory_info']):
57
+ try:
58
+ info = proc.info
59
+ if info['name'] and info['pid'] > 0:
60
+ # Get architecture info
61
+ arch = self._get_process_architecture(info['pid'])
62
+
63
+ processes.append({
64
+ 'pid': info['pid'],
65
+ 'name': info['name'],
66
+ 'exe_path': info['exe'] or 'N/A',
67
+ 'architecture': arch,
68
+ 'memory_usage': info['memory_info'].rss if info['memory_info'] else 0
69
+ })
70
+ except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
71
+ continue
72
+
73
+ except Exception as e:
74
+ logger.error(f"Error enumerating processes: {e}")
75
+
76
+ return sorted(processes, key=lambda x: x['name'].lower())
77
+
78
+ def _get_process_architecture(self, pid: int) -> str:
79
+ """Determine process architecture (32-bit or 64-bit)"""
80
+ try:
81
+ if IS_WINDOWS:
82
+ handle = self.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION, False, pid)
83
+ if not handle:
84
+ return "Unknown"
85
+
86
+ try:
87
+ # Check if process is WOW64 (32-bit on 64-bit Windows)
88
+ is_wow64 = ctypes.wintypes.BOOL()
89
+ if self.kernel32.IsWow64Process(handle, ctypes.byref(is_wow64)):
90
+ if is_wow64.value:
91
+ return "x86"
92
+ else:
93
+ # Check system architecture
94
+ if platform.machine().endswith('64'):
95
+ return "x64"
96
+ else:
97
+ return "x86"
98
+ return "Unknown"
99
+ finally:
100
+ self.kernel32.CloseHandle(handle)
101
+ else:
102
+ # Linux: Use /proc filesystem
103
+ try:
104
+ with open(f'/proc/{pid}/exe', 'rb') as f:
105
+ exe_path = f.read()
106
+ # Check if executable path contains 32-bit indicators
107
+ if b'32' in exe_path or b'x86' in exe_path:
108
+ return "x86"
109
+ # Check system architecture
110
+ if platform.machine().endswith('64'):
111
+ return "x64"
112
+ return "x86"
113
+ except (FileNotFoundError, PermissionError):
114
+ return "Unknown"
115
+ except Exception as e:
116
+ logger.error(f"Error getting process architecture: {e}")
117
+ return "Unknown"
118
+
119
+ def attach_process(self, pid: int) -> ProcessInfo:
120
+ """Attach to a process"""
121
+ try:
122
+ proc = psutil.Process(pid)
123
+
124
+ process_info = ProcessInfo(
125
+ pid=pid,
126
+ name=proc.name(),
127
+ exe_path=proc.exe() or 'N/A',
128
+ architecture=self._get_process_architecture(pid),
129
+ memory_usage=proc.memory_info().rss,
130
+ handle=pid if not IS_WINDOWS else None,
131
+ access_level="full" if IS_WINDOWS else "limited"
132
+ )
133
+
134
+ self.current_process = process_info
135
+ logger.info(f"Attached to process {pid} ({process_info.name})")
136
+ return process_info
137
+
138
+ except psutil.NoSuchProcess:
139
+ raise Exception(f"Process {pid} not found")
140
+ except psutil.AccessDenied:
141
+ raise Exception(f"Access denied to process {pid}")
142
+ except Exception as e:
143
+ raise Exception(f"Failed to attach to process {pid}: {e}")
144
+
145
+ def detach_process(self) -> bool:
146
+ """Detach from current process"""
147
+ try:
148
+ if self.current_process:
149
+ if IS_WINDOWS and self.current_process.handle:
150
+ self.kernel32.CloseHandle(self.current_process.handle)
151
+ self.current_process = None
152
+ logger.info("Detached from process")
153
+ return True
154
+ return False
155
+ except Exception as e:
156
+ logger.error(f"Error detaching from process: {e}")
157
+ return False
158
+
159
+ def get_process_info(self, pid: int) -> Dict[str, Any]:
160
+ """Get detailed information about a process"""
161
+ try:
162
+ proc = psutil.Process(pid)
163
+
164
+ return {
165
+ 'pid': pid,
166
+ 'name': proc.name(),
167
+ 'exe': proc.exe() or 'N/A',
168
+ 'cwd': proc.cwd() or 'N/A',
169
+ 'cmdline': proc.cmdline(),
170
+ 'create_time': proc.create_time(),
171
+ 'status': proc.status(),
172
+ 'username': proc.username(),
173
+ 'memory_info': {
174
+ 'rss': proc.memory_info().rss,
175
+ 'vms': proc.memory_info().vms
176
+ },
177
+ 'cpu_percent': proc.cpu_percent(),
178
+ 'num_threads': proc.num_threads(),
179
+ 'architecture': self._get_process_architecture(pid),
180
+ 'platform': platform.system()
181
+ }
182
+ except psutil.NoSuchProcess:
183
+ raise Exception(f"Process {pid} not found")
184
+ except Exception as e:
185
+ raise Exception(f"Failed to get process info: {e}")
@@ -0,0 +1,202 @@
1
+ """
2
+ Process Monitors Module
3
+ Handles process state monitoring and change detection
4
+ """
5
+
6
+ import threading
7
+ import time
8
+ import psutil
9
+ import logging
10
+ from typing import Dict, List, Callable, Optional
11
+ from dataclasses import dataclass
12
+ from datetime import datetime
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ @dataclass
17
+ class ProcessState:
18
+ """Process state snapshot"""
19
+ pid: int
20
+ name: str
21
+ status: str
22
+ memory_usage: int
23
+ cpu_percent: float
24
+ num_threads: int
25
+ timestamp: datetime
26
+
27
+ class ProcessMonitor:
28
+ """Monitors process state changes"""
29
+
30
+ def __init__(self):
31
+ self.monitored_processes: Dict[int, ProcessState] = {}
32
+ self.callbacks: List[Callable] = []
33
+ self.monitoring = False
34
+ self.monitor_thread: Optional[threading.Thread] = None
35
+ self.update_interval = 5.0 # seconds
36
+
37
+ def add_process(self, pid: int):
38
+ """Add a process to monitoring"""
39
+ try:
40
+ proc = psutil.Process(pid)
41
+ state = ProcessState(
42
+ pid=pid,
43
+ name=proc.name(),
44
+ status=proc.status(),
45
+ memory_usage=proc.memory_info().rss,
46
+ cpu_percent=proc.cpu_percent(),
47
+ num_threads=proc.num_threads(),
48
+ timestamp=datetime.now()
49
+ )
50
+ self.monitored_processes[pid] = state
51
+ logger.info(f"Added process {pid} to monitoring")
52
+
53
+ except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
54
+ logger.error(f"Cannot monitor process {pid}: {e}")
55
+ raise
56
+
57
+ def remove_process(self, pid: int):
58
+ """Remove a process from monitoring"""
59
+ if pid in self.monitored_processes:
60
+ del self.monitored_processes[pid]
61
+ logger.info(f"Removed process {pid} from monitoring")
62
+
63
+ def add_callback(self, callback: Callable[[int, str, Dict], None]):
64
+ """Add a callback for process state changes
65
+
66
+ Callback signature: callback(pid, event_type, data)
67
+ Event types: 'terminated', 'memory_change', 'status_change'
68
+ """
69
+ self.callbacks.append(callback)
70
+
71
+ def start_monitoring(self):
72
+ """Start the monitoring thread"""
73
+ if self.monitoring:
74
+ return
75
+
76
+ self.monitoring = True
77
+ self.monitor_thread = threading.Thread(target=self._monitor_loop, daemon=True)
78
+ self.monitor_thread.start()
79
+ logger.info("Process monitoring started")
80
+
81
+ def stop_monitoring(self):
82
+ """Stop the monitoring thread"""
83
+ self.monitoring = False
84
+ if self.monitor_thread:
85
+ self.monitor_thread.join(timeout=2.0)
86
+ logger.info("Process monitoring stopped")
87
+
88
+ def _monitor_loop(self):
89
+ """Main monitoring loop"""
90
+ while self.monitoring:
91
+ try:
92
+ self._check_processes()
93
+ time.sleep(self.update_interval)
94
+ except Exception as e:
95
+ logger.error(f"Error in monitoring loop: {e}")
96
+ time.sleep(1.0)
97
+
98
+ def _check_processes(self):
99
+ """Check all monitored processes for changes"""
100
+ for pid in list(self.monitored_processes.keys()):
101
+ try:
102
+ self._check_single_process(pid)
103
+ except Exception as e:
104
+ logger.error(f"Error checking process {pid}: {e}")
105
+
106
+ def _check_single_process(self, pid: int):
107
+ """Check a single process for changes"""
108
+ old_state = self.monitored_processes[pid]
109
+
110
+ try:
111
+ proc = psutil.Process(pid)
112
+
113
+ # Get current state
114
+ current_state = ProcessState(
115
+ pid=pid,
116
+ name=proc.name(),
117
+ status=proc.status(),
118
+ memory_usage=proc.memory_info().rss,
119
+ cpu_percent=proc.cpu_percent(),
120
+ num_threads=proc.num_threads(),
121
+ timestamp=datetime.now()
122
+ )
123
+
124
+ # Check for changes
125
+ self._detect_changes(old_state, current_state)
126
+
127
+ # Update stored state
128
+ self.monitored_processes[pid] = current_state
129
+
130
+ except psutil.NoSuchProcess:
131
+ # Process terminated
132
+ self._notify_callbacks(pid, 'terminated', {'last_state': old_state})
133
+ self.remove_process(pid)
134
+
135
+ except (psutil.AccessDenied, psutil.ZombieProcess) as e:
136
+ logger.warning(f"Cannot access process {pid}: {e}")
137
+
138
+ def _detect_changes(self, old_state: ProcessState, new_state: ProcessState):
139
+ """Detect and report changes between states"""
140
+
141
+ # Status change
142
+ if old_state.status != new_state.status:
143
+ self._notify_callbacks(
144
+ new_state.pid,
145
+ 'status_change',
146
+ {
147
+ 'old_status': old_state.status,
148
+ 'new_status': new_state.status
149
+ }
150
+ )
151
+
152
+ # Significant memory change (>10MB or >10%)
153
+ memory_diff = abs(new_state.memory_usage - old_state.memory_usage)
154
+ memory_percent_change = memory_diff / old_state.memory_usage if old_state.memory_usage > 0 else 0
155
+
156
+ if memory_diff > 10 * 1024 * 1024 or memory_percent_change > 0.1:
157
+ self._notify_callbacks(
158
+ new_state.pid,
159
+ 'memory_change',
160
+ {
161
+ 'old_memory': old_state.memory_usage,
162
+ 'new_memory': new_state.memory_usage,
163
+ 'change': memory_diff,
164
+ 'percent_change': memory_percent_change
165
+ }
166
+ )
167
+
168
+ # Thread count change
169
+ if old_state.num_threads != new_state.num_threads:
170
+ self._notify_callbacks(
171
+ new_state.pid,
172
+ 'thread_change',
173
+ {
174
+ 'old_threads': old_state.num_threads,
175
+ 'new_threads': new_state.num_threads
176
+ }
177
+ )
178
+
179
+ def _notify_callbacks(self, pid: int, event_type: str, data: Dict):
180
+ """Notify all callbacks of an event"""
181
+ for callback in self.callbacks:
182
+ try:
183
+ callback(pid, event_type, data)
184
+ except Exception as e:
185
+ logger.error(f"Error in process monitor callback: {e}")
186
+
187
+ def get_process_state(self, pid: int) -> Optional[ProcessState]:
188
+ """Get current state of a monitored process"""
189
+ return self.monitored_processes.get(pid)
190
+
191
+ def get_all_states(self) -> Dict[int, ProcessState]:
192
+ """Get all current process states"""
193
+ return self.monitored_processes.copy()
194
+
195
+ def set_update_interval(self, seconds: float):
196
+ """Set the monitoring update interval"""
197
+ if seconds > 0:
198
+ self.update_interval = seconds
199
+
200
+ def __del__(self):
201
+ """Cleanup on destruction"""
202
+ self.stop_monitoring()
@@ -0,0 +1,131 @@
1
+ """
2
+ Process Permissions Module
3
+ Handles security and permission validation
4
+ """
5
+
6
+ import ctypes
7
+ import ctypes.wintypes
8
+ import os
9
+ import logging
10
+ from typing import Set, List
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ class PermissionChecker:
15
+ """Handles permission and security checks"""
16
+
17
+ def __init__(self):
18
+ self.kernel32 = ctypes.windll.kernel32
19
+ self.advapi32 = ctypes.windll.advapi32
20
+
21
+ def has_debug_privileges(self) -> bool:
22
+ """Check if current process has debug privileges"""
23
+ try:
24
+ # Get current process token
25
+ token = ctypes.wintypes.HANDLE()
26
+ if not self.advapi32.OpenProcessToken(
27
+ self.kernel32.GetCurrentProcess(),
28
+ 0x0020, # TOKEN_ADJUST_PRIVILEGES
29
+ ctypes.byref(token)
30
+ ):
31
+ return False
32
+
33
+ try:
34
+ # Check for SeDebugPrivilege
35
+ privilege_name = "SeDebugPrivilege"
36
+ luid = ctypes.wintypes.LUID()
37
+
38
+ if not self.advapi32.LookupPrivilegeValueW(
39
+ None,
40
+ privilege_name,
41
+ ctypes.byref(luid)
42
+ ):
43
+ return False
44
+
45
+ # Check if privilege is enabled
46
+ privilege_set = ctypes.create_string_buffer(16) # PRIVILEGE_SET structure
47
+ privilege_length = ctypes.wintypes.DWORD(16)
48
+ result = ctypes.wintypes.BOOL()
49
+
50
+ if self.advapi32.PrivilegeCheck(
51
+ token,
52
+ privilege_set,
53
+ ctypes.byref(result)
54
+ ):
55
+ return bool(result.value)
56
+
57
+ return False
58
+
59
+ finally:
60
+ self.kernel32.CloseHandle(token)
61
+
62
+ except Exception as e:
63
+ logger.warning(f"Failed to check debug privileges: {e}")
64
+ return False
65
+
66
+ def is_elevated(self) -> bool:
67
+ """Check if current process is running with elevated privileges"""
68
+ try:
69
+ return ctypes.windll.shell32.IsUserAnAdmin()
70
+ except Exception:
71
+ return False
72
+
73
+ def can_access_process(self, pid: int, access_level: str = "read") -> tuple[bool, str]:
74
+ """Check if we can access a specific process with given access level"""
75
+ try:
76
+ if access_level == "read":
77
+ access_rights = 0x0400 | 0x0010 # PROCESS_QUERY_INFORMATION | PROCESS_VM_READ
78
+ elif access_level == "debug":
79
+ access_rights = 0x1F0FFF # PROCESS_ALL_ACCESS
80
+ else:
81
+ return False, f"Invalid access level: {access_level}"
82
+
83
+ handle = self.kernel32.OpenProcess(access_rights, False, pid)
84
+ if handle:
85
+ self.kernel32.CloseHandle(handle)
86
+ return True, "Access granted"
87
+ else:
88
+ error_code = ctypes.get_last_error()
89
+ return False, f"Access denied (Error {error_code})"
90
+
91
+ except Exception as e:
92
+ return False, f"Exception checking access: {e}"
93
+
94
+ def get_security_recommendations(self) -> List[str]:
95
+ """Get security recommendations for current environment"""
96
+ recommendations = []
97
+
98
+ if not self.is_elevated():
99
+ recommendations.append("Consider running as administrator for full functionality")
100
+
101
+ if not self.has_debug_privileges():
102
+ recommendations.append("Debug privileges not available - some features may be limited")
103
+
104
+ return recommendations
105
+
106
+ def validate_address(self, address: int) -> bool:
107
+ """Validate that an address is within reasonable bounds"""
108
+ # Basic sanity checks for memory addresses
109
+ if address < 0:
110
+ return False
111
+
112
+ # Check for obviously invalid addresses
113
+ if address < 0x1000: # Null page
114
+ return False
115
+
116
+ # Check for addresses that are too high (basic check)
117
+ if address > 0x7FFFFFFFFFFF: # Max user-mode address on x64
118
+ return False
119
+
120
+ return True
121
+
122
+ def validate_size(self, size: int) -> bool:
123
+ """Validate that a size parameter is reasonable"""
124
+ if size <= 0:
125
+ return False
126
+
127
+ # Limit maximum read size to prevent abuse
128
+ if size > 1024 * 1024 * 100: # 100MB max
129
+ return False
130
+
131
+ return True
@@ -0,0 +1,119 @@
1
+ {
2
+ "enabled": true,
3
+ "description": "Process whitelist for MCP Cheat Engine Server",
4
+ "last_updated": "2025-07-31T01:58:10.838750",
5
+ "entries": [
6
+ {
7
+ "process_name": "notepad.exe",
8
+ "description": "Windows Notepad",
9
+ "category": "system",
10
+ "added_date": "2025-07-31T01:58:10.497479",
11
+ "enabled": true,
12
+ "exact_match": true
13
+ },
14
+ {
15
+ "process_name": "code.exe",
16
+ "description": "Visual Studio Code",
17
+ "category": "development",
18
+ "added_date": "2025-07-31T01:58:10.497487",
19
+ "enabled": true,
20
+ "exact_match": true
21
+ },
22
+ {
23
+ "process_name": "devenv.exe",
24
+ "description": "Visual Studio",
25
+ "category": "development",
26
+ "added_date": "2025-07-31T01:58:10.497490",
27
+ "enabled": true,
28
+ "exact_match": true
29
+ },
30
+ {
31
+ "process_name": "windbg.exe",
32
+ "description": "Windows Debugger",
33
+ "category": "development",
34
+ "added_date": "2025-07-31T01:58:10.497495",
35
+ "enabled": true,
36
+ "exact_match": true
37
+ },
38
+ {
39
+ "process_name": "x64dbg.exe",
40
+ "description": "x64dbg Debugger",
41
+ "category": "development",
42
+ "added_date": "2025-07-31T01:58:10.497497",
43
+ "enabled": true,
44
+ "exact_match": true
45
+ },
46
+ {
47
+ "process_name": "ollydbg.exe",
48
+ "description": "OllyDbg Debugger",
49
+ "category": "development",
50
+ "added_date": "2025-07-31T01:58:10.497498",
51
+ "enabled": true,
52
+ "exact_match": true
53
+ },
54
+ {
55
+ "process_name": "calc.exe",
56
+ "description": "Windows Calculator",
57
+ "category": "system",
58
+ "added_date": "2025-07-31T01:58:10.497500",
59
+ "enabled": true,
60
+ "exact_match": true
61
+ },
62
+ {
63
+ "process_name": "mspaint.exe",
64
+ "description": "Microsoft Paint",
65
+ "category": "system",
66
+ "added_date": "2025-07-31T01:58:10.497501",
67
+ "enabled": true,
68
+ "exact_match": true
69
+ },
70
+ {
71
+ "process_name": "wordpad.exe",
72
+ "description": "Windows WordPad",
73
+ "category": "system",
74
+ "added_date": "2025-07-31T01:58:10.497503",
75
+ "enabled": true,
76
+ "exact_match": true
77
+ },
78
+ {
79
+ "process_name": "minesweeper.exe",
80
+ "description": "Minesweeper",
81
+ "category": "game",
82
+ "added_date": "2025-07-31T01:58:10.497504",
83
+ "enabled": true,
84
+ "exact_match": true
85
+ },
86
+ {
87
+ "process_name": "solitaire.exe",
88
+ "description": "Solitaire",
89
+ "category": "game",
90
+ "added_date": "2025-07-31T01:58:10.497505",
91
+ "enabled": true,
92
+ "exact_match": true
93
+ },
94
+ {
95
+ "process_name": "test*.exe",
96
+ "description": "Test Applications",
97
+ "category": "test",
98
+ "added_date": "2025-07-31T01:58:10.497507",
99
+ "enabled": true,
100
+ "exact_match": false
101
+ },
102
+ {
103
+ "process_name": "demo*.exe",
104
+ "description": "Demo Applications",
105
+ "category": "test",
106
+ "added_date": "2025-07-31T01:58:10.497509",
107
+ "enabled": true,
108
+ "exact_match": false
109
+ },
110
+ {
111
+ "process_name": "dbengine-x86_64.exe",
112
+ "description": "Database Engine x64",
113
+ "category": "development",
114
+ "added_date": "2025-07-31T05:02:00.000000",
115
+ "enabled": true,
116
+ "exact_match": true
117
+ }
118
+ ]
119
+ }
File without changes
@@ -0,0 +1,37 @@
1
+ """
2
+ Utility Functions Module
3
+ Provides validation, formatting, and data type utilities
4
+ """
5
+
6
+ from .validators import (
7
+ validate_address, validate_size, validate_pattern,
8
+ validate_process_identifier, validate_data_type,
9
+ sanitize_filename, validate_region_list
10
+ )
11
+ from .formatters import (
12
+ format_memory_data, format_raw_bytes, format_process_info,
13
+ format_size, format_timestamp, format_hex_dump, format_scan_results
14
+ )
15
+ from .data_types import (
16
+ DataType, Architecture, MemoryProtection,
17
+ ProcessSnapshot, MemoryBlock, ScanResult, PointerChain,
18
+ DataTypeConverter, PatternMatcher, AddressCalculator,
19
+ AnalysisContext, SimpleCache
20
+ )
21
+
22
+ __all__ = [
23
+ # Validators
24
+ 'validate_address', 'validate_size', 'validate_pattern',
25
+ 'validate_process_identifier', 'validate_data_type',
26
+ 'sanitize_filename', 'validate_region_list',
27
+
28
+ # Formatters
29
+ 'format_memory_data', 'format_raw_bytes', 'format_process_info',
30
+ 'format_size', 'format_timestamp', 'format_hex_dump', 'format_scan_results',
31
+
32
+ # Data Types
33
+ 'DataType', 'Architecture', 'MemoryProtection',
34
+ 'ProcessSnapshot', 'MemoryBlock', 'ScanResult', 'PointerChain',
35
+ 'DataTypeConverter', 'PatternMatcher', 'AddressCalculator',
36
+ 'AnalysisContext', 'SimpleCache'
37
+ ]