Changelog

What’s new in HashGuard

Features, improvements and fixes, release by release.

New

Licence gate and a self-protected CLI

The CLI checks the customer licence before doing any work, and ships obfuscated by its own pipeline.

  • The licence is validated once per run, before any obfuscation, multi-slot runs included.
  • Each machine takes one seat, identified by a SHA-256 hash of local hardware identifiers; the seat is released when the run exits.
  • The key is read from the OS keyring on a workstation, or from PLR_LICENCE_KEY in CI.
  • The released CLI jar is obfuscated by HashGuard itself and carries its watermark.
  • String decryption resolves through an invokedynamic path that Java 8 accepts.
Improved

On-demand decryption and finer shuffling

Encrypted references and strings cost less at start-up, and shuffling can be tuned list by list.

  • Reference and string blobs are decrypted slice by slice the first time they are used, instead of all at once.
  • shuffleOptions switches each list that shuffling reorders; MethodParameters stays in place by default.
  • Records, MethodParameters and other metadata seen through reflection keep their integrity.
New

Sensitive VM and hardened runtime helpers

Selected methods can be virtualised, and the code HashGuard injects is harder to spot and to bypass.

  • sensitiveVm virtualises the methods listed in sensitiveVmMethods, before anything is renamed.
  • Integrity checks run through several gates behind a sealed bootstrap chain.
  • Common runtime instrumentation flags are rejected at launch.
  • Generated helper and crypto runtimes no longer stand out in the protected jar.
New

Gradle plugin

Protect the jar your build produces with one task, published with the API and the engine as version 26.6.1.

  • The fr.polargames.plr-obfuscator plugin adds a plrObfuscate task configured by inputJar, configFile, slotCount and outputDir.
  • The runtime classpath of the project is passed as libraries automatically.
  • Multi-slot builds write one jar per slot and a keys manifest.
New

Profiles and an output budget

One key sets a baseline for every option, and a budget keeps heavy passes from inflating the jar.

  • profile takes Ghost, Low, Medium, High or Extreme; options written explicitly still win.
  • maxOutputRatio caps the output at a multiple of the input instruction count; heavy passes stop once it is spent.
  • renameMemberPrefix prefixes renamed fields and methods, and generated classes join renamePackage.
  • Encrypted classes carry an HMAC-SHA256 integrity tag.
New

Ghost members and compress-then-encrypt

Phantom members break structural fingerprints, and encrypted payloads got smaller.

  • ghostMembers injects phantom fields and methods; ghostMembersIntense adapts the injection to enums and large classes.
  • Strings and references are compressed before AES encryption.
  • magicCrypter compresses each class before encrypting it.
New

Dispatchers, method salts and SPECK constants

Calls, signatures and numbers each gained a new layer.

  • invokeDispatcher routes owned static, virtual and interface calls through a per-class dispatcher.
  • methodSalt appends a dead parameter to private methods and rewrites every call site.
  • numberSpeck encrypts numeric constants with a per-class SPECK decryptor.
  • Reference obfuscation mixes several algorithms and derives its IVs from the calling context.
New

A dozen new passes

The structure and the data flow of a class became much harder to follow.

  • blockBreak, trapEdge and gotoObfuscation fragment what decompilers see of the control flow.
  • integerTable, fieldProxy and fieldDescriptorMutation hide constants and field accesses.
  • parameterPacking carries private method parameters in arrays, without boxing.
  • annotationConfuser injects phantom annotations, and comparisonObfuscation hides string comparisons.
New

A headless obfuscator

HashGuard started as a deep rewrite of the Bozar fork into a command-line tool.

  • The graphical interface is gone: one JSON config drives the CLI.
  • Transformers run in ordered phases, each in a fixed slot.
  • The annotations API lets code mark what to keep, and annotations are stripped from the output.
  • Encryption moved from XOR to AES-128-CTR, and runs gained diagnostics and a mapping output.

Protect your next release

Buy a licence, drop a config file next to your build and ship a jar that is hard to read.