WASM Build & Security

This guide covers the essential build process and security considerations for implementing L3S DRM in your WASM module. These security measures are crucial for protecting your aircraft against tampering and reverse engineering.

Important: These security measures are highly recommended for any public release. With default compiler settings, the generated .wasm file tends to be fairly human-readable, making it easier for attackers to locate and modify critical DRM-related logic.


Security Implementation

1. Using the Latest Include Files

Ensure you're using the latest files from the include/ directory provided with L3S DRM. These files contain the most current security features and should be copied to your project's include path.


2. String Obfuscation

L3S DRM includes a header-only library (obfusheader.h) that enables simple string obfuscation in C++. This makes it significantly harder for attackers to identify sensitive information in your compiled WASM.

Usage:

  1. Add #include "obfusheader.h" to your C++ file
  2. Wrap sensitive strings in OBF(...), for example: OBF("\work\auth.l3")

Recommended strings to obfuscate:

  • Activation URLs
  • Local file paths
  • Regex patterns

Example implementation:

#include "obfusheader.h"
std::string apiKey = OBF("YOUR_API_KEY");

3. WASM Signature Verification (Direct Sales Only)

For Direct Sales builds, DRMPublish::VerifySignature(...) is a critical security function that should be called at least once during aircraft initialization.

It is fine (and even recommended) to call it multiple times during startup from different systems or entry points.

However, do not call it continuously during runtime, as this may cause stuttering or performance issues.

Critical: Do not call this function in Marketplace builds. It will cause the .wasm module to crash instantly once published to the MSFS Store.

case PANEL_SERVICE_PRE_INSTALL:
{
#ifndef _MARKETPLACE_PKG
    // If you are publishing to Marketplace, do NOT call this function.
    // The .WASM module will crash once it's in the MSFS Store.
    DRMPublish::VerifySignature(OBF(".\SimObjects\Airplanes\MyCompany_CommBus_Aircraft\panel\SampleCommBus.wasm"));
    // If this fails, the DRM Signature is not valid and the WASM module will crash/exit instantly without any error message.
#endif // !_MARKETPLACE_PKG

    return true;
}

4. Build Configuration Setup

It's recommended to set up separate build configurations for Marketplace (incl. XBOX) and Direct Sales releases. The _MARKETPLACE_PKG compiler flag should be defined for Marketplace builds.

This enables conditional compilation, allowing you to include or exclude certain security features based on your distribution method.


Complete Build Process

1. Build the WASM file

Compile your .wasm file using your standard build process.

For Direct Sales builds, do NOT use the unsigned output directly — it will crash in MSFS without a signature.

2. Optimize the WASM file (optional but highly recommended)

This step makes reverse engineering more difficult:

wasm-opt INPUT_FILE.unsigned.wasm -o optimized.unsigned.wasm \
  --strip-debug \
  --strip-dwarf \
  --flatten \
  --rereloop \
  --reorder-functions \
  --reorder-globals \
  --reorder-locals \
  --untee \
  --strip-producers \
  --strip-target-features \
  --enable-bulk-memory-opt

3. Sign the WASM file (Direct Sales only)

This step is required for non-Marketplace builds:

WasmSigner.exe optimized.unsigned.wasm final.wasm

Note: Signing is not required for Marketplace builds

The output final.wasm is now ready for packaging.

Tip: This process might seem complex at first glance, but it's easy to automate using a .bat or build script.


Build Automation Examples

Visual Studio Post-Build Event

For Visual Studio projects, you can automate the entire process using a post-build event. Add this to your project configuration:

Post-Build Event Command:

$(ProjectDir)scripts\postbuild-msfs.bat $(SolutionDir) $(OutDir)

Example post-build script (postbuild-msfs.bat):

@echo off
setlocal enabledelayedexpansion

echo ---- BEGIN POST BUILD SCRIPT ----
echo solution dir = %1%
echo output dir = %2%

cd /d "%~dp0"
if errorlevel 1 exit /b 1

REM Find the first .wasm file
set "WASM_FILE="
for %%F in ("%2%\*.wasm") do (
    set "WASM_FILE=%%~fF"
    goto :found_wasm
)

echo No .wasm file found in %2%
exit /b 1

:found_wasm
echo wasm file = !WASM_FILE!

echo -- WASM-OPT ---
wasm-opt "!WASM_FILE!" -o "!WASM_FILE!" ^
  --strip-debug ^
  --strip-dwarf ^
  --flatten ^
  --rereloop ^
  --reorder-functions ^
  --reorder-globals ^
  --reorder-locals ^
  --untee ^
  --strip-producers ^
  --strip-target-features ^
  --enable-bulk-memory-opt
if errorlevel 1 exit /b 1

echo -- SIGN WASM ---
WasmSigner "!WASM_FILE!" "!WASM_FILE!"
if errorlevel 1 exit /b 1

echo -- COPY INTO AIRCRAFT SOURCE FOLDER --
copy /Y "!WASM_FILE!" "%1%..\..\PackageSources\SimObjects\Airplanes\MyCompany_CommBus_Aircraft\panel\"
if errorlevel 1 exit /b 1

echo ---- END POST BUILD SCRIPT ----

Tip: This script automatically finds the .wasm file, optimizes it, signs it (for Direct Sales), and copies it to your aircraft package folder—all in one step!


Marketplace/Xbox vs Direct Sales Summary

FeatureMarketplace BuildDirect Sales Build
VerifySignature()Must NOT be calledRequired
WASM SigningNot requiredRequired
Keyless ModeSet to trueSet to false

Troubleshooting

WASM crashes immediately on Marketplace

Make sure you're not calling DRMPublish::VerifySignature() in Marketplace builds and set Keyless Mode to true.

Direct Sales build crashes without signature

Ensure you're signing your WASM file with WasmSigner.exe for all Direct Sales builds.

Performance issues

Don't call DRMPublish::VerifySignature() continuously during runtime. Call it only during initialization.