217 lines
12 KiB
Markdown
217 lines
12 KiB
Markdown
# Antivirus false positives — what is actually happening and what to do about it
|
||
|
||
LiveWall is flagged by a handful of engines out of seventy. This page explains why, what has already
|
||
been done about it, in what order to fix the rest, and what to tell users in the meantime.
|
||
|
||
Last reviewed: 2026-11-04, for `LiveWall-Setup-1.8.0.exe`.
|
||
|
||
---
|
||
|
||
## 1. What the scan actually said
|
||
|
||
VirusTotal, first submission 2026-11-04, **3 of 71 engines**:
|
||
|
||
| Engine | Verdict | What that engine is telling you |
|
||
|---|---|---|
|
||
| SecureAge (APEX) | `Malicious` | Reputation/heuristic verdict; APEX is well known for flagging new, unsigned, low-prevalence files. |
|
||
| Trapmine | `Malicious.high.ml.score` | A pure machine-learning score. No signature, no analyst: "this file shape looks like things we have seen". |
|
||
| VBA32 | `TScope.Malware-Cryptor.SB` | "SB" = **solid block**. VBA32 scores the NSIS solid archive as a crypter. |
|
||
|
||
Undetected: **Microsoft Defender, Kaspersky, BitDefender, ESET, Avast/AVG, Malwarebytes, Sophos,
|
||
Symantec, Trend Micro, McAfee, GData, Ikarus, ClamAV, DrWeb, CrowdStrike, SentinelOne, Palo Alto,
|
||
Fortinet, Webroot**, and 50 more.
|
||
|
||
Facts from the report that explain the three verdicts:
|
||
|
||
* **File is not signed.** No Authenticode signature, no publisher.
|
||
* **First submission = last submission.** Prevalence zero. Reputation engines have nothing to go on,
|
||
so they fall back to heuristics — and the fallback is "guilty until seen a lot".
|
||
* **DetectItEasy: `Installer: Nullsoft Scriptable Install System (3.11-1) [zlib,solid]`.** NSIS is the
|
||
single most abused installer format in the world, and `/SOLID` hides each file's structure behind
|
||
one compressed stream. That is exactly what the VBA32 and Trapmine scores are reacting to.
|
||
* Nothing else: no packer (UPX), entropy of `.text` is 6.09 (normal), imports are ordinary, the file
|
||
has proper version info (Product, Description, File Version, Copyright).
|
||
|
||
**This is not a detection of behaviour in the app.** The three engines never ran it — these are static
|
||
or reputation verdicts on an unsigned installer stub.
|
||
|
||
---
|
||
|
||
## 2. Why a wallpaper app trips heuristics at all
|
||
|
||
Beyond "unsigned + unknown", the app's own behaviour looks like the shape of a threat to a scanner:
|
||
|
||
| The app does | Scanners see |
|
||
|---|---|
|
||
| Finds `WorkerW`, re-parents a hidden window into the shell desktop | "hides a window inside Explorer" |
|
||
| Registers global hotkeys | "installs system-wide input handling" |
|
||
| Optionally starts with Windows (HKCU `Run`) | "persistence" — **off by default** in LiveWall |
|
||
| Loads .NET assemblies from `%APPDATA%\LiveWall\plugins` | "executes code from a user-writable directory" — **off by default**, needs two explicit consents, hash-pinned |
|
||
| Ships WebView2 and plays YouTube | "network access" |
|
||
|
||
None of that is malicious, and none of it is unique to LiveWall — every live-wallpaper app does the
|
||
first two. But it means the app will be *judged on reputation*, not on inspection. That is why the
|
||
answer is not "make the code cleaner", it is "get a signature and get seen".
|
||
|
||
Things that were already right (keep them that way): no bundled offers, no telemetry, no admin rights
|
||
(`RequestExecutionLevel user`), per-user install, real version metadata on both the installer and the
|
||
binaries, uninstaller registered, no obfuscation, no UPX.
|
||
|
||
---
|
||
|
||
## 3. Fixes, in order of how much they actually help
|
||
|
||
### 3.1 Sign everything with Authenticode (the only real fix)
|
||
|
||
An unsigned download is *the* variable here. It is also what every vendor replies with when you file a
|
||
false-positive report ("please sign your binaries").
|
||
|
||
* **EV code-signing certificate** (~$300–500/year, hardware token/HSM): SmartScreen and Defender
|
||
reputation trust it immediately, and heuristics weight signed files far higher.
|
||
* **OV code-signing certificate** (~$100–300/year): works, but reputation accumulates over weeks of
|
||
downloads. Expect fewer and fewer flags as it builds.
|
||
* **Self-signed certificate: do not bother.** An untrusted signature is worth no more than no
|
||
signature, and sometimes less.
|
||
* Sign **both** the published binaries and the installer, and let NSIS sign the uninstaller it
|
||
generates (`installer/sign.ps1` and the `SIGNTOOL` hook in `LiveWall.nsi` do all of this). Always
|
||
timestamp (RFC 3161) so signatures survive certificate expiry.
|
||
|
||
```powershell
|
||
# after signing, every file reports a publisher instead of "Unknown publisher"
|
||
.\installer\sign.ps1 -Thumbprint <sha1-of-cert> # or -Pfx .\codesign.pfx
|
||
```
|
||
|
||
### 3.2 Report the false positive — every one of the three
|
||
|
||
Vendors fix these in days when you tell them. Submit the file (or its hash), say what it is, and ask
|
||
for a reclassification. Use the "Contact vendor" link on the VirusTotal page for each detection, and:
|
||
|
||
| Vendor | Where |
|
||
|---|---|
|
||
| **Microsoft** (even though it currently passes — keeps Defender's cloud verdict clean) | <https://www.microsoft.com/en-us/wdsi/filesubmission> → *Software developer* → "I believe this file is incorrectly detected" |
|
||
| **SecureAge** | support@secureage.com, or the contact form on secureage.com — attach the VT link |
|
||
| **Trapmine** | Trapmine support (contact form / support@trapmine.com) — quote the exact ML verdict |
|
||
| **VBA32** | virus@vba32.com (their sample/FP mailbox) |
|
||
|
||
Text that works — it gives the analyst everything they need in one screen:
|
||
|
||
> Subject: False positive — LiveWall 1.8.0 installer (NSIS), unsigned open-source wallpaper app
|
||
>
|
||
> Hello,
|
||
>
|
||
> Your engine reports `<verdict>` for SHA-256
|
||
> `7242a2a3fd6fc142279aecf2ea83f02501af4df3fdd1ecfe7c481bf6aa7a1764`
|
||
> (`LiveWall-Setup-1.8.0.exe`, VirusTotal: <link>).
|
||
>
|
||
> LiveWall is a free live-wallpaper app for Windows 11 (GIF/video/YouTube on the desktop). The file is
|
||
> an NSIS 3.11 installer built by our own script from our own source; it installs per-user into
|
||
> `%LOCALAPPDATA%\Programs\LiveWall`, needs no admin rights, contains no bundled offers, no telemetry,
|
||
> no obfuscation and no downloader. It is currently unsigned while certification is in progress.
|
||
>
|
||
> The detection looks like a heuristic on the NSIS solid archive rather than on behaviour. Please
|
||
> reclassify. I can provide the source, the build script, signed builds, or any further sample you
|
||
> need.
|
||
>
|
||
> Thank you.
|
||
|
||
Also worth doing once: create a **VirusTotal account** and use *Reanalyze* after reporting, and keep the
|
||
VT link in the release notes so users see the same picture you do.
|
||
|
||
### 3.3 Change the container, not the app
|
||
|
||
Two variants are built from the same source specifically for this:
|
||
|
||
| Build | Command | Why |
|
||
|---|---|---|
|
||
| `LiveWall-Setup-1.8.0.exe` | `bash installer/build-installer.sh` | solid LZMA, smallest (709 KB) |
|
||
| `LiveWall-Setup-1.8.0-lzma.exe` | `COMPRESS=lzma OUT_SUFFIX=-lzma bash installer/build-installer.sh` | no solid block, one stream per file (809 KB) |
|
||
| `LiveWall-Setup-1.8.0-zlib.exe` | `COMPRESS=zlib OUT_SUFFIX=-zlib bash installer/build-installer.sh` | no solid block, no LZMA at all (972 KB) |
|
||
| `LiveWall-1.8.0-portable.zip` | `.\build.ps1 -Task portable` | **no executable container at all** — a plain zip of the app |
|
||
|
||
Upload the variants to VirusTotal and keep the one that scores cleanest. The zlib build is the one to
|
||
try first if VBA32/Trapmine are the only remaining flags: "solid" and "lzma" are exactly what those two
|
||
score. The ZIP walks around the whole class of problems — nothing to unpack, nothing to score as a
|
||
self-extracting stub — and is a perfectly good distribution format for a 2.7 MB app that needs the
|
||
.NET 8 Desktop Runtime anyway.
|
||
|
||
Longer term, a **signed MSI (WiX)** or **MSIX** is the most "boring" container Windows offers, at the
|
||
cost of more build work. Not worth it before signing.
|
||
|
||
### 3.4 Build reputation
|
||
|
||
* Publish from **one identity, consistently**: same certificate, same publisher name in the version
|
||
resources (`Company`, `LegalCopyright`, `OriginalFilename`), same download host.
|
||
* Get real download volume — GitHub Releases, winget (`winget-pkgs`), Chocolatey, PortableApps,
|
||
Scoop. High prevalence is itself an allow-list for every ML engine.
|
||
* Keep the source public and linked from the download page. Analysts and users both use it.
|
||
* Don't re-release new hashes constantly: every build resets file reputation. Batch fixes.
|
||
|
||
### 3.5 Keep the plugin system's shape defensible
|
||
|
||
The plugin system is the most "malware-shaped" feature in the app (loading arbitrary .NET assemblies
|
||
from `%APPDATA%`). It is already as gated as a design can be, and it is worth saying so in any
|
||
submission or user-facing explanation:
|
||
|
||
* the system is **off by default** (`Plugins.Enabled = false`);
|
||
* enabling it shows a mandatory third-party-code warning that must be acknowledged;
|
||
* each plugin is hashed (SHA-256) and shows its hash, publisher and permissions in its own warning
|
||
before a single line of it runs;
|
||
* the approved hash is pinned — a changed DLL is unverified again and stops loading;
|
||
* nothing is ever downloaded or executed automatically, and there is no network component in the loader.
|
||
|
||
---
|
||
|
||
## 4. What to tell users right now
|
||
|
||
Wording that is honest and de-escalates:
|
||
|
||
> **Heads-up about antivirus warnings.** `LiveWall-Setup-1.8.0.exe` is currently flagged by 3 of 71
|
||
> engines on VirusTotal (SecureAge, Trapmine, VBA32) and is clean on the other 68, including Microsoft
|
||
> Defender, Kaspersky, BitDefender, ESET and Malwarebytes. The three are reputation/ML verdicts on an
|
||
> installer that is not yet code-signed — not behaviour detections. The installer is built from the
|
||
> source in this repository, installs per-user without admin rights, and contains no telemetry, no
|
||
> bundled offers and no downloader.
|
||
>
|
||
> * Check it yourself: VirusTotal link, SHA-256 `…` (matches the file you downloaded).
|
||
> * Vendor reports filed on 2026-11-04; these verdicts typically clear within a few days.
|
||
> * Prefer no installer at all? Use the portable ZIP: unpack it and run `LiveWall.exe`.
|
||
> * If your AV quarantines it anyway: send me the engine name and the detection name, and add an
|
||
> exclusion only if you are comfortable doing so.
|
||
|
||
Two rules for that message: never tell users to "just disable your antivirus", and always give them a
|
||
hash they can verify.
|
||
|
||
---
|
||
|
||
## 5. Checklist per release
|
||
|
||
- [ ] `.\build.ps1 -Task publish`
|
||
- [ ] `bash installer/build-installer.sh` (and optionally the `-zlib` variant)
|
||
- [ ] `.\installer\sign.ps1 -Thumbprint <cert>` — verify every file has a publisher
|
||
- [ ] Upload the installer + `LiveWall.exe` to VirusTotal, check the score
|
||
- [ ] Publish the SHA-256 of every downloadable file in the release notes
|
||
- [ ] `.\build.ps1 -Task portable` as the fallback download
|
||
- [ ] If a new engine flags it: report with the template above, then *Reanalyze* a day later
|
||
- [ ] Keep a note of who flagged which version, so you can tell whether a change helped
|
||
|
||
## 6. Tracking
|
||
|
||
| Version | File | Result | Notes |
|
||
|---|---|---|---|
|
||
| 1.8.0 | `3d472fa6…3deba` | 3/71 — SecureAge, Trapmine (ML), VBA32 (TScope.Malware-Cryptor.SB) | unsigned, solid LZMA, first seen today |
|
||
| 1.8.0 (rebuild) | `7242a2a3…a1764` | to be measured | version-info improvements; same container |
|
||
| 1.8.0 (zlib) | `78cde58c…fc4b` | to be measured | no solid block — expected to clear VBA32/Trapmine |
|
||
| 1.8.2 | `843425a9…f321c` | to be measured | input-shield + cursor fixes; same container as 1.8.0 (unsigned, solid LZMA) |
|
||
| 1.8.2 (zlib) | `cb175d79…023a9` | to be measured | non-solid variant |
|
||
| 1.8.2 portable ZIP | `016c5793…7652e` | to be measured | no installer stub at all |
|
||
| 1.8.3 | `ce642909…a5d06` | to be measured | redesigned installer (same NSIS container, same compressor) |
|
||
| 1.8.4 | `d2de043f…906e4` | to be measured | side-menu layout fix; same container |
|
||
|
||
Also worth uploading to VirusTotal, because engines inspect them once the installer has run:
|
||
`prebuilt\LiveWall.exe` (SHA-256 `7ecaa8e2ada4833ce4b84388f17da0b5605e87cb4c3348577b23e26476c953cc` before the
|
||
last rebuild) and `LiveWall.Sdk.dll`. If those come back clean while the installer does not, that alone
|
||
proves the verdict is about the NSIS container.
|
||
|
||
Portable fallback for this build: `LiveWall-1.8.0-portable.zip`,
|
||
SHA-256 `83ce64aed61232afd6e5a39d55bf8856b4630d958de37cdc42386b92f43ab506`.
|