This page is available in English only.

What an attacker can recover (reversal classes)

The static-attacker classes AfterPack's transforms fall into, and what recovering each one gets an attacker.

AfterPack sorts its protections into classes. Each class raises the cost of reversal differently. Knowing which class covers a region of your code tells you what an attacker recovers if they read it. The Protection Map colors every token by the class it landed in.

Static attacker, defined

These are static-attacker classes. They describe what someone who reads the bytes faces: grep, AST tooling, a deobfuscator pass, or an LLM that explains code without running it. An attacker who runs the artifact under instrumentation is a separate, stronger case, covered in the threat model.

The three reversal-complexity classesRenamed & encodedPolynomial-injectiveAttacker gets:the structure, after real workFreeFlattened & fusedPolynomial-non-injectiveAttacker gets:an equivalent program, not yoursFreeDestroyed & fusedExponential — provenance, staticAttacker gets:behaviour, not your structurePlannedFree spans the first two classes. Provenance-destroying fusion is planned and not available on any tier today.Each class is a cost, not a wall — and the cost is charged again on your next build.

The classes

ClassWhat a static attacker recoversTier
Renamed & encoded (polynomial-injective)The structure, with effort. Names and literals take real pattern-recognition work. That work has to be redone on every build.Free
Flattened & fused (polynomial-non-injective)An equivalent program with the same behavior. Control flow is flattened and identities are fused, so several different original computations collapse to the same output. The mapping back to which one you wrote is gone.Free

The Free tier reaches both classes across your entire bundle (the full matrix is in Plans & tiers). Higher presets push harder within those classes. The default preset is light (complexity target 2), so set a stronger preset explicitly for production, for example --preset=hard. At hard, the engine applies control-flow flattening, identity fusion, and constant destruction uniformly across the bundle.

A third class, destroyed & fused, is not available

No build produces it, and no region is ever classed "destroyed & fused". /* @afterpack preset=extreme */ raises a region to complexity target 80 with the string floor on, which is real, measurable protection inside the flattened & fused class.

What recovering a class gets an attacker

What a class gets an attacker depends on what they were after.

  • A secret (an API key, a license threshold, a hardcoded table): neither class hides it on its own. A secret comes out of any program that behaves the way yours does, including the equivalent one recovered from a flattened-and-fused region. Protecting a secret takes a different mechanism. See Protecting a secret.
  • Understanding and cloning your code: the flattened & fused class gives real protection here. The attacker gets a working, readable equivalent, but never proof of which implementation you actually shipped: no attribution, no library fingerprint, no confirmation it is the same algorithm as a specific project it may have come from. See What AfterPack does not replace for the limits of this property.
  • Locating and patching one check (disabling a paywall, flipping one return true): neither class helps much on its own. The attacker only needs to find that one node. Finding it again costs something, and it resets on every release. The anti-tamper transform (transforms.selfIntegrity.enabled) makes a patched build produce garbage instead of running. See Best practices on rotation.

Verify it on your own build

The Protection Map shows the per-token proof: your original source, colored by which class hit each line, with the transform stack behind it on hover. Open the live demo or generate your own with npx afterpack@latest.

Next

  • Threat model: the adversary ladder these classes are scoped against.
  • Protection Map: the per-token view for your own build.
  • Best practices: what to mark and why.
  • Directives: the markers that move a region between classes.
  • Presets: the ladder and the complexity target each rung sets.