From a11a1fe7b68b8cbbb377b6f17f9773ead62668ac Mon Sep 17 00:00:00 2001 From: es3n1n Date: Tue, 20 May 2025 11:58:22 +0900 Subject: [PATCH 1/7] feat(installer): add powershell installer --- README.md | 36 ++++++++++++++++++++++++++++------ install.ps1 | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 install.ps1 diff --git a/README.md b/README.md index b451b76..be96dbe 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,29 @@ Defendnot is a successor of [no-defender](https://github.com/es3n1n/no-defender) ![](https://i.imgur.com/VGE8g6a.jpeg) -## How it works +## Installation -There's a WSC (Windows Security Center) service in Windows which is used by antiviruses to let Windows know that there's some other antivirus in the hood and it should disable Windows Defender. -This WSC API is undocumented and furthermore requires people to sign an NDA with Microsoft to get its documentation. +### One-liner -The initial implementation of [no-defender](https://github.com/es3n1n/no-defender) used thirdparty code provided by other AVs to register itself in the WSC, while defendnot interacts with WSC directly. +Open the powershell as administrator and execute any of these: -## Limitations +```powershell +# Example 1: Basic installation +irm https://es3n1n.io/defendnot.ps1 | iex -Sadly, to keep this WSC stuff even after reboot, defendnot adds itself to the autorun. Thus, you would need to keep the defendnot binaries on your disk :( +# Example 2: With custom AV name +irm https://es3n1n.io/defendnot.ps1 | iex --name "Custom AV name" + +# Example 3: Without allocating console +irm https://es3n1n.io/defendnot.ps1 | iex --silent +``` + +> [!NOTE] +> You can pass arguments to iex and installer script will forward your arguments to `defendnot-loader` as seen in examples 2 and 3. For reference what commandline arguments are allowed, see the `Usage` section below. + +### Manual + +Download the [latest](https://github.com/es3n1n/defendnot/releases/latest) release, extract it somewhere and launch `defendnot-loader`. ## Usage @@ -33,6 +46,17 @@ Optional arguments: --disable-autorun disable autorun task creation ``` +## How it works + +There's a WSC (Windows Security Center) service in Windows which is used by antiviruses to let Windows know that there's some other antivirus in the hood and it should disable Windows Defender. +This WSC API is undocumented and furthermore requires people to sign an NDA with Microsoft to get its documentation. + +The initial implementation of [no-defender](https://github.com/es3n1n/no-defender) used thirdparty code provided by other AVs to register itself in the WSC, while defendnot interacts with WSC directly. + +## Limitations + +Sadly, to keep this WSC stuff even after reboot, defendnot adds itself to the autorun. Thus, you would need to keep the defendnot binaries on your disk :( + ## Writeup [How I ruined my vacation by reverse engineering WSC](https://blog.es3n1n.eu/posts/how-i-ruined-my-vacation/) diff --git a/install.ps1 b/install.ps1 new file mode 100644 index 0000000..2eff870 --- /dev/null +++ b/install.ps1 @@ -0,0 +1,56 @@ +$ErrorActionPreference = "Stop" +$InstallPath = "$env:ProgramData\defendnot" + +switch -Wildcard ($env:PROCESSOR_ARCHITECTURE) { + "AMD64" { $arch = "x64" } + "x86" { $arch = "x86" } + "ARM64" { $arch = "ARM64" } + default { + Write-Error "Unknown architecture: $($env:PROCESSOR_ARCHITECTURE)" + exit 1 + } +} + +$repo = "es3n1n/defendnot" +$apiReleaseUrl = "https://api.github.com/repos/$repo/releases/latest" +$headers = @{ 'User-Agent'="defendnot-install/1.0" } + +try { + $release = Invoke-RestMethod -Uri $apiReleaseUrl -Headers $headers +} catch { + Write-Error "Failed to get latest release info: $_" + exit 2 +} + +$zipAsset = $release.assets | Where-Object { $_.name -ieq "$arch.zip" } +if (-not $zipAsset) { + Write-Error "Release does not contain asset for $arch" + exit 3 +} + +$zipUrl = $zipAsset.browser_download_url +$zipPath = Join-Path $env:TEMP "defendnot-$arch.zip" + +Write-Host "Downloading $($zipAsset.name)..." +Invoke-WebRequest -Uri $zipUrl -OutFile $zipPath + +If (!(Test-Path $InstallPath)) { + New-Item -Type Directory -Path $InstallPath -Force | Out-Null +} + +if (Test-Path $InstallPath) { + Write-Host "Removing previous installation..." + Remove-Item $InstallPath -Force -Recurse -ErrorAction SilentlyContinue +} + +New-Item -Type Directory -Path $InstallPath -ErrorAction SilentlyContinue | Out-Null + +Write-Host "Extracting to $InstallPath..." +Add-Type -AssemblyName System.IO.Compression.FileSystem +[System.IO.Compression.ZipFile]::ExtractToDirectory($zipPath, $InstallPath) +Remove-Item $zipPath + +Write-Host "`nDefendnot installed to $InstallPath" +Write-Host "Starting..." +Write-Host "Args: $args" +& "$InstallPath\defendnot-loader.exe" @args From 3bfc312587957bf8622484445ff0890b20a01e22 Mon Sep 17 00:00:00 2001 From: es3n1n Date: Tue, 20 May 2025 12:01:22 +0900 Subject: [PATCH 2/7] refactor(installer): minor installer cleanup --- README.md | 3 +++ install.ps1 | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index be96dbe..900d23d 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,9 @@ irm https://es3n1n.io/defendnot.ps1 | iex --silent > [!NOTE] > You can pass arguments to iex and installer script will forward your arguments to `defendnot-loader` as seen in examples 2 and 3. For reference what commandline arguments are allowed, see the `Usage` section below. +> [!NOTE] +> You can also directly use the 'longer' version of installer script url, which is `https://raw.githubusercontent.com/es3n1n/defendnot/refs/heads/master/install.ps1` + ### Manual Download the [latest](https://github.com/es3n1n/defendnot/releases/latest) release, extract it somewhere and launch `defendnot-loader`. diff --git a/install.ps1 b/install.ps1 index 2eff870..3ea7cbc 100644 --- a/install.ps1 +++ b/install.ps1 @@ -34,10 +34,6 @@ $zipPath = Join-Path $env:TEMP "defendnot-$arch.zip" Write-Host "Downloading $($zipAsset.name)..." Invoke-WebRequest -Uri $zipUrl -OutFile $zipPath -If (!(Test-Path $InstallPath)) { - New-Item -Type Directory -Path $InstallPath -Force | Out-Null -} - if (Test-Path $InstallPath) { Write-Host "Removing previous installation..." Remove-Item $InstallPath -Force -Recurse -ErrorAction SilentlyContinue From 3d969605fd575f76fb6057bcf59dd2cbfacab178 Mon Sep 17 00:00:00 2001 From: es3n1n Date: Tue, 20 May 2025 12:07:19 +0900 Subject: [PATCH 3/7] docs(readme): update advanced installer usage --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 900d23d..2c2f9d3 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ Open the powershell as administrator and execute any of these: irm https://es3n1n.io/defendnot.ps1 | iex # Example 2: With custom AV name -irm https://es3n1n.io/defendnot.ps1 | iex --name "Custom AV name" +& ([ScriptBlock]::Create((Invoke-RestMethod https://es3n1n.io/defendnot.ps1))) --name "Custom AV name" # Example 3: Without allocating console -irm https://es3n1n.io/defendnot.ps1 | iex --silent +& ([ScriptBlock]::Create((Invoke-RestMethod https://es3n1n.io/defendnot.ps1))) --silent ``` > [!NOTE] From bf9d21b626cb56d89a794619a1bc0bd61086d060 Mon Sep 17 00:00:00 2001 From: es3n1n Date: Tue, 20 May 2025 12:08:01 +0900 Subject: [PATCH 4/7] docs(readme): make advanced usage examples shorter --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2c2f9d3..7a986dc 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ Open the powershell as administrator and execute any of these: irm https://es3n1n.io/defendnot.ps1 | iex # Example 2: With custom AV name -& ([ScriptBlock]::Create((Invoke-RestMethod https://es3n1n.io/defendnot.ps1))) --name "Custom AV name" +& ([ScriptBlock]::Create((irm https://es3n1n.io/defendnot.ps1))) --name "Custom AV name" # Example 3: Without allocating console -& ([ScriptBlock]::Create((Invoke-RestMethod https://es3n1n.io/defendnot.ps1))) --silent +& ([ScriptBlock]::Create((irm https://es3n1n.io/defendnot.ps1))) --silent ``` > [!NOTE] From 897ed9c0eb98b8bcb8075d942f64bb7cf7f6840a Mon Sep 17 00:00:00 2001 From: es3n1n Date: Tue, 20 May 2025 12:09:56 +0900 Subject: [PATCH 5/7] docs(readme): update advanced usage notes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a986dc..9d41d96 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ irm https://es3n1n.io/defendnot.ps1 | iex ``` > [!NOTE] -> You can pass arguments to iex and installer script will forward your arguments to `defendnot-loader` as seen in examples 2 and 3. For reference what commandline arguments are allowed, see the `Usage` section below. +> As seen in examples 2 and 3 you can pass the commandline arguments to the installer script and it will forward them to `defendnot-loader`. For reference what commandline arguments are allowed, see the `Usage` section below. > [!NOTE] > You can also directly use the 'longer' version of installer script url, which is `https://raw.githubusercontent.com/es3n1n/defendnot/refs/heads/master/install.ps1` From 448b1ced981a2d6977e13bb2a70ea66e455f52b2 Mon Sep 17 00:00:00 2001 From: es3n1n Date: Tue, 20 May 2025 15:01:04 +0900 Subject: [PATCH 6/7] docs(readme): update installer script url --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9d41d96..afd605a 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,13 @@ Open the powershell as administrator and execute any of these: ```powershell # Example 1: Basic installation -irm https://es3n1n.io/defendnot.ps1 | iex +irm https://dnot.sh/ | iex # Example 2: With custom AV name -& ([ScriptBlock]::Create((irm https://es3n1n.io/defendnot.ps1))) --name "Custom AV name" +& ([ScriptBlock]::Create((irm https://dnot.sh/))) --name "Custom AV name" # Example 3: Without allocating console -& ([ScriptBlock]::Create((irm https://es3n1n.io/defendnot.ps1))) --silent +& ([ScriptBlock]::Create((irm https://dnot.sh/))) --silent ``` > [!NOTE] From c159dbe324bd88a9c3a92074e86c2ae37292c476 Mon Sep 17 00:00:00 2001 From: es3n1n Date: Tue, 20 May 2025 15:16:32 +0900 Subject: [PATCH 7/7] refactor: minor cleanup --- README.md | 2 +- install.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index afd605a..47cb416 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ irm https://dnot.sh/ | iex ``` > [!NOTE] -> As seen in examples 2 and 3 you can pass the commandline arguments to the installer script and it will forward them to `defendnot-loader`. For reference what commandline arguments are allowed, see the `Usage` section below. +> As seen in examples 2 and 3, you can pass the commandline arguments to the installer script and it will forward them to `defendnot-loader`. For reference what commandline arguments are allowed, see the `Usage` section below. > [!NOTE] > You can also directly use the 'longer' version of installer script url, which is `https://raw.githubusercontent.com/es3n1n/defendnot/refs/heads/master/install.ps1` diff --git a/install.ps1 b/install.ps1 index 3ea7cbc..6102a01 100644 --- a/install.ps1 +++ b/install.ps1 @@ -46,7 +46,7 @@ Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory($zipPath, $InstallPath) Remove-Item $zipPath -Write-Host "`nDefendnot installed to $InstallPath" +Write-Host "`nInstalled to $InstallPath" Write-Host "Starting..." Write-Host "Args: $args" & "$InstallPath\defendnot-loader.exe" @args