Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
630dc67058 | ||
|
|
591507512c | ||
|
|
ff49cafc74 | ||
|
|
b077ba06bd | ||
|
|
a2b66aec64 | ||
|
|
4b692b0c87 | ||
|
|
99d1b20d0f | ||
|
|
fae5edb57b | ||
|
|
6db91483a0 | ||
|
|
90383f3d09 | ||
|
|
966a5a3592 | ||
|
|
48e14cd143 | ||
|
|
4264f50ba3 | ||
|
|
887e0718d0 | ||
|
|
4870a5c480 | ||
|
|
e8cadf0537 | ||
|
|
f5124e0ef2 | ||
|
|
da9a520632 | ||
|
|
81bebeda63 | ||
|
|
4df1432be1 | ||
|
|
e699be6b2e | ||
|
|
e8dda40e7f | ||
|
|
5b4cd6e879 | ||
|
|
316b061d34 | ||
|
|
6ff27679e7 | ||
|
|
8f3adbc870 |
No files matched your search
+1101
-876
File diff suppressed because it is too large.
Load diff
+1156
-942
File diff suppressed because it is too large.
Load diff
@@ -1,4 +1,4 @@
|
||||
* {
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -14,6 +14,7 @@
|
||||
--bg-hover: rgba(0, 0, 0, 0.05);
|
||||
--text-primary: rgb(29, 29, 31);
|
||||
--text-secondary: rgb(134, 134, 139);
|
||||
--text-on-accent: rgb(255, 255, 255);
|
||||
--border-color: rgb(210, 210, 215);
|
||||
--accent-color: rgb(0, 122, 255);
|
||||
--accent-alpha: rgba(0, 122, 255, 0.1);
|
||||
@@ -82,7 +83,7 @@ body {
|
||||
}
|
||||
|
||||
.ctrl-btn:hover { background-color: var(--bg-hover); color: var(--text-primary); }
|
||||
#close_button:hover { background-color: #ff3b30; color: white; }
|
||||
#close_button:hover { background-color: #ff3b30; color: var(--text-on-accent); }
|
||||
|
||||
.theme-svg {
|
||||
width: 16px;
|
||||
@@ -258,7 +259,7 @@ body {
|
||||
|
||||
.primary-btn {
|
||||
background-color: var(--accent-color);
|
||||
color: white;
|
||||
color: var(--text-on-accent);
|
||||
border: none;
|
||||
box-shadow: 0 2px 4px var(--accent-shadow);
|
||||
}
|
||||
|
||||
+29
-19
@@ -1,4 +1,4 @@
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
document.addEventListener(eventName, e => {
|
||||
e.preventDefault();
|
||||
});
|
||||
@@ -88,9 +88,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
setTimeout(() => {
|
||||
if (!startupOverlayClosed) {
|
||||
closeStartupOverlay();
|
||||
showStartupError("PYAS WebView2 initialization is taking too long. The application will retry automatically.");
|
||||
}
|
||||
}, 12000);
|
||||
}, 20000);
|
||||
|
||||
const formatMsg = (key, ...args) => {
|
||||
let msg = getMsg(key);
|
||||
@@ -104,12 +104,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
};
|
||||
|
||||
const themes = {
|
||||
"white_switch": { "--bg-window": "245, 245, 247", "--bg-nav": "255, 255, 255", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(0,0,0,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--border-color":"210, 210, 215", "--accent-color":"0, 122, 255", "--accent-alpha":"rgba(0, 122, 255, 0.1)", "--accent-shadow":"rgba(0, 122, 255, 0.2)", "--accent-hover":"rgba(0, 122, 255, 0.3)" },
|
||||
"black_switch": { "--bg-window": "0, 0, 0", "--bg-nav": "28, 28, 30", "--bg-panel": "28, 28, 30", "--bg-hover": "rgba(255,255,255,0.1)", "--text-primary": "245, 245, 247", "--text-secondary": "134, 134, 139", "--border-color":"44, 44, 46", "--accent-color":"10, 132, 255", "--accent-alpha":"rgba(10, 132, 255, 0.1)", "--accent-shadow":"rgba(10, 132, 255, 0.2)", "--accent-hover":"rgba(10, 132, 255, 0.3)" },
|
||||
"red_switch": { "--bg-window": "253, 246, 246", "--bg-nav": "255, 240, 240", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(255,59,48,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--border-color":"250, 220, 220", "--accent-color":"255, 59, 48", "--accent-alpha":"rgba(255, 59, 48, 0.1)", "--accent-shadow":"rgba(255, 59, 48, 0.2)", "--accent-hover":"rgba(255, 59, 48, 0.3)" },
|
||||
"yellow_switch": { "--bg-window": "254, 251, 243", "--bg-nav": "255, 248, 230", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(255,149,0,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--border-color":"250, 240, 215", "--accent-color":"255, 149, 0", "--accent-alpha":"rgba(255, 149, 0, 0.1)", "--accent-shadow":"rgba(255, 149, 0, 0.2)", "--accent-hover":"rgba(255, 149, 0, 0.3)" },
|
||||
"green_switch": { "--bg-window": "246, 253, 248", "--bg-nav": "235, 250, 240", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(52,199,89,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--border-color":"220, 240, 225", "--accent-color":"52, 199, 89", "--accent-alpha":"rgba(52, 199, 89, 0.1)", "--accent-shadow":"rgba(52, 199, 89, 0.2)", "--accent-hover":"rgba(52, 199, 89, 0.3)" },
|
||||
"blue_switch": { "--bg-window": "246, 249, 253", "--bg-nav": "235, 244, 255", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(0,122,255,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--border-color":"220, 230, 250", "--accent-color":"0, 122, 255", "--accent-alpha":"rgba(0, 122, 255, 0.1)", "--accent-shadow":"rgba(0, 122, 255, 0.2)", "--accent-hover":"rgba(0, 122, 255, 0.3)" }
|
||||
"white_switch": { "--bg-window": "245, 245, 247", "--bg-nav": "255, 255, 255", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(0,0,0,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--text-on-accent": "255, 255, 255", "--border-color":"210, 210, 215", "--accent-color":"0, 122, 255", "--accent-alpha":"rgba(0, 122, 255, 0.1)", "--accent-shadow":"rgba(0, 122, 255, 0.2)", "--accent-hover":"rgba(0, 122, 255, 0.3)" },
|
||||
"black_switch": { "--bg-window": "0, 0, 0", "--bg-nav": "28, 28, 30", "--bg-panel": "28, 28, 30", "--bg-hover": "rgba(255,255,255,0.1)", "--text-primary": "216, 216, 220", "--text-secondary": "134, 134, 139", "--text-on-accent": "216, 216, 220", "--border-color":"44, 44, 46", "--accent-color":"10, 132, 255", "--accent-alpha":"rgba(10, 132, 255, 0.1)", "--accent-shadow":"rgba(10, 132, 255, 0.2)", "--accent-hover":"rgba(10, 132, 255, 0.3)" },
|
||||
"red_switch": { "--bg-window": "253, 246, 246", "--bg-nav": "255, 240, 240", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(255,59,48,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--text-on-accent": "255, 255, 255", "--border-color":"250, 220, 220", "--accent-color":"255, 59, 48", "--accent-alpha":"rgba(255, 59, 48, 0.1)", "--accent-shadow":"rgba(255, 59, 48, 0.2)", "--accent-hover":"rgba(255, 59, 48, 0.3)" },
|
||||
"yellow_switch": { "--bg-window": "254, 251, 243", "--bg-nav": "255, 248, 230", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(255,149,0,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--text-on-accent": "255, 255, 255", "--border-color":"250, 240, 215", "--accent-color":"255, 149, 0", "--accent-alpha":"rgba(255, 149, 0, 0.1)", "--accent-shadow":"rgba(255, 149, 0, 0.2)", "--accent-hover":"rgba(255, 149, 0, 0.3)" },
|
||||
"green_switch": { "--bg-window": "246, 253, 248", "--bg-nav": "235, 250, 240", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(52,199,89,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--text-on-accent": "255, 255, 255", "--border-color":"220, 240, 225", "--accent-color":"52, 199, 89", "--accent-alpha":"rgba(52, 199, 89, 0.1)", "--accent-shadow":"rgba(52, 199, 89, 0.2)", "--accent-hover":"rgba(52, 199, 89, 0.3)" },
|
||||
"blue_switch": { "--bg-window": "246, 249, 253", "--bg-nav": "235, 244, 255", "--bg-panel": "255, 255, 255", "--bg-hover": "rgba(0,122,255,0.05)", "--text-primary": "29, 29, 31", "--text-secondary": "134, 134, 139", "--text-on-accent": "255, 255, 255", "--border-color":"220, 230, 250", "--accent-color":"0, 122, 255", "--accent-alpha":"rgba(0, 122, 255, 0.1)", "--accent-shadow":"rgba(0, 122, 255, 0.2)", "--accent-hover":"rgba(0, 122, 255, 0.3)" }
|
||||
};
|
||||
|
||||
const cols = {
|
||||
@@ -1120,8 +1120,17 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
renderDataGrid('#log_export_window', [], cols.log, 'id', true);
|
||||
renderDataGrid('#netmon_window', [], cols.netmon, 'pid', false);
|
||||
|
||||
window.addEventListener('pywebviewready', () => {
|
||||
window.pywebview.api.get_config().then(cfg => {
|
||||
let pywebviewInitStarted = false;
|
||||
|
||||
const initializePywebview = () => {
|
||||
if (pywebviewInitStarted || !window.pywebview?.api) return;
|
||||
pywebviewInitStarted = true;
|
||||
|
||||
const configTimeout = new Promise((_, reject) => {
|
||||
setTimeout(() => reject(new Error("Configuration request timed out")), 10000);
|
||||
});
|
||||
|
||||
Promise.race([window.pywebview.api.get_config(), configTimeout]).then(cfg => {
|
||||
const theme = cfg.theme || "white_switch";
|
||||
const lang = cfg.language || "english_switch";
|
||||
appState.firstLaunch = cfg.first_launch;
|
||||
@@ -1132,24 +1141,25 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
const switchMap = ["process_switch", "suspend_switch", "load_switch", "document_switch", "system_switch", "network_switch", "driver_switch", "sensitive_switch", "extension_switch", "cloud_switch", "suffix_switch", "autostart_switch", "context_switch"];
|
||||
document.querySelectorAll('.toggle-switch input').forEach((toggle, index) => {
|
||||
if (appState.firstLaunch) {
|
||||
toggle.checked = false;
|
||||
toggle.disabled = true;
|
||||
if (appState.firstLaunch) {
|
||||
toggle.checked = false;
|
||||
toggle.disabled = true;
|
||||
} else if (switchMap[index]) {
|
||||
toggle.checked = !!cfg[switchMap[index]];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
closeStartupOverlay();
|
||||
window.pywebview.api.init_ui_ready();
|
||||
}).catch(err => {
|
||||
pywebviewInitStarted = false;
|
||||
console.error("Config load failed:", err);
|
||||
showStartupError(`Configuration failed to load: ${err?.message || err}`);
|
||||
try {
|
||||
window.pywebview.api.init_ui_ready();
|
||||
} catch (e) {}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
window.addEventListener('pywebviewready', initializePywebview);
|
||||
initializePywebview();
|
||||
|
||||
window.onEngineReady = async () => {
|
||||
if (!appState.firstLaunch) return;
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
<script>
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
window.setTimeout(function () {
|
||||
var app = document.querySelector('.app-container');
|
||||
var overlay = document.getElementById('loading_overlay');
|
||||
if (app) app.classList.add('fade-in');
|
||||
if (overlay && !overlay.classList.contains('fade-out')) overlay.classList.add('fade-out');
|
||||
}, 15000);
|
||||
if (overlay && !overlay.classList.contains('fade-out') && !overlay.classList.contains('startup-error')) {
|
||||
overlay.classList.add('startup-error');
|
||||
overlay.innerHTML = '<div class="startup-error-box"><h1>PYAS failed to open</h1><p>WebView2 initialization timed out. PYAS will retry automatically.</p></div>';
|
||||
}
|
||||
}, 20000);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
+1306
-1086
File diff suppressed because it is too large.
Load diff
+212
-154
@@ -1,6 +1,6 @@
|
||||
#define AppId "{{a7d7bac3-93b8-4630-8308-c7a56bf7fdf4}"
|
||||
#define AppName "PYAS"
|
||||
#define AppVersion "3.6.4.0"
|
||||
#define AppVersion "3.6.8.0"
|
||||
#define AppPublisher "PYAS Security"
|
||||
#define AppURL "https://github.com/87owo/PYAS"
|
||||
#define AppExeName "PYAS.exe"
|
||||
@@ -52,24 +52,22 @@ Name: "arabic"; MessagesFile: "SetupResources\Arabic.isl"
|
||||
Name: "russian"; MessagesFile: "SetupResources\Russian.isl"
|
||||
Name: "slovenian"; MessagesFile: "SetupResources\Slovenian.isl"
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
|
||||
Name: "autostart"; Description: "{cm:AutoStartTask}"; GroupDescription: "{cm:AdditionalIcons}"
|
||||
Name: "install_webview2"; Description: "{cm:InstallWebView2}"; GroupDescription: "{cm:Dependencies}"
|
||||
Name: "install_vcredist"; Description: "{cm:InstallVCRedist}"; GroupDescription: "{cm:Dependencies}"
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
|
||||
|
||||
[Files]
|
||||
Source: "Redist\VC_redist.x64.exe"; DestDir: "{tmp}\PYAS_Redist"; Flags: deleteafterinstall ignoreversion; AfterInstall: EnsureVCRedist
|
||||
Source: "Redist\MicrosoftEdgeWebview2Setup.exe"; DestDir: "{tmp}\PYAS_Redist"; Flags: deleteafterinstall ignoreversion; AfterInstall: EnsureWebView2
|
||||
Source: "Payload\Engine\*"; DestDir: "{app}\Engine"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "Payload\Interface\*"; DestDir: "{app}\Interface"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "Payload\License\*"; DestDir: "{app}\License"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "Payload\PYAS.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "Payload\PYAS.exe"; DestDir: "{app}"; Flags: ignoreversion; AfterInstall: FinalizeDriverRemoval
|
||||
Source: "Payload\Plugins\*"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "Redist\VC_redist.x64.exe"; DestDir: "{tmp}\PYAS_Redist"; Flags: deleteafterinstall ignoreversion
|
||||
Source: "Redist\MicrosoftEdgeWebview2Setup.exe"; DestDir: "{tmp}\PYAS_Redist"; Flags: deleteafterinstall ignoreversion
|
||||
|
||||
[Registry]
|
||||
Root: HKCU; Subkey: "Software\Classes\*\shell\PYAS_Scan"; Flags: uninsdeletekey dontcreatekey
|
||||
Root: HKCU; Subkey: "Software\Classes\Directory\shell\PYAS_Scan"; Flags: uninsdeletekey dontcreatekey
|
||||
[Registry]
|
||||
Root: HKCU; Subkey: "Software\Classes\*\shell\PYAS_Scan"; Flags: uninsdeletekey dontcreatekey
|
||||
Root: HKCU; Subkey: "Software\Classes\Directory\shell\PYAS_Scan"; Flags: uninsdeletekey dontcreatekey
|
||||
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Run"; ValueName: "PYAS_Security"; Flags: uninsdeletevalue dontcreatekey
|
||||
|
||||
[UninstallDelete]
|
||||
Type: filesandordirs; Name: "{commonappdata}\PYAS"
|
||||
@@ -80,9 +78,7 @@ Name: "{group}\{#AppName}"; Filename: "{app}\{#AppExeName}"
|
||||
Name: "{group}\Uninstall {#AppName}"; Filename: "{uninstallexe}"
|
||||
|
||||
[Run]
|
||||
Filename: "{tmp}\PYAS_Redist\VC_redist.x64.exe"; Parameters: "/quiet /norestart"; Flags: waituntilterminated runhidden; StatusMsg: "{cm:InstallingVCRuntime}"; Tasks: install_vcredist
|
||||
Filename: "{tmp}\PYAS_Redist\MicrosoftEdgeWebview2Setup.exe"; Parameters: "/silent /install"; Flags: waituntilterminated runhidden; StatusMsg: "{cm:InstallingWebView2Runtime}"; Tasks: install_webview2
|
||||
Filename: "{app}\{#AppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(AppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent runascurrentuser
|
||||
Filename: "{app}\{#AppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(AppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent runascurrentuser; Check: CanLaunchApp
|
||||
|
||||
[CustomMessages]
|
||||
english.InstallingVCRuntime=Installing Microsoft Visual C++ Runtime...
|
||||
@@ -91,9 +87,6 @@ chinesetraditional.InstallingVCRuntime=正在安裝 Microsoft Visual C++ 執行
|
||||
english.InstallingWebView2Runtime=Installing Microsoft Edge WebView2 Runtime...
|
||||
chinesesimplified.InstallingWebView2Runtime=正在安装 Microsoft Edge WebView2 Runtime...
|
||||
chinesetraditional.InstallingWebView2Runtime=正在安裝 Microsoft Edge WebView2 Runtime...
|
||||
english.AutoStartTask=Run PYAS automatically at system startup
|
||||
chinesesimplified.AutoStartTask=开机时自动运行 PYAS
|
||||
chinesetraditional.AutoStartTask=開機時自動執行 PYAS
|
||||
english.Dependencies=Dependencies:
|
||||
chinesesimplified.Dependencies=运行环境:
|
||||
chinesetraditional.Dependencies=執行環境:
|
||||
@@ -104,154 +97,219 @@ english.InstallVCRedist=Install Microsoft Visual C++ Runtime
|
||||
chinesesimplified.InstallVCRedist=安装 Microsoft Visual C++ 运行库
|
||||
chinesetraditional.InstallVCRedist=安裝 Microsoft Visual C++ 執行庫
|
||||
english.LegacyVersionDetected=An older version of PYAS was detected. Please uninstall it manually before installing.
|
||||
english.QuitFailed=PYAS or its driver could not be stopped safely. Restart Windows and run Setup again.
|
||||
english.DependencyInstallFailed=Required Microsoft runtime installation failed. Setup cannot continue.
|
||||
chinesesimplified.LegacyVersionDetected=检测到存在旧版 PYAS。请先手动卸载旧版后,再运行本安装程序。
|
||||
chinesetraditional.LegacyVersionDetected=檢測到存在舊版 PYAS。請先手動卸載舊版後,再執行本安裝程式。
|
||||
|
||||
[Code]
|
||||
var
|
||||
TasksInitialized: Boolean;
|
||||
|
||||
function IsWebView2Installed: Boolean;
|
||||
var
|
||||
RegKeyPath: string;
|
||||
Version: string;
|
||||
begin
|
||||
RegKeyPath := 'SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}';
|
||||
Result := False;
|
||||
if RegQueryStringValue(HKLM, 'SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version) then
|
||||
if Length(Version) > 0 then Result := True;
|
||||
if not Result and RegQueryStringValue(HKCU, RegKeyPath, 'pv', Version) then
|
||||
if Length(Version) > 0 then Result := True;
|
||||
if not Result and RegQueryStringValue(HKLM, RegKeyPath, 'pv', Version) then
|
||||
if Length(Version) > 0 then Result := True;
|
||||
end;
|
||||
|
||||
function IsVCRedistInstalled: Boolean;
|
||||
var
|
||||
Bld: Cardinal;
|
||||
begin
|
||||
Result := False;
|
||||
if RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', 'Bld', Bld) then
|
||||
if Bld > 0 then Result := True;
|
||||
end;
|
||||
|
||||
procedure CurPageChanged(CurPageID: Integer);
|
||||
var
|
||||
I: Integer;
|
||||
ItemText: string;
|
||||
begin
|
||||
if (CurPageID = wpSelectTasks) and not TasksInitialized then
|
||||
begin
|
||||
TasksInitialized := True;
|
||||
for I := 0 to WizardForm.TasksList.Items.Count - 1 do
|
||||
begin
|
||||
ItemText := WizardForm.TasksList.Items[I];
|
||||
if Pos('Visual C++', ItemText) > 0 then
|
||||
WizardForm.TasksList.Checked[I] := not IsVCRedistInstalled
|
||||
else if Pos('WebView2', ItemText) > 0 then
|
||||
WizardForm.TasksList.Checked[I] := not IsWebView2Installed;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure QuitOldInstance(InstallPath: string);
|
||||
var
|
||||
ResultCode: Integer;
|
||||
ExePath: string;
|
||||
begin
|
||||
ExePath := InstallPath + '\{#AppExeName}';
|
||||
if FileExists(ExePath) then
|
||||
begin
|
||||
Exec(ExePath, '-quit', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
||||
Sleep(500);
|
||||
Exec(ExpandConstant('{sys}\taskkill.exe'), '/F /IM {#AppExeName} /T', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
||||
end;
|
||||
end;
|
||||
|
||||
function InitializeSetup(): Boolean;
|
||||
var
|
||||
OldInstallPath: string;
|
||||
LegacyPath: string;
|
||||
begin
|
||||
LegacyPath := ExpandConstant('{pf32}\{#AppName}');
|
||||
if DirExists(LegacyPath) and FileExists(LegacyPath + '\{#AppExeName}') then
|
||||
begin
|
||||
MsgBox(CustomMessage('LegacyVersionDetected'), mbCriticalError, MB_OK);
|
||||
Result := False;
|
||||
Exit;
|
||||
end;
|
||||
if RegQueryStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + ExpandConstant('{#AppId}') + '_is1', 'InstallLocation', OldInstallPath) or
|
||||
RegQueryStringValue(HKCU, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + ExpandConstant('{#AppId}') + '_is1', 'InstallLocation', OldInstallPath) then
|
||||
begin
|
||||
QuitOldInstance(OldInstallPath);
|
||||
end;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function InitializeUninstall(): Boolean;
|
||||
begin
|
||||
QuitOldInstance(ExpandConstant('{app}'));
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TryCreateStartupTask;
|
||||
var
|
||||
ResultCode: Integer;
|
||||
PSExe: string;
|
||||
PSCommand: string;
|
||||
AppPath: string;
|
||||
begin
|
||||
AppPath := ExpandConstant('{app}\{#AppExeName}');
|
||||
PSExe := ExpandConstant('{sys}\WindowsPowerShell\v1.0\powershell.exe');
|
||||
PSCommand := '-NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -Command ' +
|
||||
'$Action = New-ScheduledTaskAction -Execute ''' + AppPath + ''' -Argument ''-hide''; ' +
|
||||
'$Trigger = New-ScheduledTaskTrigger -AtLogOn; ' +
|
||||
'$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries; ' +
|
||||
'Register-ScheduledTask -TaskName ''PYAS_Security_ATS'' -Action $Action -Trigger $Trigger -Settings $Settings -RunLevel Highest -Force';
|
||||
if not Exec(PSExe, PSCommand, '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
|
||||
begin
|
||||
Log(Format('Failed to create scheduled task, Exec error code: %d', [ResultCode]));
|
||||
end
|
||||
else if ResultCode <> 0 then
|
||||
begin
|
||||
Log(Format('powershell returned exit code %d while creating the scheduled task', [ResultCode]));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TryDeleteStartupTask;
|
||||
var
|
||||
ResultCode: Integer;
|
||||
begin
|
||||
if not Exec(ExpandConstant('{sys}\schtasks.exe'), '/Delete /TN "PYAS_Security_ATS" /F', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
|
||||
begin
|
||||
Log(Format('Failed to delete scheduled task, Exec error code: %d', [ResultCode]));
|
||||
end
|
||||
else if ResultCode <> 0 then
|
||||
begin
|
||||
Log(Format('schtasks returned exit code %d while deleting the scheduled task', [ResultCode]));
|
||||
end;
|
||||
end;
|
||||
[Code]
|
||||
var
|
||||
DependencyRestartRequired: Boolean;
|
||||
DependenciesReady: Boolean;
|
||||
|
||||
function FindWindow(lpClassName: LongWord; lpWindowName: string): HWND;
|
||||
external '[email protected] stdcall';
|
||||
|
||||
function GetTickCount: Cardinal;
|
||||
external '[email protected] stdcall';
|
||||
|
||||
function IsValidRuntimeVersion(Version: string): Boolean;
|
||||
begin
|
||||
Result := (Length(Trim(Version)) > 0) and (Trim(Version) <> '0.0.0.0');
|
||||
end;
|
||||
|
||||
function IsWebView2Installed: Boolean;
|
||||
var
|
||||
Version: string;
|
||||
begin
|
||||
Result := False;
|
||||
if RegQueryStringValue(HKLM, 'SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version) then
|
||||
Result := IsValidRuntimeVersion(Version);
|
||||
if not Result and RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version) then
|
||||
Result := IsValidRuntimeVersion(Version);
|
||||
if not Result and RegQueryStringValue(HKCU, 'SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}', 'pv', Version) then
|
||||
Result := IsValidRuntimeVersion(Version);
|
||||
end;
|
||||
|
||||
function IsVCRedistInstalled: Boolean;
|
||||
var
|
||||
Installed: Cardinal;
|
||||
Version: string;
|
||||
begin
|
||||
Result := False;
|
||||
if RegQueryDWordValue(HKLM64, 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', 'Installed', Installed) and (Installed = 1) then
|
||||
begin
|
||||
if RegQueryStringValue(HKLM64, 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', 'Version', Version) then
|
||||
Result := IsValidRuntimeVersion(Version)
|
||||
else
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
function DependencyExitCodeSucceeded(ResultCode: Integer): Boolean;
|
||||
begin
|
||||
Result := (ResultCode = 0) or (ResultCode = 1641) or (ResultCode = 3010);
|
||||
if (ResultCode = 1641) or (ResultCode = 3010) then
|
||||
DependencyRestartRequired := True;
|
||||
end;
|
||||
|
||||
procedure EnsureVCRedist;
|
||||
var
|
||||
ResultCode: Integer;
|
||||
InstallerPath: string;
|
||||
begin
|
||||
if IsVCRedistInstalled then Exit;
|
||||
InstallerPath := ExpandConstant('{tmp}\PYAS_Redist\VC_redist.x64.exe');
|
||||
WizardForm.StatusLabel.Caption := CustomMessage('InstallingVCRuntime');
|
||||
if not Exec(InstallerPath, '/quiet /norestart', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) or
|
||||
not DependencyExitCodeSucceeded(ResultCode) or not IsVCRedistInstalled then
|
||||
begin
|
||||
DependenciesReady := False;
|
||||
RaiseException(CustomMessage('DependencyInstallFailed'));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure EnsureWebView2;
|
||||
var
|
||||
ResultCode: Integer;
|
||||
InstallerPath: string;
|
||||
begin
|
||||
if IsWebView2Installed then Exit;
|
||||
InstallerPath := ExpandConstant('{tmp}\PYAS_Redist\MicrosoftEdgeWebview2Setup.exe');
|
||||
WizardForm.StatusLabel.Caption := CustomMessage('InstallingWebView2Runtime');
|
||||
if not Exec(InstallerPath, '/silent /install', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) or
|
||||
not DependencyExitCodeSucceeded(ResultCode) or not IsWebView2Installed then
|
||||
begin
|
||||
DependenciesReady := False;
|
||||
RaiseException(CustomMessage('DependencyInstallFailed'));
|
||||
end;
|
||||
end;
|
||||
|
||||
function WaitForMainWindowToClose(TimeoutMs: Cardinal): Boolean;
|
||||
var
|
||||
Deadline: Cardinal;
|
||||
begin
|
||||
Deadline := GetTickCount + TimeoutMs;
|
||||
repeat
|
||||
if FindWindow(0, 'PYAS Security') = 0 then
|
||||
begin
|
||||
Result := True;
|
||||
Exit;
|
||||
end;
|
||||
Sleep(100);
|
||||
until GetTickCount >= Deadline;
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function QuitOldInstance(InstallPath: string): Boolean;
|
||||
var
|
||||
ResultCode: Integer;
|
||||
ExePath: string;
|
||||
begin
|
||||
Result := True;
|
||||
ExePath := InstallPath + '\{#AppExeName}';
|
||||
if not FileExists(ExePath) then Exit;
|
||||
|
||||
if not Exec(ExePath, '-quit', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
|
||||
begin
|
||||
Result := False;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result := (ResultCode = 0) and WaitForMainWindowToClose(30000);
|
||||
end;
|
||||
|
||||
procedure FinalizeDriverRemoval;
|
||||
var
|
||||
ResultCode: Integer;
|
||||
ExePath: string;
|
||||
begin
|
||||
ExePath := ExpandConstant('{app}\{#AppExeName}');
|
||||
if not Exec(ExePath, '-quit', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) or (ResultCode <> 0) then
|
||||
RaiseException(CustomMessage('QuitFailed'));
|
||||
end;
|
||||
|
||||
function InitializeSetup(): Boolean;
|
||||
var
|
||||
OldInstallPath: string;
|
||||
LegacyPath: string;
|
||||
begin
|
||||
DependencyRestartRequired := False;
|
||||
DependenciesReady := True;
|
||||
LegacyPath := ExpandConstant('{pf32}\{#AppName}');
|
||||
if DirExists(LegacyPath) and FileExists(LegacyPath + '\{#AppExeName}') then
|
||||
begin
|
||||
MsgBox(CustomMessage('LegacyVersionDetected'), mbCriticalError, MB_OK);
|
||||
Result := False;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if RegQueryStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + ExpandConstant('{#AppId}') + '_is1', 'InstallLocation', OldInstallPath) or
|
||||
RegQueryStringValue(HKCU, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + ExpandConstant('{#AppId}') + '_is1', 'InstallLocation', OldInstallPath) then
|
||||
begin
|
||||
if not QuitOldInstance(OldInstallPath) then
|
||||
begin
|
||||
MsgBox(CustomMessage('QuitFailed'), mbCriticalError, MB_OK);
|
||||
Result := False;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function InitializeUninstall(): Boolean;
|
||||
begin
|
||||
Result := QuitOldInstance(ExpandConstant('{app}'));
|
||||
if not Result then
|
||||
MsgBox(CustomMessage('QuitFailed'), mbCriticalError, MB_OK);
|
||||
end;
|
||||
|
||||
function CanLaunchApp: Boolean;
|
||||
begin
|
||||
Result := DependenciesReady and not DependencyRestartRequired;
|
||||
end;
|
||||
|
||||
function NeedRestart: Boolean;
|
||||
begin
|
||||
Result := DependencyRestartRequired;
|
||||
end;
|
||||
procedure RemoveLegacyStartupTask;
|
||||
var
|
||||
TaskService: Variant;
|
||||
RootFolder: Variant;
|
||||
begin
|
||||
try
|
||||
TaskService := CreateOleObject('Schedule.Service');
|
||||
TaskService.Connect();
|
||||
RootFolder := TaskService.GetFolder('\');
|
||||
try
|
||||
RootFolder.DeleteTask('PYAS_Security_ATS', 0);
|
||||
Log('Removed legacy PYAS scheduled startup task');
|
||||
except
|
||||
Log('Legacy PYAS scheduled startup task was not present or could not be removed');
|
||||
end;
|
||||
except
|
||||
Log('Task Scheduler COM was unavailable while cleaning the legacy startup task');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure CurStepChanged(CurStep: TSetupStep);
|
||||
begin
|
||||
if CurStep = ssPostInstall then
|
||||
begin
|
||||
if WizardIsTaskSelected('autostart') then
|
||||
begin
|
||||
TryCreateStartupTask;
|
||||
end;
|
||||
end;
|
||||
if CurStep = ssPostInstall then
|
||||
begin
|
||||
RemoveLegacyStartupTask;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
||||
begin
|
||||
if CurUninstallStep = usUninstall then
|
||||
begin
|
||||
TryDeleteStartupTask;
|
||||
if CurUninstallStep = usUninstall then
|
||||
begin
|
||||
RemoveLegacyStartupTask;
|
||||
end
|
||||
else if CurUninstallStep = usPostUninstall then
|
||||
begin
|
||||
DelTree(ExpandConstant('{app}'), True, True, True);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
+86
-43
@@ -82,26 +82,49 @@ class ProtectMixin:
|
||||
def init_whitelist(self):
|
||||
self.manage_named_list("white_list", [self.file_pyas], action="add")
|
||||
|
||||
def sync_driver_whitelist(self, file_path, is_add=True):
|
||||
def _driver_whitelist_patterns(self, file_path, is_directory=None):
|
||||
normalized_path = self.norm_path(file_path, must_exist=False)
|
||||
if not normalized_path:
|
||||
return []
|
||||
|
||||
if is_directory is None:
|
||||
is_directory = os.path.isdir(normalized_path)
|
||||
|
||||
drive_letter = os.path.splitdrive(normalized_path)[0]
|
||||
driver_path = "*" + normalized_path[len(drive_letter):] if drive_letter else normalized_path
|
||||
patterns = [driver_path]
|
||||
|
||||
if is_directory:
|
||||
descendant_pattern = driver_path.rstrip("\\/") + "\\*"
|
||||
if descendant_pattern not in patterns:
|
||||
patterns.append(descendant_pattern)
|
||||
|
||||
return patterns
|
||||
|
||||
def sync_driver_whitelist(self, file_path, is_add=True, is_directory=None):
|
||||
with self.lock_driver:
|
||||
if not self.driver_port:
|
||||
return False
|
||||
|
||||
driver_path = str(file_path)
|
||||
drive_letter = os.path.splitdrive(driver_path)[0]
|
||||
if drive_letter:
|
||||
driver_path = "*" + driver_path[len(drive_letter):]
|
||||
|
||||
msg = PYAS_USER_MESSAGE()
|
||||
msg.Command = 1 if is_add else 2
|
||||
msg.Path = driver_path
|
||||
bytes_returned = ctypes.wintypes.DWORD(0)
|
||||
|
||||
try:
|
||||
return self.fltlib.FilterSendMessage(self.driver_port, ctypes.byref(msg), ctypes.sizeof(msg), None, 0, ctypes.byref(bytes_returned)) == 0
|
||||
except Exception:
|
||||
patterns = self._driver_whitelist_patterns(file_path, is_directory)
|
||||
if not patterns:
|
||||
return False
|
||||
|
||||
success = True
|
||||
for driver_path in patterns:
|
||||
msg = PYAS_USER_MESSAGE()
|
||||
msg.Command = 1 if is_add else 2
|
||||
bytes_returned = ctypes.wintypes.DWORD(0)
|
||||
|
||||
try:
|
||||
msg.Path = driver_path
|
||||
if self.fltlib.FilterSendMessage(self.driver_port, ctypes.byref(msg), ctypes.sizeof(msg), None, 0, ctypes.byref(bytes_returned)) != 0:
|
||||
success = False
|
||||
except Exception:
|
||||
success = False
|
||||
|
||||
return success
|
||||
|
||||
####################################################################################################
|
||||
|
||||
def _try_lock_file(self, file_path):
|
||||
@@ -891,7 +914,10 @@ class ProtectMixin:
|
||||
running = any(exe_name.lower() == "explorer.exe" for _, exe_name in self._enum_processes())
|
||||
|
||||
if not running:
|
||||
subprocess.Popen("explorer.exe", shell=True)
|
||||
explorer = self._find_windows_tool("explorer.exe")
|
||||
if not explorer:
|
||||
return
|
||||
subprocess.Popen([explorer])
|
||||
self.write_log("INFO", "System Restart", source="explorer.exe")
|
||||
|
||||
except Exception:
|
||||
@@ -1192,36 +1218,54 @@ class ProtectMixin:
|
||||
return False, 1051
|
||||
return self._delete_driver_service()
|
||||
|
||||
def _delete_driver_service(self):
|
||||
scm = self.advapi32.OpenSCManagerW(None, None, 0x0001)
|
||||
if not scm:
|
||||
return False, ctypes.get_last_error()
|
||||
def _delete_driver_service(self, timeout=15.0):
|
||||
deadline = time.monotonic() + timeout
|
||||
last_error = 0
|
||||
delete_requested = False
|
||||
|
||||
service = None
|
||||
try:
|
||||
service = self.advapi32.OpenServiceW(scm, "PYAS_Driver", 0x0004 | 0x00010000)
|
||||
if not service:
|
||||
error = ctypes.get_last_error()
|
||||
return (True, 0) if error in (1060, 1072) else (False, error)
|
||||
while time.monotonic() < deadline:
|
||||
scm = self.advapi32.OpenSCManagerW(None, None, 0x0001)
|
||||
if not scm:
|
||||
return False, ctypes.get_last_error()
|
||||
|
||||
state, error = self._query_service_state_handle(service)
|
||||
if error:
|
||||
return False, error
|
||||
if state in (2, 3, 4):
|
||||
return False, 1051
|
||||
service = None
|
||||
try:
|
||||
ctypes.set_last_error(0)
|
||||
service = self.advapi32.OpenServiceW(scm, "PYAS_Driver", 0x0004 | 0x00010000)
|
||||
if not service:
|
||||
last_error = ctypes.get_last_error()
|
||||
if last_error == 1060:
|
||||
return True, 0
|
||||
if last_error != 1072:
|
||||
return False, last_error
|
||||
else:
|
||||
state, status_error = self._query_service_state_handle(service)
|
||||
if status_error:
|
||||
return False, status_error
|
||||
|
||||
ctypes.set_last_error(0)
|
||||
if self.advapi32.DeleteService(service):
|
||||
return True, 0
|
||||
if state not in (2, 3, 4) and not delete_requested:
|
||||
ctypes.set_last_error(0)
|
||||
if self.advapi32.DeleteService(service):
|
||||
delete_requested = True
|
||||
last_error = 1072
|
||||
else:
|
||||
last_error = ctypes.get_last_error()
|
||||
if last_error == 1060:
|
||||
return True, 0
|
||||
if last_error == 1072:
|
||||
delete_requested = True
|
||||
else:
|
||||
return False, last_error
|
||||
elif state in (2, 3, 4):
|
||||
last_error = 1051
|
||||
finally:
|
||||
if service:
|
||||
self.advapi32.CloseServiceHandle(service)
|
||||
self.advapi32.CloseServiceHandle(scm)
|
||||
|
||||
error = ctypes.get_last_error()
|
||||
if error in (1060, 1072):
|
||||
return True, 0
|
||||
return False, error
|
||||
finally:
|
||||
if service:
|
||||
self.advapi32.CloseServiceHandle(service)
|
||||
self.advapi32.CloseServiceHandle(scm)
|
||||
time.sleep(0.1)
|
||||
|
||||
return False, last_error or 1072
|
||||
|
||||
def install_system_driver(self):
|
||||
try:
|
||||
@@ -1887,7 +1931,7 @@ class ProtectMixin:
|
||||
if self.driver_stop_event.is_set():
|
||||
break
|
||||
if isinstance(item, dict) and item.get("file"):
|
||||
self.sync_driver_whitelist(item["file"], True)
|
||||
self.sync_driver_whitelist(item["file"], True, item.get("is_dir"))
|
||||
|
||||
if self.driver_stop_event.is_set():
|
||||
break
|
||||
@@ -1954,4 +1998,3 @@ class ProtectMixin:
|
||||
with self.lock_driver:
|
||||
if self.driver_listener_thread is threading.current_thread():
|
||||
self.driver_listener_thread = None
|
||||
|
||||
+336
-43
@@ -1,4 +1,4 @@
|
||||
import os, re, io, csv, time, shutil, threading
|
||||
import os, re, io, csv, json, time, shutil, threading
|
||||
import pefile, hashlib, winreg, requests, subprocess
|
||||
import ctypes, ctypes.wintypes
|
||||
|
||||
@@ -167,6 +167,186 @@ class RECT(ctypes.Structure):
|
||||
####################################################################################################
|
||||
|
||||
class ToolsMixin:
|
||||
def _find_windows_tool(self, *names):
|
||||
windows_dir = os.environ.get("SystemRoot") or os.environ.get("WINDIR") or r"C:\Windows"
|
||||
search_dirs = [
|
||||
os.path.join(windows_dir, "Sysnative"),
|
||||
os.path.join(windows_dir, "System32"),
|
||||
windows_dir
|
||||
]
|
||||
|
||||
for name in names:
|
||||
executable_name = name if name.lower().endswith(".exe") else name + ".exe"
|
||||
for directory in search_dirs:
|
||||
candidate = os.path.join(directory, executable_name)
|
||||
if os.path.isfile(candidate):
|
||||
return candidate
|
||||
|
||||
candidate = shutil.which(name)
|
||||
if candidate:
|
||||
return candidate
|
||||
|
||||
return None
|
||||
|
||||
def _run_windows_tool(self, tool_names, arguments, **kwargs):
|
||||
executable = self._find_windows_tool(*tool_names)
|
||||
if not executable:
|
||||
return None
|
||||
|
||||
options = {"creationflags": 0x08000000}
|
||||
options.update(kwargs)
|
||||
try:
|
||||
return subprocess.run([executable, *arguments], **options)
|
||||
except (FileNotFoundError, OSError):
|
||||
return None
|
||||
|
||||
def _run_powershell(self, command, **kwargs):
|
||||
return self._run_windows_tool(
|
||||
("powershell.exe", "pwsh.exe"),
|
||||
["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-Command", command],
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def _set_registry_autostart(self, enable):
|
||||
run_key = r"Software\Microsoft\Windows\CurrentVersion\Run"
|
||||
value_name = "PYAS_Security"
|
||||
if enable:
|
||||
command = f'"{self.file_pyas}" -hide'
|
||||
return self._reg_write(winreg.HKEY_CURRENT_USER, run_key, value_name, winreg.REG_SZ, command)
|
||||
|
||||
try:
|
||||
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, run_key, 0, winreg.KEY_SET_VALUE) as reg:
|
||||
try:
|
||||
winreg.DeleteValue(reg, value_name)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
return True
|
||||
except FileNotFoundError:
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def _clear_event_log(self, log_name):
|
||||
result = self._run_windows_tool(
|
||||
("wevtutil.exe",),
|
||||
["cl", log_name],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL
|
||||
)
|
||||
if result is not None and result.returncode == 0:
|
||||
return True
|
||||
|
||||
try:
|
||||
wevtapi = ctypes.WinDLL("wevtapi", use_last_error=True)
|
||||
wevtapi.EvtClearLog.argtypes = [ctypes.wintypes.HANDLE, ctypes.wintypes.LPCWSTR, ctypes.wintypes.LPCWSTR, ctypes.wintypes.DWORD]
|
||||
wevtapi.EvtClearLog.restype = ctypes.wintypes.BOOL
|
||||
return bool(wevtapi.EvtClearLog(None, log_name, None, 0))
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def _manage_service_native(self, service_name, action):
|
||||
SC_MANAGER_CONNECT = 0x0001
|
||||
SERVICE_CHANGE_CONFIG = 0x0002
|
||||
DELETE = 0x00010000
|
||||
SERVICE_NO_CHANGE = 0xFFFFFFFF
|
||||
SERVICE_AUTO_START = 0x00000002
|
||||
SERVICE_DISABLED = 0x00000004
|
||||
|
||||
try:
|
||||
advapi32 = ctypes.WinDLL("advapi32", use_last_error=True)
|
||||
advapi32.OpenSCManagerW.argtypes = [ctypes.wintypes.LPCWSTR, ctypes.wintypes.LPCWSTR, ctypes.wintypes.DWORD]
|
||||
advapi32.OpenSCManagerW.restype = ctypes.wintypes.HANDLE
|
||||
advapi32.OpenServiceW.argtypes = [ctypes.wintypes.HANDLE, ctypes.wintypes.LPCWSTR, ctypes.wintypes.DWORD]
|
||||
advapi32.OpenServiceW.restype = ctypes.wintypes.HANDLE
|
||||
advapi32.CloseServiceHandle.argtypes = [ctypes.wintypes.HANDLE]
|
||||
advapi32.CloseServiceHandle.restype = ctypes.wintypes.BOOL
|
||||
|
||||
manager = advapi32.OpenSCManagerW(None, None, SC_MANAGER_CONNECT)
|
||||
if not manager:
|
||||
return False
|
||||
|
||||
service = None
|
||||
try:
|
||||
desired_access = DELETE if action == "delete" else SERVICE_CHANGE_CONFIG
|
||||
service = advapi32.OpenServiceW(manager, service_name, desired_access)
|
||||
if not service:
|
||||
return False
|
||||
|
||||
if action == "delete":
|
||||
advapi32.DeleteService.argtypes = [ctypes.wintypes.HANDLE]
|
||||
advapi32.DeleteService.restype = ctypes.wintypes.BOOL
|
||||
return bool(advapi32.DeleteService(service))
|
||||
|
||||
start_type = SERVICE_AUTO_START if action == "enable" else SERVICE_DISABLED
|
||||
advapi32.ChangeServiceConfigW.argtypes = [
|
||||
ctypes.wintypes.HANDLE,
|
||||
ctypes.wintypes.DWORD,
|
||||
ctypes.wintypes.DWORD,
|
||||
ctypes.wintypes.DWORD,
|
||||
ctypes.wintypes.LPCWSTR,
|
||||
ctypes.wintypes.LPCWSTR,
|
||||
ctypes.POINTER(ctypes.wintypes.DWORD),
|
||||
ctypes.wintypes.LPCWSTR,
|
||||
ctypes.wintypes.LPCWSTR,
|
||||
ctypes.wintypes.LPCWSTR,
|
||||
ctypes.wintypes.LPCWSTR
|
||||
]
|
||||
advapi32.ChangeServiceConfigW.restype = ctypes.wintypes.BOOL
|
||||
return bool(advapi32.ChangeServiceConfigW(
|
||||
service,
|
||||
SERVICE_NO_CHANGE,
|
||||
start_type,
|
||||
SERVICE_NO_CHANGE,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None
|
||||
))
|
||||
finally:
|
||||
if service:
|
||||
advapi32.CloseServiceHandle(service)
|
||||
advapi32.CloseServiceHandle(manager)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def _manage_scheduled_task(self, task_path, action):
|
||||
schtasks_action = "/delete" if action == "delete" else "/change"
|
||||
arguments = [schtasks_action, "/tn", task_path]
|
||||
if action == "delete":
|
||||
arguments.append("/f")
|
||||
else:
|
||||
arguments.append("/enable" if action == "enable" else "/disable")
|
||||
|
||||
result = self._run_windows_tool(
|
||||
("schtasks.exe",),
|
||||
arguments,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
if result is not None and result.returncode == 0:
|
||||
return True
|
||||
|
||||
escaped_path = task_path.replace("'", "''")
|
||||
operation = {
|
||||
"delete": "Unregister-ScheduledTask -InputObject $Task -Confirm:$false",
|
||||
"enable": "Enable-ScheduledTask -InputObject $Task | Out-Null",
|
||||
"disable": "Disable-ScheduledTask -InputObject $Task | Out-Null"
|
||||
}.get(action)
|
||||
if not operation:
|
||||
return False
|
||||
|
||||
command = (
|
||||
f"$FullName = '{escaped_path}'; "
|
||||
"$Task = Get-ScheduledTask -ErrorAction SilentlyContinue | "
|
||||
"Where-Object { ($_.TaskPath + $_.TaskName) -eq $FullName } | Select-Object -First 1; "
|
||||
f"if ($Task) {{ {operation} }} else {{ exit 1 }}"
|
||||
)
|
||||
result = self._run_powershell(command, capture_output=True, text=True)
|
||||
return bool(result and result.returncode == 0)
|
||||
|
||||
def _reg_read(self, root, path, value_name):
|
||||
try:
|
||||
with winreg.OpenKey(root, path, 0, winreg.KEY_READ) as reg:
|
||||
@@ -203,18 +383,81 @@ class ToolsMixin:
|
||||
####################################################################################################
|
||||
|
||||
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)
|
||||
task_name = "PYAS_Security_ATS"
|
||||
executable = os.path.normpath(self.file_pyas)
|
||||
escaped_executable = executable.replace("'", "''")
|
||||
errors = []
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
self.write_log("WARN", "manage_autostart", detail=str(e), success=False)
|
||||
return False
|
||||
if enable:
|
||||
task_command = f'"{executable}" -hide'
|
||||
result = self._run_windows_tool(
|
||||
("schtasks.exe",),
|
||||
["/Create", "/TN", task_name, "/TR", task_command, "/SC", "ONLOGON", "/RL", "HIGHEST", "/F"],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
if result and result.returncode == 0:
|
||||
self._set_registry_autostart(False)
|
||||
return True
|
||||
if result:
|
||||
errors.append((result.stderr or result.stdout or f"schtasks exit {result.returncode}").strip())
|
||||
|
||||
command = (
|
||||
f"$Action = New-ScheduledTaskAction -Execute '{escaped_executable}' -Argument '-hide'; "
|
||||
"$Trigger = New-ScheduledTaskTrigger -AtLogOn; "
|
||||
"$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries; "
|
||||
f"Register-ScheduledTask -TaskName '{task_name}' -Action $Action -Trigger $Trigger -Settings $Settings -RunLevel Highest -Force | Out-Null"
|
||||
)
|
||||
result = self._run_powershell(command, capture_output=True, text=True)
|
||||
if result and result.returncode == 0:
|
||||
self._set_registry_autostart(False)
|
||||
return True
|
||||
if result:
|
||||
errors.append((result.stderr or result.stdout or f"PowerShell exit {result.returncode}").strip())
|
||||
|
||||
if self._set_registry_autostart(True):
|
||||
self.write_log("INFO", "manage_autostart", detail="Scheduled Task unavailable; using HKCU Run fallback", success=True)
|
||||
return True
|
||||
else:
|
||||
task_removed = False
|
||||
query_result = self._run_windows_tool(
|
||||
("schtasks.exe",),
|
||||
["/Query", "/TN", task_name],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
result = None
|
||||
if query_result is not None and query_result.returncode != 0:
|
||||
task_removed = True
|
||||
elif query_result is not None:
|
||||
result = self._run_windows_tool(
|
||||
("schtasks.exe",),
|
||||
["/Delete", "/TN", task_name, "/F"],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
task_removed = bool(result and result.returncode == 0)
|
||||
|
||||
if query_result is None or not task_removed:
|
||||
command = (
|
||||
f"$Task = Get-ScheduledTask -TaskName '{task_name}' -ErrorAction SilentlyContinue; "
|
||||
"if ($Task) { $Task | Unregister-ScheduledTask -Confirm:$false }"
|
||||
)
|
||||
powershell_result = self._run_powershell(command, capture_output=True, text=True)
|
||||
if powershell_result is not None:
|
||||
task_removed = powershell_result.returncode == 0
|
||||
result = powershell_result
|
||||
|
||||
if result and result.returncode != 0:
|
||||
errors.append((result.stderr or result.stdout or f"task removal exit {result.returncode}").strip())
|
||||
|
||||
registry_removed = self._set_registry_autostart(False)
|
||||
if registry_removed and (task_removed or query_result is None and result is None):
|
||||
return True
|
||||
|
||||
detail = "; ".join(error for error in errors if error) or "No supported autostart method was available"
|
||||
self.write_log("WARN", "manage_autostart", detail=detail, success=False)
|
||||
return False
|
||||
|
||||
####################################################################################################
|
||||
|
||||
@@ -292,10 +535,16 @@ class ToolsMixin:
|
||||
if lock_func:
|
||||
lock_func(path, True)
|
||||
|
||||
target_list.append({"file": path, "time": time.time()})
|
||||
new_item = {"file": path, "time": time.time()}
|
||||
is_directory = None
|
||||
if list_key == "white_list":
|
||||
is_directory = os.path.isdir(path)
|
||||
new_item["is_dir"] = is_directory
|
||||
|
||||
target_list.append(new_item)
|
||||
acted_items.append(path)
|
||||
if list_key == "white_list":
|
||||
self.sync_driver_whitelist(path, True)
|
||||
self.sync_driver_whitelist(path, True, is_directory)
|
||||
|
||||
elif action == "remove":
|
||||
norm_paths_case = {os.path.normcase(p) for p in norm_paths}
|
||||
@@ -311,7 +560,8 @@ class ToolsMixin:
|
||||
|
||||
acted_items.append(val)
|
||||
if list_key == "white_list":
|
||||
self.sync_driver_whitelist(val, False)
|
||||
is_directory = item.get("is_dir") if isinstance(item, dict) else None
|
||||
self.sync_driver_whitelist(val, False, is_directory)
|
||||
|
||||
continue
|
||||
new_list.append(item)
|
||||
@@ -356,7 +606,8 @@ class ToolsMixin:
|
||||
if np and os.path.normcase(np) in norm_paths_to_remove:
|
||||
removed_items.append(val)
|
||||
if list_key == "white_list":
|
||||
self.sync_driver_whitelist(val, False)
|
||||
is_directory = item.get("is_dir") if isinstance(item, dict) else None
|
||||
self.sync_driver_whitelist(val, False, is_directory)
|
||||
|
||||
continue
|
||||
new_list.append(item)
|
||||
@@ -888,7 +1139,7 @@ class ToolsMixin:
|
||||
log_path = os.path.join(self.path_system, "System32", "winevt", "Logs", f"{log_type}.evtx")
|
||||
|
||||
size = os.path.getsize(log_path) if os.path.exists(log_path) else 0
|
||||
if subprocess.run(["wevtutil", "cl", log_type], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, creationflags=0x08000000).returncode == 0:
|
||||
if self._clear_event_log(log_type):
|
||||
total_deleted += size
|
||||
|
||||
except Exception:
|
||||
@@ -1035,20 +1286,57 @@ class ToolsMixin:
|
||||
def get_tasks():
|
||||
res = []
|
||||
try:
|
||||
proc = subprocess.run(["schtasks", "/query", "/fo", "csv", "/v"], capture_output=True, text=True, creationflags=0x08000000)
|
||||
reader = csv.reader(io.StringIO(proc.stdout))
|
||||
next(reader, None)
|
||||
proc = self._run_windows_tool(
|
||||
("schtasks.exe",),
|
||||
["/query", "/fo", "csv", "/v"],
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
if proc is not None and proc.returncode == 0:
|
||||
reader = csv.reader(io.StringIO(proc.stdout))
|
||||
next(reader, None)
|
||||
|
||||
for row in reader:
|
||||
if len(row) > 8 and row[1].strip() and row[8].strip() and row[8] != "N/A":
|
||||
name = row[1].split('\\')[-1]
|
||||
path = row[8]
|
||||
status = row[3]
|
||||
for row in reader:
|
||||
if len(row) > 8 and row[1].strip() and row[8].strip() and row[8] != "N/A":
|
||||
name = row[1].split('\\')[-1]
|
||||
path = row[8]
|
||||
status = row[3]
|
||||
|
||||
if path and "windows" not in path.lower():
|
||||
fp = self.extract_paths_from_cmdline(path)
|
||||
fpp = fp[0] if fp else path
|
||||
res.append({"id": f"tsk|{row[1]}", "type": "type_tsk", "name": name, "status": "disabled" if status == "Disabled" else "enabled", "path": fpp})
|
||||
if path and "windows" not in path.lower():
|
||||
fp = self.extract_paths_from_cmdline(path)
|
||||
fpp = fp[0] if fp else path
|
||||
res.append({"id": f"tsk|{row[1]}", "type": "type_tsk", "name": name, "status": "disabled" if status.lower() == "disabled" else "enabled", "path": fpp})
|
||||
return res
|
||||
|
||||
command = (
|
||||
"[Console]::OutputEncoding = [Text.UTF8Encoding]::new(); "
|
||||
"Get-ScheduledTask -ErrorAction SilentlyContinue | ForEach-Object { "
|
||||
"$Action = @($_.Actions)[0]; "
|
||||
"[pscustomobject]@{Name=$_.TaskName; FullName=($_.TaskPath + $_.TaskName); "
|
||||
"State=[string]$_.State; Execute=$Action.Execute; Arguments=$Action.Arguments} "
|
||||
"} | ConvertTo-Json -Compress"
|
||||
)
|
||||
proc = self._run_powershell(command, capture_output=True, text=True, encoding="utf-8", errors="replace")
|
||||
if not proc or proc.returncode != 0 or not proc.stdout.strip():
|
||||
return res
|
||||
|
||||
task_data = json.loads(proc.stdout)
|
||||
if isinstance(task_data, dict):
|
||||
task_data = [task_data]
|
||||
|
||||
for task in task_data:
|
||||
name = str(task.get("Name") or "").strip()
|
||||
full_name = str(task.get("FullName") or name).strip()
|
||||
execute = str(task.get("Execute") or "").strip()
|
||||
arguments = str(task.get("Arguments") or "").strip()
|
||||
command_line = " ".join(part for part in (execute, arguments) if part)
|
||||
if not name or not command_line or "windows" in command_line.lower():
|
||||
continue
|
||||
|
||||
paths = self.extract_paths_from_cmdline(command_line)
|
||||
path = paths[0] if paths else execute or command_line
|
||||
status = "disabled" if str(task.get("State") or "").lower() == "disabled" else "enabled"
|
||||
res.append({"id": f"tsk|{full_name}", "type": "type_tsk", "name": name, "status": status, "path": path})
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
@@ -1068,44 +1356,49 @@ class ToolsMixin:
|
||||
def manage_startup(self, items, action):
|
||||
def process_item(item_id):
|
||||
try:
|
||||
parts = item_id.split('|')
|
||||
parts = item_id.split('|', 3)
|
||||
stype = parts[0]
|
||||
|
||||
if stype == "reg":
|
||||
root, old_path, name = int(parts[1]), parts[2], parts[3]
|
||||
if action == "delete":
|
||||
self._reg_delete(root, old_path, name)
|
||||
return self._reg_delete(root, old_path, name)
|
||||
|
||||
else:
|
||||
new_path = old_path.replace("_Disabled", "") if action == "enable" else (old_path if "_Disabled" in old_path else old_path + "_Disabled")
|
||||
if old_path != new_path:
|
||||
val = self._reg_read(root, old_path, name)
|
||||
if val:
|
||||
self._reg_write(root, new_path, name, winreg.REG_SZ, val)
|
||||
self._reg_delete(root, old_path, name)
|
||||
return self._reg_write(root, new_path, name, winreg.REG_SZ, val) and self._reg_delete(root, old_path, name)
|
||||
return True
|
||||
|
||||
elif stype == "srv":
|
||||
name = parts[1]
|
||||
if action == "delete":
|
||||
subprocess.run(["sc", "delete", name], capture_output=True, creationflags=0x08000000)
|
||||
result = self._run_windows_tool(("sc.exe",), ["delete", name], capture_output=True)
|
||||
|
||||
else:
|
||||
mode = "auto" if action == "enable" else "disabled"
|
||||
subprocess.run(["sc", "config", name, f"start=", mode], capture_output=True, creationflags=0x08000000)
|
||||
result = self._run_windows_tool(("sc.exe",), ["config", name, "start=", mode], capture_output=True)
|
||||
|
||||
if result is not None and result.returncode == 0:
|
||||
return True
|
||||
return self._manage_service_native(name, action)
|
||||
|
||||
elif stype == "tsk":
|
||||
name = parts[1]
|
||||
if action == "delete":
|
||||
subprocess.run(["schtasks", "/delete", "/tn", name, "/f"], capture_output=True, creationflags=0x08000000)
|
||||
name = item_id.partition('|')[2]
|
||||
return self._manage_scheduled_task(name, action)
|
||||
|
||||
else:
|
||||
cmd = "/enable" if action == "enable" else "/disable"
|
||||
subprocess.run(["schtasks", "/change", "/tn", name, cmd], capture_output=True, creationflags=0x08000000)
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
self.write_log("WARN", "manage_startup", detail=str(e), success=False)
|
||||
return False
|
||||
|
||||
with ThreadPoolExecutor(max_workers=5) as executor:
|
||||
list(executor.map(process_item, items))
|
||||
results = list(executor.map(process_item, items))
|
||||
|
||||
return True
|
||||
success = all(results) if results else True
|
||||
if not success:
|
||||
self.write_log("WARN", "manage_startup", detail="One or more startup items could not be updated", success=False)
|
||||
return success
|
||||
+1
-1
@@ -2,7 +2,7 @@ import pyinstaller_versionfile
|
||||
|
||||
pyinstaller_versionfile.create_versionfile(
|
||||
output_file="versionfile.txt",
|
||||
version='3.6.4.0',
|
||||
version='3.6.8.0',
|
||||
company_name="PYAS Security",
|
||||
file_description="PYAS Security Antivirus",
|
||||
internal_name="PYAS",
|
||||
|
||||
@@ -61,10 +61,11 @@
|
||||
"Category": "Process",
|
||||
"InitiatorExclude": [
|
||||
"*\\PYAS.exe",
|
||||
"*\\PYAS_Setup.exe",
|
||||
"*\\unins000.exe",
|
||||
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\Temp\\*\\PYAS_Setup.tmp",
|
||||
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\Temp\\*\\_unins.tmp",
|
||||
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\sogoupdf\\pdfpopcl.exe",
|
||||
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\WeGame\\*\\tiny_dl\\TinyDL.exe",
|
||||
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\Microsoft\\OneDrive\\OneDrive.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\explorer.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\csrss.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\lsass.exe",
|
||||
@@ -76,6 +77,8 @@
|
||||
"\\Device\\HarddiskVolume*\\Program Files (x86)\\*",
|
||||
"*\\games\\Arknights Game\\Arknights.exe",
|
||||
"*\\games\\EndField Game\\EndField.exe",
|
||||
"*\\cm\\FeverGames\\*\\FeverGamesInstaller.exe",
|
||||
"*\\Davinci\\Resolve.exe",
|
||||
],
|
||||
"Target": [
|
||||
"*\\PYAS.exe",
|
||||
@@ -198,153 +201,6 @@
|
||||
],
|
||||
"Priority": 160,
|
||||
},
|
||||
{
|
||||
"Name": "Memory_Protect_Critical_Process_CreateRemoteThread",
|
||||
"Code": 1007,
|
||||
"Kill": false,
|
||||
"Category": "Memory",
|
||||
"InitiatorExclude": [
|
||||
"\\Device\\HarddiskVolume*\\Windows\\*",
|
||||
"\\Device\\HarddiskVolume*\\Program Files\\*",
|
||||
"\\Device\\HarddiskVolume*\\Program Files (x86)\\*",
|
||||
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\*",
|
||||
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender Advanced Threat Protection\\*",
|
||||
"*\\Huorong\\Sysdiag\\bin\\HipsDaemon.exe",
|
||||
"*\\360Safe.exe",
|
||||
"*\\PYAS.exe",
|
||||
],
|
||||
"Target": [
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\lsass.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\winlogon.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\services.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\csrss.exe",
|
||||
],
|
||||
"Operations": [
|
||||
"WriteMemory",
|
||||
"VmOperation",
|
||||
"CreateThread",
|
||||
],
|
||||
"OperationMatch": "All",
|
||||
"MinimumRiskScore": 90,
|
||||
"HandleTypes": [
|
||||
"Create",
|
||||
"Duplicate",
|
||||
],
|
||||
"ObjectTypes": [
|
||||
"Process",
|
||||
],
|
||||
"Priority": 175,
|
||||
},
|
||||
{
|
||||
"Name": "Memory_Protect_Critical_Process_ThreadHijack",
|
||||
"Code": 1008,
|
||||
"Kill": false,
|
||||
"Category": "Memory",
|
||||
"InitiatorExclude": [
|
||||
"\\Device\\HarddiskVolume*\\Windows\\*",
|
||||
"\\Device\\HarddiskVolume*\\Program Files\\*",
|
||||
"\\Device\\HarddiskVolume*\\Program Files (x86)\\*",
|
||||
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\*",
|
||||
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender Advanced Threat Protection\\*",
|
||||
"*\\Huorong\\Sysdiag\\bin\\HipsDaemon.exe",
|
||||
"*\\360Safe.exe",
|
||||
"*\\PYAS.exe",
|
||||
],
|
||||
"Target": [
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\lsass.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\winlogon.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\services.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\csrss.exe",
|
||||
],
|
||||
"Operations": [
|
||||
"WriteMemory",
|
||||
"VmOperation",
|
||||
"SetThreadContext",
|
||||
],
|
||||
"OperationMatch": "All",
|
||||
"MinimumRiskScore": 90,
|
||||
"HandleTypes": [
|
||||
"Create",
|
||||
"Duplicate",
|
||||
],
|
||||
"ObjectTypes": [
|
||||
"Process",
|
||||
],
|
||||
"Priority": 175,
|
||||
},
|
||||
{
|
||||
"Name": "Memory_Protect_Service_Process_CreateRemoteThread",
|
||||
"Code": 1009,
|
||||
"Kill": false,
|
||||
"Category": "Memory",
|
||||
"InitiatorExclude": [
|
||||
"\\Device\\HarddiskVolume*\\Windows\\*",
|
||||
"\\Device\\HarddiskVolume*\\Program Files\\*",
|
||||
"\\Device\\HarddiskVolume*\\Program Files (x86)\\*",
|
||||
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\*",
|
||||
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender Advanced Threat Protection\\*",
|
||||
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\*",
|
||||
"*\\Huorong\\Sysdiag\\bin\\HipsDaemon.exe",
|
||||
"*\\360Safe.exe",
|
||||
"*\\PYAS.exe",
|
||||
],
|
||||
"Target": [
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\svchost.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\svchost.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\spoolsv.exe",
|
||||
],
|
||||
"Operations": [
|
||||
"WriteMemory",
|
||||
"VmOperation",
|
||||
"CreateThread",
|
||||
],
|
||||
"OperationMatch": "All",
|
||||
"MinimumRiskScore": 90,
|
||||
"HandleTypes": [
|
||||
"Create",
|
||||
"Duplicate",
|
||||
],
|
||||
"ObjectTypes": [
|
||||
"Process",
|
||||
],
|
||||
"Priority": 170,
|
||||
},
|
||||
{
|
||||
"Name": "Memory_Protect_Service_Process_ThreadHijack",
|
||||
"Code": 1010,
|
||||
"Kill": false,
|
||||
"Category": "Memory",
|
||||
"InitiatorExclude": [
|
||||
"\\Device\\HarddiskVolume*\\Windows\\*",
|
||||
"\\Device\\HarddiskVolume*\\Program Files\\*",
|
||||
"\\Device\\HarddiskVolume*\\Program Files (x86)\\*",
|
||||
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\*",
|
||||
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender Advanced Threat Protection\\*",
|
||||
"*\\Huorong\\Sysdiag\\bin\\HipsDaemon.exe",
|
||||
"*\\360Safe.exe",
|
||||
"*\\PYAS.exe",
|
||||
],
|
||||
"Target": [
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\svchost.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\SysWOW64\\svchost.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\spoolsv.exe",
|
||||
],
|
||||
"Operations": [
|
||||
"WriteMemory",
|
||||
"VmOperation",
|
||||
"SetThreadContext",
|
||||
],
|
||||
"OperationMatch": "All",
|
||||
"MinimumRiskScore": 90,
|
||||
"HandleTypes": [
|
||||
"Create",
|
||||
"Duplicate",
|
||||
],
|
||||
"ObjectTypes": [
|
||||
"Process",
|
||||
],
|
||||
"Priority": 170,
|
||||
},
|
||||
{
|
||||
"Name": "Self_Antivirus_Protect_File",
|
||||
"Code": 2001,
|
||||
@@ -352,8 +208,6 @@
|
||||
"Category": "File",
|
||||
"InitiatorExclude": [
|
||||
"*\\PYAS.exe",
|
||||
"*\\PYAS_Setup.exe",
|
||||
"*\\unins000.exe",
|
||||
"*\\notepad*.exe",
|
||||
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\Temp\\*\\PYAS_Setup.tmp",
|
||||
"\\Device\\HarddiskVolume*\\Users\\*\\AppData\\Local\\Temp\\*\\_unins.tmp",
|
||||
@@ -392,6 +246,7 @@
|
||||
"InitiatorExclude": [
|
||||
"*\\PYAS.exe",
|
||||
"*\\Huorong\\Sysdiag\\bin\\sysclean.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\explorer.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\SearchIndexer.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\lsass.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\svchost.exe",
|
||||
@@ -399,6 +254,7 @@
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\taskhostw.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\TrustedInstaller.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\WinSxS\\*\\TiWorker.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\UUS\\amd64\\wuaucltcore.exe",
|
||||
"\\Device\\HarddiskVolume*\\$WinREAgent\\Scratch\\*\\DismHost.exe",
|
||||
],
|
||||
"Target": [
|
||||
@@ -551,7 +407,8 @@
|
||||
"*\\ventoy\\Boot\\*",
|
||||
"*\\AdminRegionConfig.*",
|
||||
"*\\nt_qq\\nt_*\\*",
|
||||
"\\Device\\HarddiskVolume*\\Users\\*\\Documents\\Tencent Files\\*\\nt_qq\\nt_*\\*",
|
||||
"*\\nt_qq\\global\\nt_*\\*",
|
||||
"\\Device\\HarddiskVolume*\\Users\\*\\Documents\\Tencent Files\\*",
|
||||
],
|
||||
"Extensions": [
|
||||
".zip",
|
||||
@@ -590,7 +447,7 @@
|
||||
"Delete",
|
||||
"Rename",
|
||||
],
|
||||
"Threshold": 5,
|
||||
"Threshold": 10,
|
||||
"TimeWindow": 3000,
|
||||
},
|
||||
{
|
||||
@@ -602,11 +459,13 @@
|
||||
"*\\PYAS.exe",
|
||||
"*\\rufus-*.exe",
|
||||
"*\\DiskInfo*.exe",
|
||||
"\\Device\\HarddiskVolume*\\Program Files\\*\\launcher\\ca_launcher.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\diskpart.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\diskmgmt.msc",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\taskhostw.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\vds.exe",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\format.com",
|
||||
"\\Device\\HarddiskVolume*\\Windows\\System32\\WinSAT.exe",
|
||||
],
|
||||
"Operations": [
|
||||
"Ioctl",
|
||||
@@ -639,8 +498,6 @@
|
||||
"*\\DefaultPassword",
|
||||
"*\\AltDefaultUserName",
|
||||
"*\\AltDefaultPassword",
|
||||
"*\\LegalNoticeCaption",
|
||||
"*\\LegalNoticeText",
|
||||
"*\\AutoReboot",
|
||||
"*\\DisableAutomaticRestartOnFailure",
|
||||
"*\\SystemBiosVersion",
|
||||
@@ -728,7 +585,6 @@
|
||||
"*\\SystemStartOptions",
|
||||
"*\\Userinit",
|
||||
"*\\UIHost",
|
||||
"*\\Debugger",
|
||||
"*\\NoControlPanel",
|
||||
"*\\NoDrives",
|
||||
"*\\NoFileMenu",
|
||||
@@ -823,6 +679,7 @@
|
||||
"*\\Sources\\SetupHost.exe",
|
||||
"*\\Work\\*\\DismHost.exe",
|
||||
"*\\Windows\\UUS\\amd64\\MoUsoCoreWorker.exe",
|
||||
"*\\Windows\\UUS\\Packages\\Preview\\amd64\\MoUsoCoreWorker.exe",
|
||||
"*\\Windows\\System32\\MoUsoCoreWorker.exe",
|
||||
"*\\Windows\\System32\\Sysprep\\sysprep.exe",
|
||||
"*\\Windows\\System32\\oobe\\*",
|
||||
@@ -855,4 +712,4 @@
|
||||
"Priority": 175,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user