Browse documentation
Documentation / Protection passes / Loader & runtime hardening

Loader & runtime hardening

ImplementedRJNI's own bundled bootstrap classes are renamed per build, the same way customer code is.

What it does

RJNI bundles a small number of its own runtime classes inside every protected jar: the native loader, the string decryptor, the tamper and anti-debug checks, the resource loader, and their siblings. All of them go through the same per-build renaming mechanism customer code gets, into a separate flat package computed over the fixed set of every runtime class RJNI might bundle. A class's assigned name therefore never depends on which of its siblings a given build uses, and stays consistent within one build.

Why it needed its own work

One of RJNI's own bootstrap methods is resolved by the JVM's default symbol-mangling convention, not through RegisterNatives. Renaming the class without re-mangling its exported native symbol would break every protected jar at first load, so the JNI specification's name-mangling rules are applied to keep the class name and its native symbol in sync. The rename also has to happen before final serialisation and checksum computation, and after everything that could inject a reference to a runtime class. Otherwise the checksum anti-tamper checksums compute wouldn't match what ships.

What is left alone

A renamed runtime class's original source-file debug attribute, an inner-class metadata entry's plain-text simple name, and a couple of human-readable comment strings in bundled configuration files still mention the class's original name. This is the same "plain string, invisible to a bytecode remapper" limitation that applies to every renamed class in the jar, customer code included. It is not specific to the loader.

Verified. In a protected jar, RJNI's own runtime classes land under the same obfuscated flat package as customer code, with no descriptive names. The full native-relinking test suite passed through this renamed path: the renamed loader located and loaded the bundled native library, and the batch build's renamed bootstrap symbol bound a native method, with no hardcoded fallback involved.