Developer CLI tool for MLVScan - scan .NET mod assemblies during development with remediation guidance and known malware family verdicts.
Download the latest mlvscan-win-x64.zip release asset from GitHub Releases, then run:
mlvscan.exe info --format jsonInstall as a global .NET tool:
dotnet tool install --global MLVScan.DevCLIOr install locally in your project:
dotnet new tool-manifest # if you don't have one already
dotnet tool install MLVScan.DevCLIThe DevCLI can be built using either the published NuGet package (default) or a local copy of MLVScan.Core for development.
By default, the build uses the published MLVScan.Core package from NuGet:
dotnet build -c ReleaseTo use a local copy of MLVScan.Core (e.g., when developing new features or testing changes):
dotnet build -c Release -p:LocalCoreBuild=trueThis switches the reference from the NuGet package to a local project reference at ../MLVScan.Core/MLVScan.Core.csproj.
Note: The NuGet package build requires a published version of MLVScan.Core that includes the current disposition and DTO contract. Until then, use -p:LocalCoreBuild=true for local development.
If installed as a global .NET tool:
dotnet tool update --global MLVScan.DevCLIOr if installed locally in your project:
dotnet tool update MLVScan.DevCLIScan a mod DLL and get developer-friendly output:
mlvscan MyMod.dllGet machine-readable JSON output in legacy format:
mlvscan MyMod.dll --jsonOr use the new standardized schema format (recommended):
mlvscan MyMod.dll --format schemaThe schema format follows MLVScan Schema, which keeps the v1 contract but adds richer context such as risk scores, developer-guidance provenance, deeper data-flow metadata, and threat-family evidence fields.
Exit with error code 1 if findings of High or Critical severity are found:
mlvscan MyMod.dll --fail-on HighShow all findings, even those without developer guidance:
mlvscan MyMod.dll --verboseEmit machine-readable tool metadata for integrations such as SIMM:
mlvscan info --format json
mlvscan --schema-versionAdd MLVScan checks to your build process by adding this to your .csproj:
Note: The output of the DevCLI may be hidden when using the dotnet CLI. Use an IDE like Visual Studio or Rider to see the full output of the DevCLI.
<Target Name="MLVScanCheck" AfterTargets="Build">
<Exec Command="dotnet tool run mlvscan -- $(TargetPath)" />
</Target><Target Name="MLVScanCheck" AfterTargets="Build">
<Exec Command="dotnet tool run mlvscan -- $(TargetPath) --fail-on High" />
</Target><Target Name="MLVScanCheck" AfterTargets="Build">
<Exec Command="dotnet tool run mlvscan -- $(TargetPath) --format schema > mlvscan-report.json" />
</Target>Note: Use --format schema for the standardized output format, or --json for the legacy format.
Here's a complete example of a mod project with MLVScan integration:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<AssemblyName>MyAwesomeMod</AssemblyName>
</PropertyGroup>
<!-- Your mod dependencies -->
<ItemGroup>
<PackageReference Include="MelonLoader" Version="0.6.1" />
</ItemGroup>
<!-- MLVScan Developer Tool -->
<ItemGroup>
<PackageReference Include="MLVScan.DevCLI" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<!-- Run MLVScan after every build -->
<Target Name="MLVScanCheck" AfterTargets="Build" Condition="'$(Configuration)' == 'Debug'">
<Exec Command="dotnet tool run mlvscan -- "$(TargetPath)""
ContinueOnError="true"
IgnoreExitCode="true" />
</Target>
<!-- Fail release builds if critical issues found -->
<Target Name="MLVScanCheckRelease" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
<Exec Command="dotnet tool run mlvscan -- "$(TargetPath)" --fail-on Critical" />
</Target>
</Project>Usage:
mlvscan <assembly-path> [options]
Arguments:
<assembly-path> Path to the .dll file to scan
Options:
-o, --format <format> Output format: console (default), json (legacy), schema (MLVScan Schema v1.1.0)
-j, --json Output results as JSON (legacy format, use --format schema for new format)
-f, --fail-on <value> Exit with error code 1 if findings >= severity (Low/Medium/High/Critical)
-v, --verbose Show all findings, not just those with developer guidance
-h, --help Show help information
--version Show version information
MLVScan Developer Report
========================
Assembly: MyMod.dll
Findings: 2
Known malware family match
Family: Embedded resource ShellExecute temp CMD dropper
Match: BehaviorVariant
Confidence: 99%
Summary: Embedded payload materialized to a temporary .cmd file and launched with hidden native shell execution.
Matched Rules: DllImportRule
[High] Detected executable write near persistence-prone directory
Rule: PersistenceRule
Occurrences: 1
Developer Guidance:
For mod settings, use MelonPreferences. For save data, use the game's
save system or Application.persistentDataPath with .json extension.
π https://melonwiki.xyz/#/modders/preferences
Suggested APIs: MelonPreferences.CreateEntry<T>
Locations:
β’ MyMod.SaveManager.SaveSettings:42
βββββββββββββββββββββββββββββββββββββββββ
{
"assemblyName": "MyMod.dll",
"totalFindings": 2,
"findings": [
{
"ruleId": "PersistenceRule",
"description": "Detected executable write near persistence-prone directory",
"severity": "High",
"location": "MyMod.SaveManager.SaveSettings:42",
"codeSnippet": "...",
"guidance": {
"remediation": "For mod settings, use MelonPreferences...",
"documentationUrl": "https://melonwiki.xyz/#/modders/preferences",
"alternativeApis": ["MelonPreferences.CreateEntry<T>"],
"isRemediable": true
}
}
]
}Using --format schema outputs the standardized MLVScan Schema format:
{
"schemaVersion": "1.1.0",
"metadata": {
"coreVersion": "1.1.5",
"platformVersion": "1.1.5",
"scannerVersion": "1.1.5",
"timestamp": "2026-01-29T12:34:56.789Z",
"scanMode": "developer",
"platform": "cli"
},
"input": {
"fileName": "MyMod.dll",
"sizeBytes": 45678,
"sha256Hash": "a1b2c3d4..."
},
"summary": {
"totalFindings": 2,
"countBySeverity": {
"High": 2
},
"triggeredRules": ["PersistenceRule"]
},
"threatFamilies": [
{
"familyId": "family-resource-shell32-tempcmd-v1",
"variantId": "resource-shell32-tempcmd-hidden",
"displayName": "Embedded resource ShellExecute temp CMD dropper",
"summary": "Embedded payload materialized to a temporary .cmd file and launched with hidden native shell execution.",
"matchKind": "BehaviorVariant",
"confidence": 0.99,
"exactHashMatch": false,
"matchedRules": ["DllImportRule"],
"advisorySlugs": ["2025-12-malware-customtv-il2cpp"],
"evidence": [
{
"kind": "api",
"value": "ShellExecuteEx"
}
]
}
],
"findings": [
{
"id": "f1a2b3c4d5e6",
"ruleId": "PersistenceRule",
"description": "Detected executable write near persistence-prone directory",
"severity": "High",
"location": "MyMod.SaveManager.SaveSettings:42",
"codeSnippet": "...",
"riskScore": 72,
"developerGuidance": {
"ruleId": "PersistenceRule",
"ruleIds": ["PersistenceRule"],
"remediation": "For mod settings, use MelonPreferences...",
"documentationUrl": "https://melonwiki.xyz/#/modders/preferences",
"alternativeApis": ["MelonPreferences.CreateEntry<T>"],
"isRemediable": true
}
}
],
"developerGuidance": [
{
"ruleId": "PersistenceRule",
"ruleIds": ["PersistenceRule"],
"remediation": "For mod settings, use MelonPreferences...",
"documentationUrl": "https://melonwiki.xyz/#/modders/preferences",
"alternativeApis": ["MelonPreferences.CreateEntry<T>"],
"isRemediable": true
}
]
}This format is compatible with the MLVScan web UI and other ecosystem tools. Schema v1.1.0 also adds optional callChainId and dataFlowChainId on findings, plus dataFlows[].callDepth and dataFlows[].isSuspicious when those sections are present.
name: Build and Scan
on: [push, pull_request]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
- name: Install MLVScan.DevCLI
run: dotnet tool install --global MLVScan.DevCLI
- name: Build
run: dotnet build -c Release
- name: Scan for issues
run: mlvscan ./bin/Release/netstandard2.1/MyMod.dll --json > scan-results.json
- name: Upload scan results
uses: actions/upload-artifact@v3
with:
name: mlvscan-results
path: scan-results.jsonstages:
- build
- scan
build:
stage: build
script:
- dotnet build -c Release
artifacts:
paths:
- bin/Release/
scan:
stage: scan
script:
- dotnet tool install --global MLVScan.DevCLI
- mlvscan ./bin/Release/netstandard2.1/MyMod.dll --json > scan-results.json
- mlvscan ./bin/Release/netstandard2.1/MyMod.dll --fail-on Critical
artifacts:
reports:
mlvscan: scan-results.json- Critical: Serious security violations (e.g., shell execution, Discord webhooks)
- High: Potentially dangerous patterns (e.g., registry access, DLL imports)
- Medium: Suspicious patterns that may be legitimate (e.g., encoded strings)
- Low: Informational findings (e.g., Base64 usage)
Each finding may include:
- Remediation: Specific advice on how to fix the issue
- Documentation URL: Link to relevant MelonLoader documentation
- Alternative APIs: Suggested safe APIs to use instead
- IsRemediable: Whether a safe alternative exists
If IsRemediable is false, the pattern has no safe alternative and should not be used in MelonLoader mods.
A: The scan typically takes 1-2 seconds for most mods. You can disable it in Debug builds or use ContinueOnError="true" to make it non-blocking.
A: The developer guidance will help you understand why something was flagged and how to fix it. If you believe it's a legitimate false positive, you can:
- Refactor your code using the suggested alternatives
- Contact the MLVScan maintainers in the Discord
- Add your mod's hash to the whitelist after community review
A: Yes! The tool works on compiled DLLs and doesn't require source code access.
- Discord: https://discord.gg/UD4K4chKak
- GitHub: Report issues and suggestions
GPL-3.0 License - See [LICENSE] file for details