L3S DRM Developer Guide
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:
- Add
#include "obfusheader.h"to your C++ file - 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. Remove All "DRM" References from Your Binary
Your compiled .wasm file contains every string literal from your C++ code in plaintext. An attacker can open the file in a text editor (e.g. Notepad++) and search for "DRM" to instantly locate security-critical code paths.
Wrap every string containing "DRM" with OBF():
// BAD — plaintext "DRM" will appear in the .wasm binary
std::cout << "Starting DRM check..." << std::endl;
// GOOD — obfuscated at compile time, invisible in the binary
std::cout << OBF("Starting DRM check...") << std::endl;Avoid naming your own functions or variables with "DRM" in the name. Function and variable names can end up in the binary. The compiler visibility flags (see below) hide most internal symbol names, but not all. Instead of InitializeDRM() or drmStatus, use ambiguous names that do not hint at the purpose of the code.
Verification: After building and running
wasm-opt(see build steps below), open the final.wasmfile in a text editor and search forDRM(case-insensitive). You should find zero matches. If any remain, either wrap the corresponding string withOBF()or rename the function/variable.
4. Compiler Visibility Flags
To reduce the number of exported symbols in your WASM module (making reverse engineering harder), add the following compiler flags:
/clang:-fvisibility=hidden /clang:-fvisibility-inlines-hiddenWhere to set in Visual Studio:
- Right-click the project → Properties
- Navigate to C/C++ → Command Line
- Add the flags to Additional Options
Important: These flags must be applied to your main WASM project and any class library projects that are linked into it, if applicable.
5. 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.
2. Optimize the WASM file (optional but highly recommended)
This step makes reverse engineering more difficult:
wasm-opt INPUT_FILE.wasm -o optimized.wasm ^
--strip-debug ^
--strip-dwarf ^
--strip-producersTip: This process is easy to automate using a
.bator build script. See the automation examples below.
Build Automation Examples
Visual Studio Pre-Build Event
The pre-build script auto-generates file hashes for integrity verification. Add this to your project configuration:
Pre-Build Event Command:
$(ProjectDir)scripts\prebuild-msfs.bat $(ProjectDir) $(SolutionDir)This script generates file hashes automatically at compile time, eliminating the need to manually look up hashes in debug mode. See the demo project for a complete example of the prebuild script.
Visual Studio Post-Build Event
For Visual Studio projects, you can automate the optimization and copy 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 ^
--strip-producers
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, and copies it to your aircraft package folder—all in one step!
Marketplace/Xbox vs Direct Sales Summary
| Feature | Marketplace Build | Direct Sales Build |
|---|---|---|
| Keyless Mode | Set to true | Set to false |
Troubleshooting
String obfuscation not working
Ensure you're including obfusheader.h and wrapping strings with OBF(...). Verify by inspecting the compiled .wasm file in a text editor for unobfuscated strings.
Build errors with visibility flags
Make sure the flags are added to Additional Options under C/C++ → Command Line, not under other compiler settings. Also ensure the flags are set for all linked projects.