From f804a5b7f0eff8cbdf81e49bf3a4a6eadf50e459 Mon Sep 17 00:00:00 2001 From: 87owo <85057800+87owo@users.noreply.github.com> Date: Tue, 16 Jun 2026 04:20:08 +0800 Subject: [PATCH] Add files via upload --- Interface/static/js/i18n.js | 66 ++++++++++++++++++++++----- Interface/static/js/main.js | 8 ++-- Interface/templates/index.html | 12 +++++ PYAS.py | 83 ++++++++++++++++++++++++++-------- 4 files changed, 135 insertions(+), 34 deletions(-) diff --git a/Interface/static/js/i18n.js b/Interface/static/js/i18n.js index 6a36052..a869413 100644 --- a/Interface/static/js/i18n.js +++ b/Interface/static/js/i18n.js @@ -179,7 +179,11 @@ window.AppI18n = { "Network Block": "網路攔截", "Driver Block": "驅動攔截", "System Restart": "系統重啟", - "Clean Junk": "清理垃圾" + "Clean Junk": "清理垃圾", + "protect_suspend": "進程暫停", + "protect_suspend_desc": "此選項可以暫停進程等待掃描", + "opt_autostart": "開機啟動", + "opt_autostart_desc": "此選項可以設定開機自動執行", }, "simplified_switch": { "app_name": "PYAS Security", @@ -360,7 +364,11 @@ window.AppI18n = { "Network Block": "网络拦截", "Driver Block": "驱动拦截", "System Restart": "系统重启", - "Clean Junk": "清理垃圾" + "Clean Junk": "清理垃圾", + "protect_suspend": "进程暂停", + "protect_suspend_desc": "此选项可以暂停进程等待扫描", + "opt_autostart": "开机启动", + "opt_autostart_desc": "此选项可以设定开机自动运行", }, "english_switch": { "app_name": "PYAS Security", @@ -541,7 +549,11 @@ window.AppI18n = { "Network Block": "Network Block", "Driver Block": "Driver Block", "System Restart": "System Restart", - "Clean Junk": "Clean Junk" + "Clean Junk": "Clean Junk", + "protect_suspend": "Process Suspend", + "protect_suspend_desc": "Suspend processes while waiting for scanning", + "opt_autostart": "Auto Start", + "opt_autostart_desc": "Run automatically at system startup", }, "japanese_switch": { "app_name": "PYAS Security", @@ -722,7 +734,11 @@ window.AppI18n = { "Network Block": "ネットワークブロック", "Driver Block": "ドライバーブロック", "System Restart": "システムの再起動", - "Clean Junk": "ジャンククリーンアップ" + "Clean Junk": "ジャンククリーンアップ", + "protect_suspend": "プロセスの一時停止", + "protect_suspend_desc": "スキャン待ちの間プロセスを一時停止します", + "opt_autostart": "自動起動", + "opt_autostart_desc": "システム起動時に自動的に実行します", }, "korean_switch": { "app_name": "PYAS Security", @@ -903,7 +919,11 @@ window.AppI18n = { "Network Block": "네트워크 차단", "Driver Block": "드라이버 차단", "System Restart": "시스템 재시작", - "Clean Junk": "정크 정리" + "Clean Junk": "정크 정리", + "protect_suspend": "프로세스 일시 중지", + "protect_suspend_desc": "스캔을 기다리는 동안 프로세스를 일시 중지합니다", + "opt_autostart": "자동 시작", + "opt_autostart_desc": "시스템 시작 시 자동으로 실행합니다", }, "french_switch": { "app_name": "PYAS Security", @@ -1084,7 +1104,11 @@ window.AppI18n = { "Network Block": "Réseau bloqué", "Driver Block": "Pilote bloqué", "System Restart": "Redémarrage système", - "Clean Junk": "Nettoyage" + "Clean Junk": "Nettoyage", + "protect_suspend": "Suspendre processus", + "protect_suspend_desc": "Suspend les processus en attente d'analyse", + "opt_autostart": "Démarrage auto", + "opt_autostart_desc": "Exécuter automatiquement au démarrage", }, "spanish_switch": { "app_name": "PYAS Security", @@ -1265,7 +1289,11 @@ window.AppI18n = { "Network Block": "Red bloqueada", "Driver Block": "Controlador bloqueado", "System Restart": "Reinicio del sistema", - "Clean Junk": "Limpieza de basura" + "Clean Junk": "Limpieza de basura", + "protect_suspend": "Suspender procesos", + "protect_suspend_desc": "Suspender procesos mientras espera el escaneo", + "opt_autostart": "Inicio automático", + "opt_autostart_desc": "Ejecutar automáticamente al inicio", }, "hindi_switch": { "app_name": "PYAS Security", @@ -1446,7 +1474,11 @@ window.AppI18n = { "Network Block": "नेटवर्क अवरुद्ध", "Driver Block": "ड्राइवर अवरुद्ध", "System Restart": "सिस्टम पुनरारंभ", - "Clean Junk": "कचरा साफ़ करें" + "Clean Junk": "कचरा साफ़ करें", + "protect_suspend": "प्रक्रिया रोकें", + "protect_suspend_desc": "स्कैन की प्रतीक्षा करते समय प्रक्रियाओं को रोकें", + "opt_autostart": "स्वतः प्रारंभ", + "opt_autostart_desc": "सिस्टम स्टार्टअप पर स्वचालित रूप से चलाएं", }, "arabic_switch": { "app_name": "PYAS Security", @@ -1627,7 +1659,11 @@ window.AppI18n = { "Network Block": "حظر شبكة", "Driver Block": "حظر محرك", "System Restart": "إعادة تشغيل النظام", - "Clean Junk": "تنظيف المخلفات" + "Clean Junk": "تنظيف المخلفات", + "protect_suspend": "تعليق العمليات", + "protect_suspend_desc": "تعليق العمليات أثناء انتظار الفحص", + "opt_autostart": "بدء تلقائي", + "opt_autostart_desc": "التشغيل تلقائيًا عند بدء التشغيل", }, "russian_switch": { "app_name": "PYAS Security", @@ -1808,7 +1844,11 @@ window.AppI18n = { "Network Block": "Блокировка сети", "Driver Block": "Блокировка драйвера", "System Restart": "Перезапуск системы", - "Clean Junk": "Очистка мусора" + "Clean Junk": "Очистка мусора", + "protect_suspend": "Приостановка процессов", + "protect_suspend_desc": "Приостановка процессов в ожидании сканирования", + "opt_autostart": "Автозапуск", + "opt_autostart_desc": "Автоматический запуск при старте системы", }, "slovenian_switch": { "app_name": "PYAS Security", @@ -1989,7 +2029,11 @@ window.AppI18n = { "Network Block": "Omrežje blokirano", "Driver Block": "Gonilnik blokiran", "System Restart": "Ponovni zagon sistema", - "Clean Junk": "Čiščenje nesnage" + "Clean Junk": "Čiščenje nesnage", + "protect_suspend": "Začasna ustavitev", + "protect_suspend_desc": "Zaustavite procese med čakanjem na skeniranje", + "opt_autostart": "Samodejni zagon", + "opt_autostart_desc": "Samodejni zagon ob zagonu sistema", } }, langMap: { diff --git a/Interface/static/js/main.js b/Interface/static/js/main.js index 38dda85..dcd8f74 100644 --- a/Interface/static/js/main.js +++ b/Interface/static/js/main.js @@ -781,7 +781,7 @@ document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.toggle-switch input').forEach((toggle, index) => { toggle.addEventListener('change', async (e) => { - const switchMap = ["process_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "context_switch"]; + const switchMap = ["process_switch", "suspend_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "autostart_switch", "context_switch"]; const key = switchMap[index]; if (window.pywebview && key) { toggle.disabled = true; @@ -1082,7 +1082,7 @@ document.addEventListener('DOMContentLoaded', () => { updateCustomSelectUI('theme_select', theme); updateCustomSelectUI('lang_select', lang); - const switchMap = ["process_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "context_switch"]; + const switchMap = ["process_switch", "suspend_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "autostart_switch", "context_switch"]; document.querySelectorAll('.toggle-switch input').forEach((toggle, index) => { if (appState.firstLaunch) { toggle.checked = false; @@ -1102,8 +1102,8 @@ document.addEventListener('DOMContentLoaded', () => { window.onEngineReady = async () => { if (!appState.firstLaunch) return; await window.pywebview.api.update_config("first_launch", false); - const switchMap = ["process_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "context_switch"]; - const seq = ["cloud_switch", "process_switch", "document_switch", "system_switch", "network_switch", "driver_switch"]; + const switchMap = ["process_switch", "suspend_switch", "document_switch", "system_switch", "driver_switch", "network_switch", "sensitive_switch", "extension_switch", "cloud_switch", "autostart_switch", "context_switch"]; + const seq = ["cloud_switch", "autostart_switch", "process_switch", "suspend_switch", "document_switch", "system_switch", "network_switch", "driver_switch"]; for (const key of seq) { const index = switchMap.indexOf(key); diff --git a/Interface/templates/index.html b/Interface/templates/index.html index d3a9504..11ce531 100644 --- a/Interface/templates/index.html +++ b/Interface/templates/index.html @@ -109,6 +109,12 @@ +
+
+

進程暫停

此選項可以暫停進程等待掃描

+
+ +

檔案防護

此選項可以隔離惡意檔案建立

@@ -215,6 +221,12 @@
+
+
+

開機啟動

此選項可以設定開機自動執行

+
+ +

選單掃描

此選項可以啟用右鍵掃描功能

diff --git a/PYAS.py b/PYAS.py index cabe4bc..75624cc 100644 --- a/PYAS.py +++ b/PYAS.py @@ -331,6 +331,7 @@ class WindowAPI: "theme": "system_switch", "first_launch": True, "process_switch": False, + "suspend_switch": True, "document_switch": False, "system_switch": False, "driver_switch": False, @@ -338,6 +339,7 @@ class WindowAPI: "extension_switch": False, "sensitive_switch": False, "cloud_switch": False, + "autostart_switch": True, "context_switch": False, "custom_rule": [], "white_list": [], @@ -483,9 +485,10 @@ class WindowAPI: self.start_daemon_thread(self.pipe_server_thread) else: success = False - elif key == "context_switch": self.register_context_menu(True) + elif key == "autostart_switch": + self.manage_autostart(True) except Exception as e: self.write_log("WARN", "Feature Start", detail=str(e), success=False) @@ -503,6 +506,17 @@ class WindowAPI: except Exception: pass self.h_dir_file = None + elif key == "autostart_switch": + self.manage_autostart(False) + elif key == "suspend_switch": + with self.lock_proc: + if hasattr(self, 'suspended_procs'): + for h in list(self.suspended_procs): + try: + self.ntdll.NtResumeProcess(h) + except Exception: + pass + self.suspended_procs.clear() if success: with self.lock_config: @@ -633,6 +647,20 @@ class WindowAPI: pass return False + def manage_autostart(self, enable): + try: + task_name = "PYAS_Security_ATS" + if enable: + cmd = f"$Action = New-ScheduledTaskAction -Execute '{self.file_pyas}' -Argument '-hide'; $Trigger = New-ScheduledTaskTrigger -AtLogOn; $Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries; Register-ScheduledTask -TaskName '{task_name}' -Action $Action -Trigger $Trigger -Settings $Settings -RunLevel Highest -Force" + subprocess.run(["powershell", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-Command", cmd], creationflags=0x08000000) + else: + subprocess.run(["schtasks", "/Delete", "/TN", task_name, "/F"], creationflags=0x08000000) + + return True + except Exception as e: + self.write_log("WARN", "manage_autostart", detail=str(e), success=False) + return False + def manage_named_list(self, list_key, files, action="add", lock_func=None): if list_key == "quarantine" and lock_func is None: lock_func = self.lock_file @@ -2689,32 +2717,42 @@ class WindowAPI: for pid in new_pids: h = self.kernel32.OpenProcess(0x1F0FFF, False, pid) if h: - self.ntdll.NtSuspendProcess(h) - with self.lock_proc: - self.suspended_procs.add(h) + with self.lock_config: + should_suspend = self.pyas_config.get("suspend_switch", True) + + if should_suspend: + self.ntdll.NtSuspendProcess(h) + with self.lock_proc: + self.suspended_procs.add(h) try: - self.proc_pool.submit(self.handle_new_process, pid, h) + self.proc_pool.submit(self.handle_new_process, pid, h, should_suspend) except Exception: - self.ntdll.NtResumeProcess(h) - with self.lock_proc: - self.suspended_procs.discard(h) - self.kernel32.CloseHandle(h) + if should_suspend: + self.ntdll.NtResumeProcess(h) + with self.lock_proc: + self.suspended_procs.discard(h) + self.kernel32.CloseHandle(h) except Exception as e: self.write_log("WARN", "protect_proc_thread", detail=str(e), success=False) - def handle_new_process(self, pid, h=None): + def handle_new_process(self, pid, h=None, suspended=None): + if suspended is None: + with self.lock_config: + suspended = self.pyas_config.get("suspend_switch", True) + if not h: h = self.kernel32.OpenProcess(0x1F0FFF, False, pid) if not h: return - self.ntdll.NtSuspendProcess(h) - with self.lock_proc: - if not hasattr(self, 'suspended_procs'): - self.suspended_procs = set() - self.suspended_procs.add(h) + if suspended: + self.ntdll.NtSuspendProcess(h) + with self.lock_proc: + if not hasattr(self, 'suspended_procs'): + self.suspended_procs = set() + self.suspended_procs.add(h) try: cmdline = self.get_process_cmdline(h) process_file = self.get_process_file(h) @@ -2764,10 +2802,17 @@ class WindowAPI: self.write_log("BLOCK", "Process DLL Block", pid=pid, source=hidden_virus_path, file_hash=self.calc_file_hash(hidden_virus_path)) finally: - self.ntdll.NtResumeProcess(h) - with self.lock_proc: - self.suspended_procs.discard(h) - self.kernel32.CloseHandle(h) + if suspended: + try: + self.ntdll.NtResumeProcess(h) + except Exception: + pass + with self.lock_proc: + self.suspended_procs.discard(h) + try: + self.kernel32.CloseHandle(h) + except Exception: + pass def scan_process_memory(self, pid, h_process): scanned_paths = set()