Protecting a mobile application against reverse engineering

TRUETECH is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Protecting a mobile application against reverse engineering
Complex
~3-5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Protecting mobile applications from reverse engineering

APK is a zip archive. apktool d app.apk disassembles it in seconds, jadx turns bytecode into readable Java. Without obfuscation, attacker sees class names, method names, logic of license check, API endpoint URLs, hardcoded strings. On iOS the situation is not much better: class-dump recovers Objective-C class headers, Ghidra disassembles native code.

Code obfuscation

Android. R8 (built into Android Gradle Plugin) — minimal entry point. Enabled via minifyEnabled = true in build.gradle and renames classes, methods, fields to a, b, c. But R8 doesn't encrypt strings. Serious string protection requires separate tool.

ProGuard rules must be written manually for each used library — otherwise reflection, Gson serialization, Firebase breaks. Typical pain: @SerializedName on model fields doesn't help if the class itself is renamed to a, and Gson can't create it via reflection. Solution — @Keep or explicit -keep rules for data classes passed through API.

Commercial obfuscators — DexGuard, iXGuard (from Guardsquare) — go further: string encryption, control flow obfuscation (inserting false branches and goto), resource protection, anti-tamper checks. DexGuard integrates into Gradle as plugin, config resembles ProGuard, but capabilities are orders of magnitude greater. Used in banking apps.

iOS. Obfuscating Swift/Objective-C binary is harder — no intermediate bytecode. Options: obfuscator-llvm (LLVM pass for control flow flattening) or commercial iXGuard. Swift function names in public API can't be hidden without ABI consequences, but private logic can be obfuscated.

Flutter. Dart compiles to machine code, which itself provides some protection. reFlutter — tool for Flutter app reverse engineering — can recover names from snapshot if app compiled without strip symbols. Enable in build: flutter build apk --obfuscate --split-debug-info=./symbols. Debug symbols go to separate file, not included in release.

String protection

Hardcoded URLs, keys, server names — first thing strings searches on binary. Minimum — don't store them in code at all (extract to remote config, e.g. Firebase Remote Config). If string must be in app — encrypt and decrypt at runtime via native code (JNI/NDK on Android), so plaintext doesn't show in dex.

Pattern: strings stored as XOR-encrypted byte array, XOR key split into parts in different native functions. Not cryptographically strong, but raises entry threshold.

Anti-debug techniques

ptrace(PTRACE_TRACEME, 0, 0, 0) on Android/Linux — process becomes tracee itself, second ptrace attach from debugger returns error. On iOS equivalent — PT_DENY_ATTACH. Frida bypasses this (not via ptrace, but via task_for_pid), but adds complexity.

Check via /proc/self/status on Android: TracerPid != 0 means debugger attached to process. Framework appdome automatically adds such checks without code changes.

Anti-Frida: Frida injects frida-agent into process via frida-gadget. Detect via checking loaded libraries (/proc/self/maps), presence of frida-server port (27042), filenames in /proc/self/fd. But userspace Frida detection Frida itself bypasses — arms race.

Checking application integrity

On Android verify APK signature at runtime: PackageManager.getPackageInfo() returns signatures list. Hash them and compare with hardcoded value. If signature changed — app is repackaged. Hide the check itself in native code, otherwise trivially patched in smali.

Google Play Integrity API (replacement for SafetyNet Attestation) — more reliable: server receives signed token from Google with verdict MEETS_DEVICE_INTEGRITY, MEETS_STRONG_INTEGRITY. Can't forge without Google servers. Downside — requires network request and API quota.

On iOS — DCAppAttestService (App Attest). Similar mechanism: device gets attestation from Apple, server verifies via Apple API.

Native code and React Native

Business logic that can't be disclosed, move to NDK (Android) or native framework (iOS). Native code is harder to reverse-engineer than Kotlin/Java or JavaScript bundle.

React Native stores all JavaScript in index.android.bundle — regular file inside APK, readable by any JS formatter. Protection: Hermes bytecode (compile via --hermes), bundle encryption via native module that decrypts in memory before loading into engine. Metro Bundler supports custom serializer for this.

Timelines

Basic R8/ProGuard setup with string protection and anti-tamper checks — 3–5 days. DexGuard/iXGuard integration with fine configuration tuning — up to 2 weeks (many iterations to avoid runtime breaking). Native migration of critical logic — separate assessment by scope.