Configuration
One JSON file tells Lock Master what to protect and how hard. Every technique is opt-in — nothing happens unless you ask for it. This page is the map; each layer has its own page with real before/after code for every transform.
com/you/Main, not com.you.Main.** matches any depth, * a single segment.Structure
The top level is a set of optional blocks. Include only the ones you need:
{
"techniques": { ... }, // class-file protections (strings, rename, stripping)
"keep": { ... }, // what to never rename / touch
"rename": { ... }, // how renaming names things
"flow": { ... }, // control-flow obfuscation
"classGuard": { ... }, // whole-class encryption (sealed classes)
"antiDebug": { ... }, // refuse to run under a debugger
"seed": 123456 // optional: reproducible builds
}jar, libraries and mappingexist in the engine but are handled by the platform in the cloud (your input and output come from the CLI's --in/--out) — you don't set them here.
The four layers
Protection stacks in four layers, from cheapest to strongest. Each has a dedicated page that walks through every option with real engine output — one small method or jar, transformed, then decompiled so you see exactly what ships:
- Renaming & layout — strip the meaning out of class, method, field and package names. Covers
rename,keeprules, and the five package strategies. - String encryption — remove every readable literal from the class file. Covers the
PER_METHOD,INLINEandPOOLmodes. - Control-flow obfuscation — rewrite how methods branch, loop and compute so no clean Java reproduces them. Covers presets and all nineteen
flowtechniques. - Class encryption — ship your classes as encrypted blobs with no bytecode to decompile. Covers
classGuard,antiDebugandwatermark.
techniques
The techniques block holds the class-file-level switches. The two headline ones,stringEncryption and rename, have their own pages (strings, renaming). The rest are stripping and metadata options:
| Field | What it does |
|---|---|
| stringEncryption | Encrypt string literals — NONE / PER_METHOD / INLINE / POOL. See String encryption. |
| rename | Rename classes/methods/fields (uses rename + keep). See Renaming & layout. |
| stripDebug | Remove debug info — line numbers and local variable names. Recommended. |
| stripInnerClasses / stripNestInfo | Drop inner-class / nest-mate metadata. |
| synthetic | Mark members synthetic, hiding them from some tools and IDEs. |
| cacheMode | String cache: FAST (cache after first decrypt) or SAFE (re-decrypt and wipe on every access). |
| callerBinding | Key strings to their runtime caller: STACKWALKER (default) or STACKTRACE (cheaper, spoofable). |
| assetPool | Where encrypted string data lives: INLINE (helper class) or EXTERNAL (META-INF/strings.dat). |
| stripKotlinMetadata | Drop Kotlin @Metadata (for Kotlin code). |
| stripAnnotations | Drop invisible (CLASS-retention) annotations; runtime-visible ones are always kept. Use keepAnnotations for exceptions. |
seed & reproducibility
Set "seed": <number> to make builds reproducible: the same input plus the same config produces byte-identical output, with stable obfuscated names across runs — which is what lets a public API keep the same renamed symbols release to release. Leave it out for a fresh random build each time.
classGuard uses a secure random key by design, so turning it on makes the build non-reproducible regardless of the seed.Full reference
Every field, with valid values, in one file — copy it and delete what you don't need. It's valid JSON as-is (no comments), so it runs, though reflectionObfuscation andclassGuard are off by default because they change the most:
{
"techniques": {
"stringEncryption": "PER_METHOD",
"rename": true,
"synthetic": false,
"stripDebug": true,
"stripInnerClasses": false,
"stripNestInfo": false,
"cacheMode": "FAST",
"callerBinding": "STACKWALKER",
"assetPool": "INLINE",
"stripKotlinMetadata": false,
"stripAnnotations": false,
"keepAnnotations": []
},
"keep": {
"packages": ["com/you/api"],
"classes": ["com/you/Main"],
"members": [
{ "classPattern": "com/you/**", "methodPattern": "on*", "fieldPattern": null, "descriptor": null }
]
},
"rename": {
"deep": 3,
"chars": ["a", "b", "c", "d"],
"packageStrategy": "WRAPPER",
"packageDepth": 2,
"packagePool": 8
},
"flow": {
"enabled": true,
"preset": "custom",
"intensity": 6,
"timingSafeIndy": true,
"seedThreading": false,
"cfgFlattening": false,
"bogusControlFlow": { "enabled": true, "weight": 5 },
"deadCode": { "enabled": true, "weight": 5 },
"tryCatchAbuse": { "enabled": true, "weight": 5 },
"exceptionFlow": { "enabled": true, "weight": 5 },
"controlFlowFlattening": { "enabled": true, "weight": 5 },
"loopTransforms": { "enabled": true, "weight": 5 },
"gotoSpaghetti": { "enabled": true, "weight": 5 },
"methodOutlining": { "enabled": true, "weight": 5 },
"irreducibleFlow": { "enabled": true, "weight": 5 },
"switchBogusCases": { "enabled": true, "weight": 5 },
"invokeDynamic": { "enabled": true, "weight": 5 },
"seedMutation": { "enabled": true, "weight": 5 },
"integerSplitting": { "enabled": true, "weight": 5 },
"fakeLoops": { "enabled": true, "weight": 5 },
"branchAugmentation": { "enabled": true, "weight": 5 },
"arithmeticMBA": { "enabled": true, "weight": 5 },
"exceptionOverlap": { "enabled": true, "weight": 5 },
"constantExpression": { "enabled": true, "weight": 5 },
"reflectionObfuscation": { "enabled": false, "weight": 5 }
},
"classGuard": {
"enabled": false,
"mode": "STANDALONE",
"pluginMainClass": null,
"excludeClasses": []
},
"antiDebug": {
"enabled": false,
"action": "throw",
"checkAgents": false
},
"seed": null
}Full examples
A plugin, light and safe
Strings gone, renamed, cheap flow obfuscation, keeping the main class and public API. A great starting point for a first plugin:
{
"techniques": {
"stringEncryption": "POOL",
"rename": true,
"stripDebug": true
},
"flow": { "enabled": true, "preset": "light" },
"keep": {
"classes": ["com/you/MyPlugin"],
"packages": ["com/you/api"]
}
}A plugin, sealed (strong)
Adds class encryption in PLUGIN mode and anti-debug. Note the main class is both thepluginMainClass and excluded from encryption, and kept from renaming:
{
"techniques": {
"stringEncryption": "PER_METHOD",
"rename": true,
"stripDebug": true
},
"flow": { "enabled": true, "preset": "balanced", "timingSafeIndy": true },
"classGuard": {
"enabled": true,
"mode": "PLUGIN",
"pluginMainClass": "com/you/MyPlugin",
"excludeClasses": ["com/you/MyPlugin"]
},
"antiDebug": { "enabled": true },
"keep": { "classes": ["com/you/MyPlugin"] }
}A standalone app, everything on
Aggressive flow, sealed classes with a generated launcher, and anti-debug that kills the JVM under a debugger or agent:
{
"techniques": { "stringEncryption": "PER_METHOD", "rename": true, "stripDebug": true },
"flow": { "enabled": true, "preset": "aggressive" },
"classGuard": { "enabled": true, "mode": "STANDALONE" },
"antiDebug": { "enabled": true, "action": "exit", "checkAgents": true },
"keep": { "classes": ["com/you/Main"] }
}