Guide

Mobile code obfuscation guide

Evaluate code obfuscation on your own app: list what needs hiding, compare a baseline and a protected build side by side, then judge the cost to engineers.

  • Know what matters

    List the logic, strings and libraries that would hurt you if read. Protection effort should follow that list, not a default setting.

  • Same tasks, two builds

    Give an analyst the unprotected and the protected build and the same questions. The difference in what they recover is your evidence.

  • Cost to your team

    Good obfuscation keeps crash traces readable and releases routine. Judge it on debugging and upkeep as well as on hiding.

Evaluate code protection against your own app, not a sample the supplier chose. Begin with an inventory of the logic, strings and dependencies that would harm you if someone read them. Then protect a real release build and give the protected and unprotected versions the same analysis tasks, so the difference is measured rather than described. Finally, judge the result on what it costs your engineers in debugging, crash diagnosis and release upkeep. Obfuscation makes analysis slower and costlier; runtime checks cover what happens once the app is running. Android, iOS, Flutter and React Native each get their own test.

What Otukan’s obfuscation does is covered on mobile code obfuscation. Other buyer aids are on solution guides.

Build a code inventory

An attacker reads the parts of your app that pay off. Your inventory should name those parts before any tool touches the build.

Sensitive logic

  • Which code decides money, access or entitlement: fee and discount rules, licence checks, reward logic, transaction signing?
  • Which code talks to your backend, and which request formats would help someone script your API?
  • Which code contains your own security checks, which an attacker would look for first?

Strings and embedded data

  • Which endpoints, lookup keys, feature flags and error messages sit in the binary as readable text?
  • Which configuration files and bundled assets reveal how the app works?
  • Are any secrets embedded that should instead come from the server at run time?

Dependencies and framework layers

Where your code lives decides which protection applies. Record it per platform.

AssetWhere it sits on AndroidWhere it sits on iOS
App logicDEX bytecode from Kotlin or JavaCompiled Swift or Objective-C code, with Objective-C class and selector names readable in runtime metadata
Native codeShared libraries in the APK or bundleFrameworks and dynamic libraries in the app bundle
Flutter codeCompiled Dart in the app’s native libraryCompiled Dart in the app framework
React Native codeJavaScript or Hermes bytecode bundle in assetsJavaScript or Hermes bytecode bundle in the app bundle
Third-party SDKsVendor libraries and their rulesVendor frameworks

Design the test: baseline against protected

A fair test holds everything constant except protection. Build both versions from the same commit, with the same configuration, as release builds.

Analysis tasks

Run these tasks on both builds in an authorised setting, and note what the analyst recovered and how hard it was:

  1. Find the function that performs a named sensitive action, starting from its screen.
  2. Search the binary for a known endpoint or error message.
  3. Follow the path from a button tap to the network call it triggers.
  4. Locate a native function by name and read its logic.
  5. Recover readable Dart or JavaScript logic from a Flutter or React Native build.
  6. Remove one of the app’s own security checks and run the result.

Recording results

TaskBaseline buildProtected buildAnalyst notes
Find a sensitive functionRecovered or notRecovered or notEffort and route taken
Find a known stringRecovered or notRecovered or notWhere it appeared
Trace a flow to the networkRecovered or notRecovered or notWhere the trail broke
Remove a security checkRan or notRan or notWhat stopped it

How Otukan answers. Otukan renames classes, methods and fields to meaningless names, stores strings in protected form until the moment they are needed, restructures control flow in the code you choose, protects bundled configuration and assets, and strips and transforms C and C++ native libraries. It protects Dart code in Flutter apps and JavaScript or Hermes bytecode in React Native apps directly, not only the native shell around them. Our engineers sit with yours to compare decompiled output of both builds, task by task. Task six is where obfuscation meets anti-tampering: Otukan hides its own integrity checks inside the protected code, detects altered code at run time and sends a tamper signal to your backend.

Decide on debugging, crash diagnosis and upkeep

Protection your engineers cannot live with gets switched off. Weigh these criteria as heavily as the analysis results.

Debugging

  • Can developers keep debugging unprotected builds while QA tests protected ones?
  • How are names kept for reflection, serialisation, dependency injection and third-party SDKs?

Crash diagnosis

  • Does each protected build produce a private mapping file your crash reporting can use?
  • Do dSYM files on iOS and native symbols on Android still translate stack traces?
  • Has a deliberate test crash in the protected build been translated back to readable source lines?

Release maintenance

  • Is protection configuration kept in version control and reviewed like code?
  • What happens when a new dependency arrives or a keep rule is missing?
  • Can heavier transforms be limited to sensitive code?
CriterionQuestion to answerWhat good looks like
DebuggabilityCan engineers work normally?Protection applies to release builds only
Crash diagnosisAre traces readable?Test crash maps back to source
UpkeepDoes each release need manual work?Configuration is versioned and repeatable
Scope controlCan protection be targeted?Heavier transforms where you choose

How Otukan answers. Every protected build ships with a private mapping file, and native symbols stay available to you for crash analysis. Otukan maintains the keep list with your team and leaves third-party SDKs as their vendors ship them. Each release also comes with a list of the strings Otukan protected, so reviewers can confirm the sensitive ones were covered. It fits your existing build and release pipeline, and your signing keys stay with your team. To turn industry mobile security index findings into a test of your own binary, see mobile security index analysis.

The wider comparison with build-tool shrinking is covered on ProGuard vs mobile app shielding. The wider evaluation against reverse engineering is covered on the anti reverse engineering solution guide.

Common questions

  • Does code obfuscation stop reverse engineering?

    No. Obfuscation makes analysis slower and costlier, and runtime checks cover what happens once the app is running. The guide asks you to measure the difference on your own app by giving an analyst the same tasks on a baseline build and a protected build.

  • Does Otukan protect Flutter and React Native code?

    Yes. Otukan protects Dart code in Flutter apps and JavaScript or Hermes bytecode in React Native apps directly, not only the native shell around them. Android, iOS, Flutter and React Native each get their own test in the evaluation.

  • How do we compare protected and unprotected builds fairly?

    Build both from the same commit, with the same configuration, as release builds. Run the same analysis tasks on each in an authorised setting, such as finding a sensitive function or a known string, and record what was recovered. Otukan’s engineers compare decompiled output with yours, task by task.

  • Will obfuscation make crash reports unreadable?

    No. Every protected build ships with a private mapping file, and native symbols stay available to you for crash analysis. The guide recommends translating a deliberate test crash in the protected build back to readable source lines before you rely on it.

  • How are third-party SDKs and reflection handled?

    Otukan leaves third-party SDKs as their vendors ship them and protects your code around them. It maintains a keep list with your team for names used by reflection, serialisation, dependency injection and third-party SDKs, and you choose where heavier transforms apply.

See your own code, protected

Tell us your platforms, whether the app is native, Flutter or React Native, and which code you most want to keep private. We will not ask you to send source code, binaries or signing keys.

Or request a technical demo