A mobile security team should evaluate hooking and instrumentation detection against the three ways code gets changed while an app runs: libraries injected into the process, functions intercepted on their way in or out, and the traces instrumentation frameworks leave behind. Tie every test to a sensitive flow and to the signal your server should receive. Then validate the policy in observe mode, with your own diagnostic tools and legitimate SDKs in the build, before you enforce it. Scope Android and iOS separately, because their runtimes and techniques differ. Everything here assumes authorised testing on builds you own.
The product view is covered on mobile app hooking detection. The wider runtime picture is covered on mobile RASP.
Know the mechanism
Ask the supplier which mechanisms each check addresses. A single answer for “hooking” hides the detail that matters.
Injected libraries
Code that your build never contained appears in the process. On Android this can happen through process injection on a rooted device or through a library added to a repackaged APK; on iOS it can come from a jailbreak’s injection facility or from a load command added to a re-signed copy.
Function interception
Existing code is redirected. Techniques include patching the first instructions of a native function, changing import table entries, replacing Java methods inside the Android runtime and swapping Objective-C method implementations on iOS.
Framework artefacts
Instrumentation frameworks leave marks: unexpected listening ports, named threads, mapped files and agent code in memory. Attackers rename and relocate these marks, so artefact checks work best alongside checks on the code itself.
| Mechanism | Android example | iOS example | What a check looks at |
|---|---|---|---|
| Injected library | Library loaded from outside the APK | Dynamic library not in the app bundle | Loaded module list against the build |
| Native interception | Patched function prologue | Patched function prologue | Code bytes against the shipped release |
| Managed interception | Replaced Java method | Swapped Objective-C method | Method tables and implementations |
| Framework artefact | Agent thread or port | Agent thread or port | Process and memory state |
How Otukan answers. Otukan checks every mechanism in this table, with separate checks built for Android and for iOS. It compares the libraries loaded into your process with the set your release expects, verifies that protected native functions still match the shipped code and that calls to system and library functions resolve to their genuine addresses, and detects changes to Java and Kotlin method dispatch on Android and Objective-C method replacement on iOS. It also looks for the threads, components and communication channels instrumentation toolkits add. The checks are layered, repeated through the session and hidden by obfuscation, so removing one still leaves the others running.
Define the execution context
Detection only helps if it runs where the risk is and produces something your backend can act on.
The sensitive flow
- Which flows would an attacker instrument: login, one-time code entry, payment confirmation, reward redemption?
- Which functions in those flows carry the decision, and are they in native, managed, Dart or JavaScript code?
- In Flutter and React Native apps, does the decision sit in framework code, in a native plugin, or in both?
Timing
- Do checks run only at launch, or also at authentication and before each sensitive action?
- What happens if instrumentation attaches after the app has started?
The observable signal
- What does your server receive when a check fires, and with which request?
- Can the signal name the check that fired, so your team knows the mechanism?
How Otukan answers. Otukan runs its checks at launch, at authentication and again before the sensitive actions you mark, so instrumentation that attaches late is caught before the step that matters. In Flutter and React Native apps it covers the native layer and the framework runtime. The signal travels to your backend with the login or transaction request and names the layer and the protected function involved, so your analysts can group sessions by technique.
Validate the policy
The fastest way to lose trust in a control is to block your own users. Validate in stages.
Clean baseline
- Run the protected release build on unmodified Android and iOS devices through every key journey, with every flow set to observe.
- Confirm that analytics, crash reporting, performance and accessibility SDKs do not raise detections. Some legitimately swap methods or wrap functions.
Authorised attack runs
| Test case | Setup | Expected detection | Expected response |
|---|---|---|---|
| Library injection | Rooted or jailbroken lab device | Injected module reported | As set for the flow |
| Method replacement | Lab device with a method-swapping module | Managed interception reported | Flow restricted |
| Native patch | Lab device with debugger access | Code change reported | Session ended |
| Late attach | Instrumentation after launch | Detection before the next sensitive step | Step-up or refusal |
Enforcement
- Which flows move from observe to restrict or terminate, and who signs off?
- How are diagnostics handled, given that debug builds used by your engineers differ from the release build?
How Otukan answers. Otukan lets you start each flow in observe and move it to warn, restrict or terminate once your baseline is clean. Our engineers validate the checks with yours against the SDKs and diagnostic tools your release build actually contains, record the libraries it is expected to load, test with assistive features switched on and reproduce each attack case in your authorised lab.
Emulator checks are covered on emulator detection.