Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: "Disable always running antimalware service" is wrong. #393

Open
femdiya opened this issue Jul 31, 2024 · 7 comments
Open

[Bug]: "Disable always running antimalware service" is wrong. #393

femdiya opened this issue Jul 31, 2024 · 7 comments
Labels
bug Something isn't working

Comments

@femdiya
Copy link

femdiya commented Jul 31, 2024

Description

:: ----------------------------------------------------------
:: --------Disable always running antimalware service--------
:: ----------------------------------------------------------
echo --- Disable always running antimalware service
PowerShell -ExecutionPolicy Unrestricted -Command "reg add 'HKLM\Software\Policies\Microsoft\Windows Defender' /v 'ServiceKeepAlive' /t 'REG_DWORD' /d '1' /f"
:: ----------------------------------------------------------

This is the code used on the website "privacy.sexy"
Which is in fact, wrong.
The correct value for 'ServiceKeepAlive' should be '0' as documented here:
Group policy template

If you enable this setting, the antimalware service will always remain running even if both antivirus and antispyware security intelligence is disabled. (1)

If you disable or do not configure this setting, the antimalware service will be stopped when both antivirus and antispyware security intelligence is disabled. If the computer is restarted, the service will be started if it is set to Automatic startup. After the service has started, there will be a check to see if antivirus and antispyware security intelligence is enabled. If at least one is enabled, the service will remain running. If both are disabled, the service will be stopped. (0)

How can the bug be recreated?

Script error
(GPT made this)

  1. Operating System: This script affects Windows users.
  2. Script Error: Running the original script will incorrectly set the ServiceKeepAlive registry value to 1, which keeps the antimalware service running.
  3. Steps to Recreate:
    • Run the original script with administrator privileges on a Windows machine.
    • Check the registry value for HKLM\Software\Policies\Microsoft\Windows Defender\ServiceKeepAlive using the Registry Editor or by running the command: reg query "HKLM\Software\Policies\Microsoft\Windows Defender" /v "ServiceKeepAlive".
    • Verify that the value is set to 1, which contradicts the intended behavior of disabling the service.
  4. Correct Value: The corrected script sets the ServiceKeepAlive value to 0, which stops the service when both antivirus and antispyware security intelligence are disabled.

Operating system

This script affects Windows users.

Script file

https://gist.github.com/femdiya/dd9c4628cd0261e65f09d586801fa8a0

Screenshots

No response

Additional information

The data for the value 'ServiceKeepAlive' should be '0', not '1'. (In order to disable antimalware service, as promised in title of the script)

@femdiya femdiya added the bug Something isn't working label Jul 31, 2024
@femdiya femdiya changed the title [Bug]: "Disable always running antimalware service" is wrong [Bug]: "Disable always running antimalware service" is wrong. Aug 1, 2024
@femdiya
Copy link
Author

femdiya commented Aug 1, 2024

Update:
I'm working on a big issue (not a PR, sorry, I don't know how to code) and I'd like this script to be added into the project too (I didn't include this in that issue):

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Microsoft Antimalware]
"ServiceKeepAlive"=dword:00000000

And with the powershell command:
PowerShell -ExecutionPolicy Unrestricted -Command "reg add 'HKLM\SOFTWARE\Policies\Microsoft\Microsoft Antimalware' /v 'ServiceKeepAlive' /t 'REG_DWORD' /d '0' /f"
Also here's the reference:
Group policy catalog
@undergroundwires

@undergroundwires
Copy link
Owner

You are completely right. It's a bug. These are great contributions, same value as PRs. Thank you a lot.
This will be fixed.

I'm stuck with two more keys, both are highly undocumented:

IsServiceRunning:

It is at HKLM\SOFTWARE\Microsoft\Windows Defender.

Seems like value 0 mean it's Running and value 1 means its Off.

I may be wrong, please check:

ServiceStartStates:

It is also at HKLM\SOFTWARE\Microsoft\Windows Defender:

See WindowsPhoneInfo forums.

This guide tells it to set it to 1.


Modifying this keys are hard and require TrustedInstaller privileges, I generate these from privacy.sexy for testing:

Set `IsServiceRunning` to `1`
PowerShell -ExecutionPolicy Unrestricted -Command "$command = '    reg add "^""HKLM\SOFTWARE\Microsoft\Windows Defender"^"" /v "^""IsServiceRunning"^"" /t "^""REG_DWORD"^"" /d "^""1"^"" /f'; $trustedInstallerSid = [System.Security.Principal.SecurityIdentifier]::new('S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464'); $trustedInstallerName = $trustedInstallerSid.Translate([System.Security.Principal.NTAccount]); $streamOutFile = New-TemporaryFile; $batchFile = New-TemporaryFile; try {; $batchFile = Rename-Item $batchFile "^""$($batchFile.BaseName).bat"^"" -PassThru; "^""@echo off`r`n$command`r`nexit 0"^"" | Out-File $batchFile -Encoding ASCII; $taskName = 'privacy.sexy invoke'; schtasks.exe /delete /tn "^""$taskName"^"" /f 2>&1 | Out-Null <# Clean if something went wrong before, suppress any output #>; $taskAction = New-ScheduledTaskAction -Execute 'cmd.exe' -Argument "^""cmd /c `"^""$batchFile`"^"" > $streamOutFile 2>&1"^""; $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries; Register-ScheduledTask -TaskName $taskName -Action $taskAction -Settings $settings -Force -ErrorAction Stop | Out-Null; try {; ($scheduleService = New-Object -ComObject Schedule.Service).Connect(); $scheduleService.GetFolder('\').GetTask($taskName).RunEx($null, 0, 0, $trustedInstallerName) | Out-Null; $timeOutLimit = (Get-Date).AddMinutes(5); Write-Host "^""Running as $trustedInstallerName"^""; while((Get-ScheduledTaskInfo $taskName).LastTaskResult -eq 267009) {; Start-Sleep -Milliseconds 200; if((Get-Date) -gt $timeOutLimit) {; Write-Warning "^""Skipping results, it took so long to execute script."^""; break;; }; }; if (($result = (Get-ScheduledTaskInfo $taskName).LastTaskResult) -ne 0) {; Write-Error "^""Failed to execute with exit code: $result."^""; }; } finally {; schtasks.exe /delete /tn "^""$taskName"^"" /f | Out-Null <# Outputs only errors #>; }; Get-Content $streamOutFile; } finally {; Remove-Item $streamOutFile, $batchFile; }"
Set `IsServiceRunning` to `0`
PowerShell -ExecutionPolicy Unrestricted -Command "$command = '    reg add "^""HKLM\SOFTWARE\Microsoft\Windows Defender"^"" /v "^""IsServiceRunning"^"" /t "^""REG_DWORD"^"" /d "^""0"^"" /f'; $trustedInstallerSid = [System.Security.Principal.SecurityIdentifier]::new('S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464'); $trustedInstallerName = $trustedInstallerSid.Translate([System.Security.Principal.NTAccount]); $streamOutFile = New-TemporaryFile; $batchFile = New-TemporaryFile; try {; $batchFile = Rename-Item $batchFile "^""$($batchFile.BaseName).bat"^"" -PassThru; "^""@echo off`r`n$command`r`nexit 0"^"" | Out-File $batchFile -Encoding ASCII; $taskName = 'privacy.sexy invoke'; schtasks.exe /delete /tn "^""$taskName"^"" /f 2>&1 | Out-Null <# Clean if something went wrong before, suppress any output #>; $taskAction = New-ScheduledTaskAction -Execute 'cmd.exe' -Argument "^""cmd /c `"^""$batchFile`"^"" > $streamOutFile 2>&1"^""; $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries; Register-ScheduledTask -TaskName $taskName -Action $taskAction -Settings $settings -Force -ErrorAction Stop | Out-Null; try {; ($scheduleService = New-Object -ComObject Schedule.Service).Connect(); $scheduleService.GetFolder('\').GetTask($taskName).RunEx($null, 0, 0, $trustedInstallerName) | Out-Null; $timeOutLimit = (Get-Date).AddMinutes(5); Write-Host "^""Running as $trustedInstallerName"^""; while((Get-ScheduledTaskInfo $taskName).LastTaskResult -eq 267009) {; Start-Sleep -Milliseconds 200; if((Get-Date) -gt $timeOutLimit) {; Write-Warning "^""Skipping results, it took so long to execute script."^""; break;; }; }; if (($result = (Get-ScheduledTaskInfo $taskName).LastTaskResult) -ne 0) {; Write-Error "^""Failed to execute with exit code: $result."^""; }; } finally {; schtasks.exe /delete /tn "^""$taskName"^"" /f | Out-Null <# Outputs only errors #>; }; Get-Content $streamOutFile; } finally {; Remove-Item $streamOutFile, $batchFile; }"
Set `ServiceStartStates` to `1`
PowerShell -ExecutionPolicy Unrestricted -Command "$command = '    reg add "^""HKLM\SOFTWARE\Microsoft\Windows Defender"^"" /v "^""ServiceStartStates"^"" /t "^""REG_DWORD"^"" /d "^""1"^"" /f'; $trustedInstallerSid = [System.Security.Principal.SecurityIdentifier]::new('S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464'); $trustedInstallerName = $trustedInstallerSid.Translate([System.Security.Principal.NTAccount]); $streamOutFile = New-TemporaryFile; $batchFile = New-TemporaryFile; try {; $batchFile = Rename-Item $batchFile "^""$($batchFile.BaseName).bat"^"" -PassThru; "^""@echo off`r`n$command`r`nexit 0"^"" | Out-File $batchFile -Encoding ASCII; $taskName = 'privacy.sexy invoke'; schtasks.exe /delete /tn "^""$taskName"^"" /f 2>&1 | Out-Null <# Clean if something went wrong before, suppress any output #>; $taskAction = New-ScheduledTaskAction -Execute 'cmd.exe' -Argument "^""cmd /c `"^""$batchFile`"^"" > $streamOutFile 2>&1"^""; $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries; Register-ScheduledTask -TaskName $taskName -Action $taskAction -Settings $settings -Force -ErrorAction Stop | Out-Null; try {; ($scheduleService = New-Object -ComObject Schedule.Service).Connect(); $scheduleService.GetFolder('\').GetTask($taskName).RunEx($null, 0, 0, $trustedInstallerName) | Out-Null; $timeOutLimit = (Get-Date).AddMinutes(5); Write-Host "^""Running as $trustedInstallerName"^""; while((Get-ScheduledTaskInfo $taskName).LastTaskResult -eq 267009) {; Start-Sleep -Milliseconds 200; if((Get-Date) -gt $timeOutLimit) {; Write-Warning "^""Skipping results, it took so long to execute script."^""; break;; }; }; if (($result = (Get-ScheduledTaskInfo $taskName).LastTaskResult) -ne 0) {; Write-Error "^""Failed to execute with exit code: $result."^""; }; } finally {; schtasks.exe /delete /tn "^""$taskName"^"" /f | Out-Null <# Outputs only errors #>; }; Get-Content $streamOutFile; } finally {; Remove-Item $streamOutFile, $batchFile; }"
Set `ServiceStartStates` to `0`
  PowerShell -ExecutionPolicy Unrestricted -Command "$command = '    reg add "^""HKLM\SOFTWARE\Microsoft\Windows Defender"^"" /v "^""ServiceStartStates"^"" /t "^""REG_DWORD"^"" /d "^""0"^"" /f'; $trustedInstallerSid = [System.Security.Principal.SecurityIdentifier]::new('S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464'); $trustedInstallerName = $trustedInstallerSid.Translate([System.Security.Principal.NTAccount]); $streamOutFile = New-TemporaryFile; $batchFile = New-TemporaryFile; try {; $batchFile = Rename-Item $batchFile "^""$($batchFile.BaseName).bat"^"" -PassThru; "^""@echo off`r`n$command`r`nexit 0"^"" | Out-File $batchFile -Encoding ASCII; $taskName = 'privacy.sexy invoke'; schtasks.exe /delete /tn "^""$taskName"^"" /f 2>&1 | Out-Null <# Clean if something went wrong before, suppress any output #>; $taskAction = New-ScheduledTaskAction -Execute 'cmd.exe' -Argument "^""cmd /c `"^""$batchFile`"^"" > $streamOutFile 2>&1"^""; $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries; Register-ScheduledTask -TaskName $taskName -Action $taskAction -Settings $settings -Force -ErrorAction Stop | Out-Null; try {; ($scheduleService = New-Object -ComObject Schedule.Service).Connect(); $scheduleService.GetFolder('\').GetTask($taskName).RunEx($null, 0, 0, $trustedInstallerName) | Out-Null; $timeOutLimit = (Get-Date).AddMinutes(5); Write-Host "^""Running as $trustedInstallerName"^""; while((Get-ScheduledTaskInfo $taskName).LastTaskResult -eq 267009) {; Start-Sleep -Milliseconds 200; if((Get-Date) -gt $timeOutLimit) {; Write-Warning "^""Skipping results, it took so long to execute script."^""; break;; }; }; if (($result = (Get-ScheduledTaskInfo $taskName).LastTaskResult) -ne 0) {; Write-Error "^""Failed to execute with exit code: $result."^""; }; } finally {; schtasks.exe /delete /tn "^""$taskName"^"" /f | Out-Null <# Outputs only errors #>; }; Get-Content $streamOutFile; } finally {; Remove-Item $streamOutFile, $batchFile; }"

They seem to be represent the state of MsMpEng.exe. I guess they're deleted by Defender during shutdown because I do not have these keys.

When I search these keys, I see some projects setting them as 1 to disable Defender.

I could not understand exactly which number is representing what because usually 0 means disabled/negative but here 0 seems to represent running state. In that case, why would we set this serve in "not running" state? Isn't it better to set it in "running" state so it does not get re-run?

I need some help with investigation/testing.

What do you suggest we do with those @femdiya ?

Alternative I. Set to 1 as some tell
Alternative II. Set to 0
Alternative III. Exclude them from privacy.sexy completely

@femdiya
Copy link
Author

femdiya commented Aug 3, 2024

@undergroundwires
Sorry I just saw your message,
I think that "IsServiceRunning" and "ServiceStartStates" are somehow related to Event ID 5007 (Sorry if I'm not useful, I'm trying)
Microsoft documentation
A website noting that Event ID 5007 is related to config changes
Might wanna check this user on malwarebytes forum

Update: Now I get it:
Microsoft Community II
This reference you gave me, user "AeiZii" answered that "IsServiceRunning" is related to showing that whatever Windows Defender Service is running or not, and Event ID 5007 just shows the change that happened automatically in defenders configurations -by windows defender ofc-.

Secondly, I personally think (and from a human-readablity point), "IsServiceRunning" "0" means it's not running, "1" means it's running. (I can confirm this behavior on my main system which defender is enabled and the value is "1")

Third, I used Windows Sandbox to confirm this behavior, some things to consider:

  1. Windows defender is not present in Windows Sandbox at all. Which means there are only leftover keys and static keys left in system. (Static = not changes by the subject, for example I call the IsServiceRunning a dynamic key, because it changes by the subject)
  2. I did not find ServiceStartStates neither on my machine, and on the Sandbox.
  3. I found IsServiceRunning on my machine (with Defender enabled) and the status was "1" and I can confirm Windows Defender Services running on the background. IsServiceRunning was not found on Windows Sandbox (With defender ripped completely)

For my thoughts on "other projects setting this value to 0", I need more resources confirming that they do such thing.
All I saw was "This guide" mentioned by you, which to me, was some cheap copy-paste that websites use to increase their rank in search engines SEO. (And most importantly, advertise their product) Sorry, I personally don't think this is enough evidence.

And for the next part, I asked GPT about what does this value do:

-------------------------
IsServiceRunning
-------------------------

The IsServiceRunning registry key found at HKLM\SOFTWARE\Microsoft\Windows Defender in the Windows Registry is a part of the configuration settings for Windows Defender, the built-in antivirus and anti-malware tool in Windows operating systems.

Detailed Information about IsServiceRunning

Purpose:

The IsServiceRunning registry key is used to indicate the operational status of the Windows Defender service (WinDefend). This service is responsible for providing real-time protection against viruses, malware, and other security threats.

Location:

The key is located in the Windows Registry at:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender

Data Type:

The IsServiceRunning key is a DWORD (32-bit) value.

Possible Values:

  • 0: This value means that the Windows Defender service is not running.
  • 1: This value means that the Windows Defender service is currently running.

Functionality:

  • Real-time Protection: When the IsServiceRunning key is set to 1, it means that the Windows Defender service is actively running and providing real-time protection against security threats. This includes monitoring files, processes, and network activity for malicious behavior.
  • Inactive State: When the IsServiceRunning key is set to 0, the Windows Defender service is inactive. In this state, real-time protection and other active scanning features are not available, and the system may be vulnerable to security threats.

How IsServiceRunning Works

  1. Service Control:

    • The state of IsServiceRunning is controlled by the Windows Service Control Manager (SCM), which starts and stops the Windows Defender service based on system configuration and user settings.
  2. Integration with Windows Security Center:

    • The status indicated by IsServiceRunning is used by the Windows Security Center to inform users about the state of their antivirus protection. If the service is not running (IsServiceRunning is 0), the Security Center may alert the user that their system is unprotected.
  3. Script and Programmatic Access:

    • Administrators and security tools can query this registry key to programmatically determine the status of Windows Defender. This can be done using scripting languages like PowerShell, or programmatically through Windows API calls.

Example Usage:

  • Checking Status with PowerShell:

    $defenderStatus = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Defender" -Name "IsServiceRunning"
    if ($defenderStatus.IsServiceRunning -eq 1) {
        Write-Output "Windows Defender is running."
    } else {
        Write-Output "Windows Defender is not running."
    }
  • Modifying the Status:
    Modifying the IsServiceRunning key directly in the registry to start or stop the service is not recommended because proper service management should be done through the Windows Service Control Manager or using appropriate system tools. However, administrators can start or stop the Windows Defender service using commands like:

    net start WinDefend  // To start the service
    net stop WinDefend   // To stop the service

Implications of Modifying IsServiceRunning

  • System Security: Incorrectly modifying the IsServiceRunning key or stopping the Windows Defender service can leave the system vulnerable to security threats.
  • Compatibility: Some third-party security software may require disabling Windows Defender. In such cases, the service status can be managed to avoid conflicts, but it should be done following best practices and with appropriate tools.

Best Practices

  • Regular Monitoring: Regularly check the status of Windows Defender to ensure it is running and providing protection.
  • Automated Scripts: Use scripts to automate the monitoring and management of Windows Defender status, ensuring it is enabled and running as required.
  • Security Policies: Implement security policies that prevent unauthorized changes to the Windows Defender service status, maintaining system integrity and protection.

The IsServiceRunning registry key is a critical indicator of the operational status of Windows Defender, helping ensure the system remains protected against various security threats.

-------------------------
ServiceStartStates
-------------------------

The ServiceStartStates registry value is part of the configuration for Windows Defender, located at HKLM\SOFTWARE\Microsoft\Windows Defender. This value provides information about the startup states of the Windows Defender service.

Detailed Information about ServiceStartStates

Purpose:

The ServiceStartStates registry value tracks the states of the Windows Defender service during system startup. It can help administrators understand how the service is configured to start and if there were any issues during the startup process.

Location:

The key is located in the Windows Registry at:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender

Data Type:

The ServiceStartStates key is a DWORD (32-bit) value.

Possible Values:

The specific values for ServiceStartStates are not explicitly documented by Microsoft, but it typically reflects a bitmask representing different states related to the service's startup. Common values might include:

  • 0: Service is disabled or not configured to start.
  • 1: Service is set to start automatically.
  • 2: Service is set to start manually.
  • 4: Service encountered an error during startup.

The values can be combined, as the bitmask might reflect multiple states or flags.

How ServiceStartStates Works

  1. Startup Configuration:

    • The ServiceStartStates value reflects how the Windows Defender service (WinDefend) is configured to start. This includes settings from the Service Control Manager (SCM) and any startup flags set by the system or administrators.
  2. Tracking Startup Issues:

    • If there are issues during the startup process, such as failures or delays, these might be reflected in the ServiceStartStates value. This helps in troubleshooting startup problems with the Windows Defender service.
  3. Integration with System Tools:

    • System tools and administrative scripts can query this value to understand the startup configuration and any issues related to the Windows Defender service.

Example Usage:

  • Checking Status with PowerShell:

    $defenderStartState = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Defender" -Name "ServiceStartStates"
    Write-Output "Windows Defender ServiceStartStates: $($defenderStartState.ServiceStartStates)"
  • Interpreting Values:
    Since the specific bitmask values for ServiceStartStates are not well-documented, interpreting the exact meaning requires understanding typical Windows service startup flags and states.

Implications of Modifying ServiceStartStates

  • System Stability: Modifying the ServiceStartStates directly in the registry is not recommended, as it can affect the startup behavior and stability of the Windows Defender service.
  • Startup Configuration: Properly configure the Windows Defender service startup settings through system management tools, such as the Services console (services.msc), rather than modifying the registry directly.

Best Practices

  • Regular Monitoring: Regularly check the ServiceStartStates value to ensure the Windows Defender service is configured correctly and starts as expected.
  • Automated Scripts: Use scripts to automate the monitoring of Windows Defender startup states, ensuring any issues are promptly detected and addressed.
  • Security Policies: Implement security policies that prevent unauthorized changes to the Windows Defender service configuration, maintaining system integrity and protection.

Summary

The ServiceStartStates registry value provides important information about the startup configuration and states of the Windows Defender service. By monitoring this value, administrators can ensure the service is configured correctly, detect startup issues, and maintain overall system security and stability.

Then I asked GPT about why there's no "3" data? (Which is a stupid question, sorry)
They answered this:

You're right to question the possible values, and my initial response may have oversimplified the potential values for the ServiceStartStates key. The specific bitmask values for ServiceStartStates can indeed include combinations of bits that go beyond simple integers like 0, 1, 2, and 4.

The ServiceStartStates key reflects a bitmask, meaning that each bit represents a different state or flag. Here's a more detailed breakdown of the possible values and combinations:

Possible Values and Combinations

  1. 0x0 (0): No special conditions; the service is not running or is disabled.
  2. 0x1 (1): The service is set to start automatically.
  3. 0x2 (2): The service is set to start manually.
  4. 0x4 (4): The service encountered an error during startup.
  5. 0x3 (3): Combination of 0x1 and 0x2, meaning the service has properties of both automatic and manual start (though this combination is rare and might be more indicative of a configuration or reporting anomaly).
  6. Other combinations: Bitmasks can represent more complex states if more flags are used in the future.

Understanding the Bitmask

The bitmask is a way to represent multiple boolean states in a single integer value. Here’s a conceptual example of how these might be interpreted:

  • Bit 0 (0x1): Indicates whether the service is set to start automatically.
  • Bit 1 (0x2): Indicates whether the service is set to start manually.
  • Bit 2 (0x4): Indicates whether the service encountered an error during startup.

In a bitmask:

  • 0x0 means none of these conditions are true.
  • 0x1 means only the first condition is true (auto start).
  • 0x2 means only the second condition is true (manual start).
  • 0x4 means only the third condition is true (error on startup).
  • 0x3 means both the first and second conditions are true (which might indicate a configuration or logical issue).

Checking Values with PowerShell

Here's an updated PowerShell example to interpret these values more comprehensively:

$defenderStartState = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Defender" -Name "ServiceStartStates"
$startState = $defenderStartState.ServiceStartStates

switch ($startState) {
    0 { Write-Output "No special conditions; the service is not running or is disabled." }
    1 { Write-Output "The service is set to start automatically." }
    2 { Write-Output "The service is set to start manually." }
    3 { Write-Output "The service is set to start both automatically and manually (configuration anomaly)." }
    4 { Write-Output "The service encountered an error during startup." }
    default { Write-Output "Unknown state: $startState" }
}

Conclusion

The values for ServiceStartStates are indeed more complex than just 0, 1, 2, and 4. The bitmask can represent various states, including combinations of these states. It’s essential to interpret the bitmask correctly to understand the exact startup conditions and issues related to the Windows Defender service.

My final thoughts:

  1. IsServiceRunning is a key used by Windows Service Manager (?) to check and report that is WinDefend¹ running or not. If key to this value is "0", Service Manager reports to user (and possibly apps and games) that Windows Defender is disabled, Opposite goes for if the key is set to "1". However, this can be abused (one scenario is that if user is unaware of what are they doing):
    1.1. WinDefend (Or Windows Defender in general
    ¹, see below) IS ENABLED and user/privacy.sexy changes this value to report DISABLED.
    1.2. WinDefend (Or Windows Defender in general*¹, see below) IS DISABLED and user/privacy.sexy changes this value to report ENABLED.

1.3. And from what I saw from users on forums, this key is dynamic and will be changed by Windows Defender when some actions are triggered (like scanning), And in order to report the correct status of "WinDefend" (?)*¹ service and/or Windows Defender status in general.

(I'll say my personal choice of whatever these keys should be added to the script or not after this)

  1. ServiceStartStates is reflecting (?) Windows Defender service (WinDefend) and/or Windows Defender "startup status" (?) in general. Mostly (and probably) used by IT Managers and developers to check the startup status. Proper configurations is done by editing startup values of the "service(s)" (?)¹. This value can be abused too (one scenario is that if user is unaware of what are they doing):
    2.1. WinDefend (Or Windows Defender in general
    ¹, see below) is set to disabled startup type, but this value is set to "1" which means automatic startup type.

IMPORTANT!
*¹: More research (and test) should be done in order to see which services/components these values (ServiceStartStates and IsServiceRunning) have impact on/have connection with. Current information shows that these values have connections with "WinDefend" service, although I'm not very "sure" about that..

  1. Final thoughts and best possible solutions.
    Clearly, our information is very limited and we're relying only on GPT and user experience (which can include errors and mistakes).
    There's no proper documentation whatsoever, if we're about to reference users to what these values and keys do in future, we should redirect them to this issue ([Bug]: "Disable always running antimalware service" is wrong. #393).

We also have so many choices of whatever we should add them to the privacy.sexy or not:

First option, we can add both, under "Advanced/Not-recommended" classification. Give them static keys of "example. ServiceStartStates=0 and IsServiceRunning=0" and other possible revert configurations based on (limited) information we have. I don't recommend this because of the fact we're so low on intel on how to actually get to work with these both keys.

Second option, we can add these under another script (Merge these values with another related script). For example, after confirming that these values only affect "WinDefend", we can add the both values under the "Disable "Microsoft Defender Antivirus Service"" script in privacy.sexy. Which sounds ideal, but there are some things are to consider. For example we have to first confirm that these values only affect "WinDefend" service and nothing more.

Third option, we can complete our (possible) tests and documentation, and decide for what's next. Add them in a completely different script, Merge them with other scripts, Or even decide to not add them at all due to conflict and...

Wrapping up:
Based on our current information ServiceStartStates is only a informational value and most likely to cause more problems than solve, I recommend leaving this to the system. Current intel shows that Windows automatically changes this value to the subject, which the proper way to actually make this script have effect, is to use it together with some other script(s) that config correct system services/components, which first, we have to confirm that this value even have any connection with those services/components (as otherwise, can cause incompatibility due to not being adapted correctly).
IsServiceRunning on the other hand, can be useful, for reporting Windows Defenders status to apps, games, users and..
This can be useful and I think we can make a good use of it. Same as above, current intel shows that this is a dynamic value too, Windows will change it automatically. The only correct way is to use it with correct scripts.

The only correct way to decide what to do next, is proper documentations and possibly tests (if needed).

All information I've provided is limited and my conclusions are highly limited too, with proper documentation and (perhaps) tests, we can provide better solutions.

Sorry for poor English.

@undergroundwires
Copy link
Owner

Thank you for the research.

Another article is this one which seems to be copy paste of the same thing as you figured out. There are bunch of copies of this article on very low reputable sources.

ServiceStartStates is only handled by MpSvc.dll and MpClient.dll based on DLL exports. This post shows that it's set to 0 during Avast scan then back to 1 when the scan was completed. This maybe useful because if this set is set 0 when a third-party AV is detected (when Defender gets disabled by OS) then it is useful.

Similarly, IsServiceRunning is also handled by MpClient.dll and MpSvc.dll.

Interestingly MpSvc.dll has this string: Failed to delete IsServiceRunning. This might cause false positive dirty service shutdown warning., source. This is valuable information coming from Microsot DLL. So this value is supposed to be deleted on system shutdown and read on system boot. Community discussions above show that this is also modified during Defender updates.

Either personal tests or docs. We do not have the doc and seems that we're doing the first research on these. As you verify that running state is 1, I also agree 1 must be running state.

I think a good test would be, disabling Defender by official way which is installing a third-party antivirus, for example Avast. Then watch how values of these keys are changing.

@femdiya
Copy link
Author

femdiya commented Aug 4, 2024

Thanks for the response.
First:

Another article is this one which seems to be copy paste of the same thing as you figured out. There are bunch of copies of this article on very low reputable sources.

No, I don't use these cheap copy-paste articles which they only serve to boost the website reputation and make money for the website.

Moving on.

And to mention that, I have no comments on how-to test this value.

So, looks like you found out more things that connect to those 2 values, really interesting.
Assuming that your research is enough evidence to prove connection between those values and Defender itself, I have 0 knowledge about what these .dll files are, and what are they connected to. I'm sure you know pretty much about .dll's, so maybe check that out?

From what I see, I think that those .dll's are related to Windows Defender and all of it's services. Please check out #402 , SIDE NOTE 2 at additional information about my suggestions to disable new defender services.

Best practice should be, creating a whole "Disable All Windows Defender Services" script, using my suggestions and current codes in the project (and further more research about all Windows Defender services), and finally, adding those two values (+ some tweaks, -hat im not sure about, to remove/unload those functions from those .dll's) with correct data and configuration, and test it on a clean Windows installation, and confirm within Event Viewer.

@undergroundwires
Copy link
Owner

I installed third-party antivirus (Avast) and see the following changes:

Windows 11 23H2:

Key Initial data After antivirus
IsServiceRunning 1 1
ServiceStartStates Missing Missing

Windows 10 23H2:

Key Initial data After antivirus
IsServiceRunning Missing Missing
ServiceStartStates Missing Missing

I will still include setting 0 values for this in privacy.sexy.

@femdiya
Copy link
Author

femdiya commented Sep 14, 2024

I installed third-party antivirus (Avast) and see the following changes:

Windows 11 23H2:
Key Initial data After antivirus
IsServiceRunning 1 1
ServiceStartStates Missing Missing

Uhhh, Avast?
Did the Avast itself disable the Defender? (as all AV's do)

undergroundwires added a commit that referenced this issue Oct 29, 2024
This commit adds disabling missing low-level Defender service/drivers,
improve disabling existing ones, and improve their documentation.

Key changes:

- Add disabling missing Defender services.
- Add disabling missing Defender processes.
- Add soft-deleting of missing service files
- Fix `ServiceKeepAlive` value #393, #426
- Add disabling system modification restrictions for persistent Disable
  service disabling.
- Recommend more Defender scripts on 'Strict' level

Other supporting changes:

- Add more documentation for related scripts.
- Move disabling `SecHealthUI` to disabling Windows Security.
- Fix `DisableService` attempting to disable the service even though its
  disabled.
- Add ability to disable service on revert in
  `DisableServiceInRegistry`.
- Improve categorization for simplicity, add new categories for new
  scripts.
- Add ability to run `DeleteRegistryValue` as `TrustedInstaller`.
- Rename some scripts/categories for simplicity and clarity.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants