diff --git a/Interface/static/js/main.js b/Interface/static/js/main.js index 3719784..2548e3f 100644 --- a/Interface/static/js/main.js +++ b/Interface/static/js/main.js @@ -85,6 +85,7 @@ document.addEventListener('DOMContentLoaded', () => { startup: [{key: 'type', label: 'col_type', flex: 0.5, isI18n: true}, {key: 'name', label: 'col_name', flex: 1.5}, {key: 'status', label: 'col_status', flex: 0.5, isI18n: true}, {key: 'path', label: 'col_path', flex: 3}], virus: [{key: 'label', label: 'col_type', flex: 1, isI18n: true}, {key: 'path', label: 'col_path', flex: 3}], pathOnly: [{key: 'path', label: 'col_path', flex: 1}], + fileList: [{key: 'time_str', label: 'col_date', flex: 1.5}, {key: 'path', label: 'col_path', flex: 5}], junk: [{key: 'path', label: 'col_path', flex: 3}, {key: 'sizeStr', label: 'col_size', flex: 1}], popup: [{key: 'exe', label: 'col_prog', flex: 1}, {key: 'class', label: 'col_class', flex: 1}, {key: 'title', label: 'col_title', flex: 2}], repair: [{key: 'display', label: 'col_repair', flex: 1, isI18n: true}, {key: 'path', label: 'col_path', flex: 3}], @@ -594,9 +595,19 @@ document.addEventListener('DOMContentLoaded', () => { const refreshConfigLists = () => { if (!window.pywebview) return; window.pywebview.api.get_config().then(cfg => { - renderDataGrid('#whitelist_window', (cfg.white_list || []).map(i => ({path: i.file || i})), cols.pathOnly, 'path'); - renderDataGrid('#quarantine_window', (cfg.quarantine || []).map(i => ({path: i.file || i})), cols.pathOnly, 'path'); - renderDataGrid('#custom_protect_window', (cfg.custom_rule || []).map(i => ({path: i.file || i})), cols.pathOnly, 'path'); + const formatTime = (ts) => { + if (!ts) return '-'; + const d = new Date(ts * 1000); + const pad = n => n.toString().padStart(2, '0'); + return `[${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}]`; + }; + const mapList = (arr) => (arr || []).map(i => ({ + path: i.file || (typeof i === 'string' ? i : ''), + time_str: formatTime(i.time) + })); + renderDataGrid('#whitelist_window', mapList(cfg.white_list), cols.fileList, 'path'); + renderDataGrid('#quarantine_window', mapList(cfg.quarantine), cols.fileList, 'path'); + renderDataGrid('#custom_protect_window', mapList(cfg.custom_rule), cols.fileList, 'path'); const popupRules = (cfg.block_list || []).map(item => ({ exe: item.exe || '*', class: item.class || '*', title: item.title || '*', value: item.exe || item.title })); renderDataGrid('#popup_window', popupRules, cols.popup, 'value'); }); @@ -1054,9 +1065,9 @@ document.addEventListener('DOMContentLoaded', () => { renderDataGrid('#startup_window', [], cols.startup, 'id', false); renderDataGrid('#junk_window', [], cols.junk, 'path', true); renderDataGrid('#repair_window', [], cols.repair, 'id', true); - renderDataGrid('#whitelist_window', [], cols.pathOnly, 'path', false); - renderDataGrid('#quarantine_window', [], cols.pathOnly, 'path', false); - renderDataGrid('#custom_protect_window', [], cols.pathOnly, 'path', false); + renderDataGrid('#whitelist_window', [], cols.fileList, 'path', false); + renderDataGrid('#quarantine_window', [], cols.fileList, 'path', false); + renderDataGrid('#custom_protect_window', [], cols.fileList, 'path', false); renderDataGrid('#popup_window', [], cols.popup, 'value', false); renderDataGrid('#log_export_window', [], cols.log, 'id', true); renderDataGrid('#netmon_window', [], cols.netmon, 'pid', false); diff --git a/Interface/templates/index.html b/Interface/templates/index.html index 6ae55da..d3a9504 100644 --- a/Interface/templates/index.html +++ b/Interface/templates/index.html @@ -284,34 +284,64 @@
diff --git a/PYAS.py b/PYAS.py index 48fafde..0404810 100644 --- a/PYAS.py +++ b/PYAS.py @@ -355,7 +355,7 @@ class WindowAPI: self.lock_io = threading.RLock() self.pyas_default = { - "version": "3.5.9", + "version": "3.6.0", "api_host": "https://pyas-security.com/", "api_key": "fBRZxYS1UxykM-qzNOlKOEl63WILzlvgNMn6QfsG6FXCAAIktCrOPTAfY5_hEyuZ", "suffix": [".exe", ".dll", ".sys", ".ocx", ".scr", ".efi", ".acm", ".ax", ".cpl", ".drv", ".com", ".mui", ".pyd", ".wfx", ".api", ".awx", ".rll", ".winmd", ".ax"], @@ -680,25 +680,24 @@ class WindowAPI: acted_items = [] with self.lock_config: target_list = self.pyas_config.setdefault(list_key, []) - if action == "add": for path in norm_paths: path_case = os.path.normcase(path) exists = False for item in target_list: - if isinstance(item, dict): - val = item.get("file", "") - np = self.norm_path(val, must_exist=False) - if np and os.path.normcase(np) == path_case: - exists = True - break + val = item.get("file", "") if isinstance(item, dict) else item + np = self.norm_path(val, must_exist=False) + + if np and os.path.normcase(np) == path_case: + exists = True + break if not exists: if lock_func: lock_func(path, True) - target_list.append({"file": path}) + target_list.append({"file": path, "time": time.time()}) acted_items.append(path) if list_key == "white_list": self.sync_driver_whitelist(path, True) @@ -706,7 +705,6 @@ class WindowAPI: elif action == "remove": norm_paths_case = {os.path.normcase(p) for p in norm_paths} new_list = [] - for item in target_list: val = item.get("file", "") if isinstance(item, dict) else item if val: @@ -1094,18 +1092,43 @@ class WindowAPI: return [] def open_file_location(self, file_path): - if file_path: - expanded_path = os.path.expandvars(file_path).strip('"').strip("'") + if not file_path: + return False - if os.path.exists(expanded_path): - try: - clean_path = os.path.normpath(expanded_path) - subprocess.Popen(f'explorer /select,"{clean_path}"') + expanded_path = os.path.expandvars(file_path).strip('"').strip("'") + reg_prefixes = ("HKLM", "HKCU", "HKCR", "HKU", "HKCC", "HKEY_") - return True - except Exception: - pass + if expanded_path.upper().startswith(reg_prefixes): + try: + full_path = expanded_path + if full_path.startswith("HKLM"): + full_path = full_path.replace("HKLM", "HKEY_LOCAL_MACHINE", 1) + elif full_path.startswith("HKCU"): + full_path = full_path.replace("HKCU", "HKEY_CURRENT_USER", 1) + elif full_path.startswith("HKCR"): + full_path = full_path.replace("HKCR", "HKEY_CLASSES_ROOT", 1) + elif full_path.startswith("HKU"): + full_path = full_path.replace("HKU", "HKEY_USERS", 1) + elif full_path.startswith("HKCC"): + full_path = full_path.replace("HKCC", "HKEY_CURRENT_CONFIG", 1) + subprocess.run(["taskkill", "/F", "/IM", "regedit.exe"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, creationflags=0x08000000) + self._reg_write(winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Applets\Regedit", "LastKey", winreg.REG_SZ, full_path) + subprocess.Popen("regedit.exe") + + return True + except Exception: + pass + return False + + if os.path.exists(expanded_path): + try: + clean_path = os.path.normpath(expanded_path) + subprocess.Popen(f'explorer /select,"{clean_path}"') + return True + + except Exception: + pass return False def open_website(self): diff --git a/PYAS_Version.py b/PYAS_Version.py index c2fecbc..90b68e9 100644 --- a/PYAS_Version.py +++ b/PYAS_Version.py @@ -2,7 +2,7 @@ import pyinstaller_versionfile pyinstaller_versionfile.create_versionfile( output_file="versionfile.txt", -version='3.5.9.0', +version='3.6.0.0', company_name="PYAS Security", file_description="PYAS Security Antivirus", internal_name="PYAS",