Whonix Windows Installer - Design Documentation

From Whonix
< Dev
Jump to navigation Jump to search

Work in progress.

Design / Features[edit]


  • new implementation of whonix.exe in lazarus (without NET framework)
  • platform independent ( later linux/mac version possible )
  • ui consists of two forms ( main & error )
  • main form has two buttons for start/stop and manage Whonix VMs
  • error form pops up if virtualbox is missing


  • installs windows version of WhonixStarter
  • adds start menu entry
  • adds desktop shortcut
  • uninstall over Windows "Programs and Features" tool


  • ui consists of a main form with several pages guiding the user through the installation process
  • platform independent ( later linux/mac version possible )
  • installs VirtualBox and WhonixOVA
  • executes WhonixStarterSetup.msi (Windows only)
  • checks installed and only reinstall missing components
  • does not uninstall or delete any component


  • Whonix .ova is bigger than 2 GB.
  • Windows .cab files have a hardcoded 2 GB maximum file size.


  • cross compile on Debian (source) for Windows (target)
  • building does not require Windows

Build limitations:

  • needs Debian bookworm or above because of minimal wixl and lazarus version

flow chart[edit]

(1) Whonix-Starter:

  • lazbuildWhonixStarter.lprWhonixStarter.exe
  • wixlWhonixStarterSetup.wxsWhonixStarter.exe, WhonixStarterSetup.wxsWhonixStarterSetup.msi

(2) Whonix-Installer:

  • lazbuildWhonixSetup.lprWhonixSetup.exe
  • WhonixSetup.exe + append + Whonix.ovaWhonixSetup-Xfce.exe





code signing[edit]


EV (extended validation) certificate required to avoid Microsoft SmartScreen Filter warning message.


  • EV code signing for Windows authenticode to avoid Microsoft SmartScreen Filter warning message.
  • cross signing
  • build scripts running on Debian Linux
  • build result (program) running on Windows 64 bit
  • avoid running proprietary closed source software on local build machine
  • can be fully automated using build scripts
  • avoid hardware token (compatibility, hassle)
  • avoid proprietary closed source device drivers
  • ideally avoid non-mainline Linux kernel drivers
  • supports signing big files



  • asked. does not have Linux tools.





Google Cloud HSM;

Verification of Code Signing Process[edit]

Verification of VirtualBox[edit]

VirtualBox for Windows is signed using Microsoft Authenticode signatures ("signtool").

VirtualBox's digital signature can be verified on the Linux platform using osslsigncode. Example:

osslsigncode verify -in VirtualBox-*.exe

A script verifyarchive.org has been added to the virtualbox-windows-installer-binary repository as a reminder and example how to verify the digital software signatures on the Linux platform.

Signing Whonix Windows Installer[edit]

This document is based on a case where an executable (hello.exe) is signed using GitHub Actions (CI) and CodeSigner.

For more details on the test, please refer to this GitHub repository: https://github.com/adrelanos/codesigner-testarchive.org

When a file (hello.exe) is signed, creating hello_signed.exe, the goal is to ensure that no additional modifications, beyond the signing process, have occurred. These could potentially include the insertion of malicious code.


  • Original file: hello.exe
  • Signed file: hello_signed.exe
  • Extracted signature file: hello_signature.pem
  • File with reattached signature: hello_with_signature.exe
  • File with reattached signature and reset PE header: hello_with_signature_reset_PE.exe
  • File with removed signature: hello_without_signature.exe
  • File with removed signature and reset PE header: hello_without_signature_reset_PE.exe
  • pe-header-to-zeroarchive.org

To achieve this, the original file is compared with the signed file in various stages and through different methods. The key stages are as follows:

1. Extract the signature from the signed file using osslsigncode:

osslsigncode extract-signature -in hello_signed.exe -out hello_signature.pem

2. The original file (hello.exe) is then re-signed using this extracted signature to create a new file (hello_with_signature.exe):

osslsigncode attach-signature -sigin hello_signature.pem -in hello.exe -out hello_with_signature.exe

At this point, one would expect hello_signed.exe to be identical to hello_with_signature.exe. However, it was discovered that the signing process (osslsigncode attach-signature) modified the PE header of the file by adding a PE checksum, thus resulting in a difference between these two files.

To analyze and understand these differences, a set of tools were used, including diff, vbindiff, diffoscope, and readpe. These comparisons brought to light the change in the PE checksum.

3. In order to make a direct comparison, the PE checksum in hello_with_signature.exe was reset to 0, mirroring its original state in hello.exe and hello_signed.exe. This was achieved using a Python script named pe-header-to-zero:

pe-header-to-zero hello_with_signature.exe hello_with_signature_reset_PE.exe

After running this script, the newly created file hello_with_signature_reset_PE.exe was found to be an exact match to hello_signed.exe.

4. The script pe-header-to-zero was also used on hello_without_signature.exe to create hello_without_signature_reset_PE.exe:

pe-header-to-zero hello_without_signature.exe hello_without_signature_reset_PE.exe

It was found that hello_without_signature_reset_PE.exe was an exact match to the original hello.exe, further validating the process.

Following this thorough examination, it can be reasonably stated that the signing process did not introduce any unwanted or malicious modifications to the original executable file.

All operations were performed using the osslsigncode tool.

To install and examine PE headers, the pev tool was used:

sudo apt install pev

To view the PE checksum, the readpe utility was used:

readpe hello_signed.exe

readpe hello_with_signature_reset_PE.exe

readpe hello_without_signature_reset_PE.exe



Reminder: Always please merge first before developing further.

document build.sh[edit]

Please document / refactor.

mv "WhonixSetup.lpi" "WhonixSetup.lpi.in"
cp "WhonixSetup.lpi.in" "WhonixSetup.lpi"


Can these varialbes be improved or removed if not essential?


change to...?

      <UseVersionInfo Value="True"/>
      <MajorVersionNr Value="1"/>
      <MinorVersionNr Value="2"/>
      <RevisionNr Value="3"/>
      <BuildNr Value="4"/>


Add WhonixSetup.lpi.in (WhonixInstaller.lpi.in) to .gitignore?

rename setup to installer[edit]

  • Please rename all mentions of textual string setup to installer.
  • Please rename all mentions of textual string Setup to Installer.
  • Please rename all files containing setup (or Setup) to installer (or Installer).
  • Update .gitignore.

remove minimal installation[edit]

Only "full" installation option needed for simplicity.

document gitignore special files[edit]

Please document .gitignore files.

remove VERSION_MAJOR etc[edit]

These ones would be hard to maintain. Maximum 1 version variable please.

export VERSION_MAJOR="0"
export VERSION_MINOR="0"
export VERSION_BUILD="0"

Windows_User_Interface wiki page[edit]

TODO: update/rewrite Dev/Windows_User_Interface

See Also[edit]

We believe security software like Whonix needs to remain open source and independent. Would you help sustain and grow the project? Learn more about our 12 year success story and maybe DONATE!