Protection Strength and the Closed Plugin
RenMori uses an open-core architecture. The open-source renmori CLI handles packing, verification and CI integration, and includes a fixed open baseline format; full-strength protection is provided by a closed native plugin. The plugin itself is a free precompiled binary; only its source code is closed.
The two protection strengths
The container structure of the baseline format is public, and the keys and reader are distributed with the game in plaintext. It defeats off-the-shelf tools but does not constitute real protection against a targeted attacker. Use full protection for official releases. For the threat model of both, see Threat model.
How the strength is determined
The default behavior prefers failing over degrading automatically, in order to avoid releasing a build with only baseline strength without noticing. When the behavior "use full protection if the plugin is available, otherwise baseline" is wanted, specify auto explicitly.
Plugin lookup order
When the plugin is needed, renmori searches in the following order and uses the first available result:
- The file specified by
--plugin PATH - The file specified by the environment variable
RENMORI_PLUGIN - The plugin in the local cache
- Automatic download from the public release
If a specified path does not exist, a notice is printed to stderr and the search continues with the subsequent steps. When RENMORI_NO_DOWNLOAD is set, step 4 is skipped.
Automatic download
Platforms and files
The plugin is selected according to the platform running renmori and is unrelated to the game's target platforms; the target platforms are determined by --platforms or by automatic detection. Platforms not listed above have no downloadable plugin and can only specify one with --plugin or use baseline protection.
Download flow
- Determine the download address: by default
https://github.com/MewBaka/RenMori/releases/download/<tag>/, where<tag>defaults to the plugin tag built into the current version and can be overridden byRENMORI_PLUGIN_TAG; whenRENMORI_PLUGIN_BASE_URLis set, the download is made from that address instead - Confirm: in an interactive terminal the prompt
Full protection needs the closed plugin. Download <file> from <url> ? [Y/n]is shown, and answeringnornoabandons the download; in CI, non-interactive environments, or with--quietor-y, the download proceeds directly - Fetch
SHA256SUMSfrom the same address and look up the checksum for the corresponding file; abandon if no corresponding entry is found - Download the plugin file, compute its SHA-256 and compare it with
SHA256SUMS; on a mismatch, discard the file and print "Downloaded plugin failed its checksum; discarded" - Write to a temporary file first, then atomically replace the cache path with it; on macOS and Linux, set the executable permission
If any step fails, the plugin is treated as unavailable: when no strength is set the command fails, and with auto it falls back to baseline.
Cache location
The cache is stored in a separate directory per release tag; after upgrading renmori or changing RENMORI_PLUGIN_TAG, the new directory for the corresponding tag is used. Deleting the cache directory forces a fresh download.
Environment variables
Offline and internal network environments
- Pre-populated cache: run full protection once on a machine with network access, then copy the cache directory to the same location on the offline machine
- Fixed path: place the plugin file on the build machine and specify it with
RENMORI_PLUGINor--plugin - Internal mirror: serve both the plugin file and
SHA256SUMSfrom an internal server, and pointRENMORI_PLUGIN_BASE_URLat that address - No network access: set
RENMORI_NO_DOWNLOAD=1to ensure that the build process makes no network requests
For how to cache the plugin in CI, see CI integration.
Capability handshake
Before using the plugin, renmori invokes it with the capabilities subcommand and reads the JSON it returns, which includes the interface version supported by the plugin and the list of available strengths. The plugin is treated as unavailable in the following cases:
- The plugin cannot be executed, returns a non-zero exit code, or does not respond within 30 seconds
- The returned content is not valid JSON
- The interface version is lower than the version required by
renmori, in which case stderr showsplugin interface … unsupported
After a successful handshake, renmori invokes the plugin with the protect subcommand, passes through stdin a request JSON containing the source directory, output directory, strength, platforms, launcher, exclusion list, chunk size and lockdown setting, and reads the result from the last line of the plugin's stdout; the plugin's progress output goes directly to stderr. A plugin whose name ends in .py is run by the current Python interpreter; otherwise it is executed directly.
For the complete process interface between the open-source tool and the closed plugin, see Plugin interface.