obfuscator 0.1.0 copy "obfuscator: ^0.1.0" to clipboard
obfuscator: ^0.1.0 copied to clipboard

Library used to obfuscate Dart and Flutter source code.

0.0.1 #

  • Initial release of the Dart Obfuscator CLI.

0.0.1+1 #

  • Add help flag for CLI command.
  • Fix README.md file errors.
  • Fix various logic errors.

0.0.1+2 #

  • Update README.md file.

0.0.1+3 #

  • Update dependencies.
  • Fix README.md file errors.

0.1.0 #

  • Update dependencies to analyzer 14, dart_style 3.1.12 and package_config 3.
  • Rewrite the rename engine around resolved element identity. Declarations and references are now matched by the element they resolve to instead of by name and parent identifier, which removes the length-preserving replacement constraint and makes runs on large multi-package projects practical.
  • Add --clear, which keeps the declarations and comments of a package, directory or file as written while still rewriting its references to renamed declarations.
  • Preserve the input directory layout in the output, including pub workspaces, assets, symbolic links and part files, so the obfuscated project builds with the same commands as the original.
  • Resolve transitive relative path: dependencies, so naming one entry point package is enough to obfuscate a whole application. Disable with --no-follow-path-deps.
  • Keep names which the language requires to match: overrides, interface and mixin members, field and accessor pairs, initialising and super formals, the named parameters of an override group, redirecting factory parameters, and the branches of a conditional import or export.
  • Never rename the reserved runtime identifiers main, call, toJson, fromJson, toString, hashCode, noSuchMethod and runtimeType, operators, unnamed constructors, anything declared outside of the run, or the named parameters written as part of a function type.
  • Naming a type with --pub now keeps the identifiers of its members too.
  • Rename show/hide combinators, documentation comment references, assignment and increment targets, pattern fields, extension types, typedefs, top-level variables and, with --rename-locals, local variables and functions.
  • Strip comments from obfuscated sources, preserving // ignore: and other analyzer and formatter directives. Disable with --no-strip-comments.
  • Add --seed for reproducible output, --name-length, --root, --format and --pub-get.
  • Emit retained.json alongside mappings.json, recording why each identifier was kept.
  • Rewrite the path: dependencies of the copied packages so that they resolve within the copy. A dependency declared with an absolute path previously pointed back at the original checkout, which built the copied package against unobfuscated sources.
  • Clone directories holding no sources copy-on-write where the filesystem supports it (APFS, Btrfs), so that a shared asset payload does not cost disk space per run.
  • Rework --merge, now opt-in, into a merged library package which the applications of the run import, rather than one file holding everything:
    • Every package without a lib/main.dart is merged into <out>/merged/<name>/lib/merged.dart; each application is copied beside it with its dependencies, imports and package-qualified asset paths rewired onto the merged package.
    • Directives are stripped by their parsed ranges rather than per line. A wrapped import or export previously left its continuation behind as invalid text, and part of was not removed at all.
    • Libraries selected by a conditional import are kept as separate files beside the merged library, with the selecting directive preserved, since only one branch is ever compiled and the branches declare the same identifiers.
    • Asset and font files declared by the merged packages are copied, and the packages/<package>/… references to them are rewritten.
    • ignore_for_file comments are consolidated into one directive, and the per-line ignore comments they subsume are dropped.
    • Import prefixes are no longer available as replacement identifiers, so a generated name cannot shadow a prefix once every library shares one scope.
    • Add --merge-name for the identifier of the generated package.
    • --merge composes with --clear: a cleartext package is kept beside the merged library under its own name, with its own assets and readability, and its references to the merged packages rewired onto it. That delivers a readable plugin over a merged, obfuscated framework.
  • Stop copying a package nested inside another one twice, which also produced a doubled directory when the inner copy was cloned copy-on-write.
  • Rename import prefixes. A prefix is visible only within its own library, so it was never safe to leave one naming the package it points at — and in a merged output, where every library shares one scope, a prefix could collide with any identifier kept as written.
  • Identify a synthesised element by its library URI and full chain of enclosing names rather than by its immediate parent alone, so that the same-named parameters of same-named methods of different classes stay distinct. An element which can be identified no other way keeps its name instead of risking a rename only some of the analysed packages agree on.
  • Treat build output and tooling state as somebody else's code. A Dart file below .dart_tool or build, or in the localisation output directory of a package declaring flutter: generate: true, is regenerated by pub get and by every build: renaming a declaration there was undone by that regeneration while the rewritten references kept the new name, which static analysis did not report and the compiler did.
  • Keep the named parameters of a function referenced as a value rather than invoked. A torn-off function is matched structurally against whatever function type it is assigned to, and only one side of that match can be renamed.
  • Point a preserved conditional directive at the branch files as they were copied beside the merged library, rather than at the package: URIs of the packages that were merged away.
  • Report the identifiers which more than one imported library declares before writing a merged output. Separate libraries may each import a different package offering the same name; once they share one scope the name is ambiguous, and no rename can repair it. Re-exports are not reported, since two imports offering the same declaration are unambiguous.
  • Enumerate the files to rewrite by walking the copied packages, rather than asking each analysis context which files it analyses. A path excluded by an analysis_options.yaml is hidden from analysis but still compiled: its declarations were left as written while every reference to them was renamed, which no analyser reported and every build rejected. Such excludes are additionally relaxed for the duration of the run and restored afterwards, so the analyser resolves the same files the compiler does.
  • Leave a package nested inside the input which the run does not resolve as written, and leave a file no analysis context covers as written rather than failing the run. A vendored build tool carrying its own pubspec.yaml is not part of the program being obfuscated.
  • Keep a nested package which depends on one being obfuscated out of the copy. It is never analysed, so every identifier it refers to stayed as written while the declaration moved underneath it — an application beside a library the run pulled in was delivered unable to resolve the library it consumes. A nested package which depends on nothing of the run, or which a run package depends on, is still copied.
  • Remove the prefix from a reference whose import the merge drops. An import of a merged package disappears, because the library it named is now part of the same file; the references written through its prefix were left qualified by a prefix nothing declared any more. Where the prefix names both a merged library and one which is kept, no rename can repair the reference, and the run reports it.
  • Keep the prefix when repointing an import of a merged package at the merged library. A prefix is a declaration of the importing library and its references were renamed to match, so dropping it while rewiring the import orphaned every one of them. Importing the merged library once per prefix keeps them resolving.
  • Keep the field names of a record pattern. A record's fields are matched structurally, so those names describe the type being destructured rather than any declaration of the run.
  • Rename the shorthand form of a pattern field, case Foo(:final id), as the field it names. That single token is both a reference to the field and the declaration of a variable; the field decides the name, and the variable's own references follow it.
  • Rename a variable shared by the branches of a logical-or pattern together with the variable each branch declares, since the language requires every one of them to be written with the same name.
  • Add an end-to-end test suite: 64 tests covering the rename engine, the reports and both delivery shapes against synthetic multi-package fixtures.
  • Apply every source rewrite through one utility, which reports two rewrites disagreeing about the same range rather than silently keeping one of them, and give the replacement name generator a widening search so that a small --name-length on a large codebase runs out of candidates instead of spinning forever.
  • Refuse to use a shallow output directory, since the location is emptied per run.
5
likes
160
points
86
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Library used to obfuscate Dart and Flutter source code.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

analyzer, args, dart_style, package_config, path, pubspec_parse, yaml, yaml_edit

More

Packages that depend on obfuscator