For more than a decade, the standard playbook of mobile banking malware on Android relied on a simple visual trick: the overlay. A malicious application, having quietly persuaded the victim to grant Accessibility privileges, watched the operating system like a hawk. The moment the user tapped the icon of their mobile banking application, the malware sprang into action, throwing an identical, counterfeit login interface directly over the genuine window. To the user, it appeared as though their bank was requesting their username and password. In reality, their keystrokes were being harvested by an invisible spectator sitting just above the glass. Security vendors and mobile operating system architects responded in kind, building increasingly aggressive heuristics to detect overlay windows, flag abusive accessibility bindings, and terminate rogue processes before they could obscure legitimate financial software.
That defensive cat-and-mouse game rested on an implicit assumption that defined modern endpoint security: as long as the genuine banking application was running inside its own sandboxed process, its internal logic could be trusted to defend itself. If the application checked its own cryptographic signature, inspected the list of active accessibility services, or requested an attestation verdict from Google Play Integrity API, the answers returning to the bank's backend servers were assumed to be honest reports from a pristine client.
In mid-October 2026, cybersecurity research firm ThreatFabric published a technical disclosure that decisively dismantled that assumption. Researchers uncovered a newly emerged Android banking trojan named Hirudo. Rather than fighting Android's accessibility restrictions or attempting to paint deceptive pixel layers over a running banking application, Hirudo takes a radical, surgical path. When it identifies a target financial institution on a victim's smartphone, it prompts the user with a counterfeit update notice, triggers the operating system's native uninstaller to eliminate the genuine banking app, and immediately replaces it with a trojanized clone.
The modified application carries the exact same package name and version number as the official release, but its runtime has been re-engineered from the inside. By injecting a lightweight dynamic hooking engine into the application's foundational initialization code, Hirudo turns the banking application into an active conspirator against its own security architecture. When the application queries Android to verify its cryptographic signature, the hook answers with the bank's genuine certificate. When it scans for unauthorized accessibility tools, the hook returns an empty array. When it requests a hardware attestation token, the traffic is quietly rerouted through the attacker's infrastructure.
The implications of this architectural shift extend far beyond individual malware infections. Hirudo represents the practical death of client-side trust in mobile finance. It demonstrates that an application running in an execution environment controlled or manipulated by an adversary cannot serve as a reliable witness in its own defense. Understanding how Hirudo operates, why it chose Indonesian financial institutions as its primary proving ground, and how mobile security engineering must adapt to survive this paradigm shift is the defining challenge for digital banking in 2026.
๐ฑ The Illusion of the Seamless Screen
The architectural journey of Android financial malware has always mirrored the evolution of Android's internal permission model. In the early days of mobile banking, threats were primitive SMS forwarders and credential scrapers that relied on broad, unmonitored permissions. As Google hardened the Android sandbox throughout the late 2010s, malicious operators migrated en masse to Android's Accessibility Services. Originally designed to empower users with visual and motor disabilities by allowing screen reading and automated input, Accessibility became the universal skeleton key for Android trojans. By abusing Accessibility, malware families such as SharkBot, Anatsa, and Vultur could read text displayed on the screen, inject synthetic taps, and draw overlay windows that perfectly mimicked authentic login flows.
However, the overlay strategy possessed inherent weaknesses that defensive tooling gradually learned to exploit. An overlay is an inherently external operation. It requires two separate processes interacting through the Android Window Manager. Modern banking applications began implementing defensive checks: querying WindowManager.LayoutParams.FLAG_SECURE to prevent screen capture, inspecting the view hierarchy for obscured touch events, and actively querying the system for third-party applications holding active accessibility bindings. Furthermore, Google began restricting Accessibility access for applications downloaded outside certified app stores, while Play Protect gained heuristics designed to flag applications that requested accessibility permissions immediately after installation.
For malware authors, the operational cost of maintaining external overlay infrastructure began to skyrocket. Detection rates were climbing, and legitimate financial applications were increasingly refusing to launch if they sensed an untrusted service monitoring the display. The attackers needed a way to bypass these defensive barriers not by outsmarting them from the outside, but by neutralizing them from within.
This is the strategic leap embodied by Hirudo. Instead of existing as a separate, hostile entity that monitors the banking application through system APIs, Hirudo migrates into the banking application itself. By replacing the entire executable package with a modified clone, the trojan eliminates the need for visual deception. The user does not interact with a counterfeit overlay sitting on top of the bank; they interact with the authentic banking application, compiled from the bank's own code, rendering the bank's own design system, connecting to the bank's own production API endpoints. The only difference is that the foundational execution environment inside the application has been systematically falsified.
The attack begins through seemingly innocuous distribution vectors known as droppers. ThreatFabric discovered that Hirudo's operators disguise their initial payload within consumer applications that offer immediate, engaging utility: third-party shopping portals, micro-drama streaming platforms, and adult video players. These droppers are not crude mockups. They embed legitimate WebViews that load authentic web content, allowing the user to browse products or watch videos without encountering immediate friction. Behind this operational facade, however, the dropper immediately initializes an environment discovery routine.
The dropper requests notification access and Accessibility permissions, often framing the prompt as a necessary enhancement for video playback performance or interface personalization. The moment Accessibility is granted, the dropper queries Android's package manager to build a complete inventory of every financial application installed on the handset.
๐ The Forced Uninstallation Handshake
Once Hirudo identifies a target banking application on the device, it encounters the primary cryptographic hurdle of the Android operating system: the APK signature verification model. Android enforces a strict security policy known as signature matching. When an application update is installed, the package manager checks whether the cryptographic signature of the incoming APK matches the signature of the currently installed application. If the certificates do not match, Android immediately aborts the installation with an incompatible update error.
Because Hirudo's operators do not possess the bank's private signing keys, they cannot create an update that Android will accept over the top of the legitimate installation. A patched APK signed with an arbitrary developer certificate or an Android Open Source Project test key cannot coexist with or overwrite the genuine software. The genuine application must be completely removed from the filesystem before the trojanized version can take its place.

To accomplish this without raising immediate suspicion, Hirudo orchestrates a carefully timed social engineering sequence. First, the dropper displays a system-style dialog informing the user that their mobile banking application requires an urgent, mandatory security update to maintain compatibility with new banking regulations or backend infrastructure. Before the user has time to evaluate the authenticity of this message, Hirudo uses its accessibility privileges to initiate the native Android uninstallation flow for the genuine banking app.
In standard Android operation, uninstalling an application requires an explicit confirmation tap on an operating system prompt. Hirudo's accessibility automation handles this constraint with aggressive precision. In observed campaign variants, the trojan launches the uninstallation intent and immediately attempts to automate the confirmation click through Accessibility before the user fully registers what is transpiring on the screen. Simultaneously, the dropper establishes a background HTTP connection to its content delivery infrastructure to retrieve the pre-compiled, trojanized APK tailored specifically for that targeted financial institution.
To protect this critical download and installation phase from defensive scrutiny, Hirudo incorporates an ingenious network evasion technique. During the installation routine, the dropper can establish a deliberately malformed local VPN connection on the device. By creating a loopback VPN interface that lacks functional routing tables, the malware temporarily severs the device's internet connectivity during the exact seconds that the malicious APK is being unpacked and installed by Android's package installer.
This tactical network blackout serves a specific defensive objective: it disrupts Google Play Protect's real-time cloud lookup mechanisms. When an unknown application is sideloaded, Play Protect attempts to transmit package telemetry, code hashes, and behavioral metadata to Google's backend servers for dynamic scanning and reputation scoring. By momentarily starving the network socket, Hirudo increases the likelihood that the local installer will fall back to local cached verification heuristics, allowing the trojanized package to finalize installation without triggering an immediate cloud-based blocking warning. Once the installation completes, the broken VPN is dismantled, network routing restores, and the compromised application sits quietly on the user's home screen, ready for execution.
๐งฌ One Line in the Application Class
What makes Hirudo exceptionally dangerous from a software engineering perspective is how little of the bank's original codebase is actually modified. Attackers who attempt to reverse-engineer complex enterprise applications often introduce instability. When an APK is decompiled, altered extensively, and recompiled using tools like Apktool or Smali assemblers, internal obfuscation maps can break, native library bindings can fail, and dynamic resource references can cause the application to crash at launch.
Hirudo completely sidesteps this instability. An inspection of the trojanized banking packages decompiled by ThreatFabric revealed that the attackers did not tamper with the bank's business logic, account dashboards, or transaction signing routines. Instead, they added precisely one line of execution code into the application's top-level Application subclass, within the initialization lifecycle methods.
That single native library invocation bootstraps an advanced runtime hooking architecture composed of two well-known open-source instrumentation frameworks: YAHFA (Yet Another Hook Framework for Android) and Dobby. YAHFA is designed for high-performance Java and Dalvik or ART method hooking, allowing arbitrary bytecode methods to be intercepted and rerouted before or after execution. Dobby, meanwhile, operates at the native binary level, hooking C and C++ functions within shared object libraries loaded into the process memory space.
The operational brilliance of Hirudo lies in its dormant triggering mechanism. The injected native library does not begin manipulating the application immediately upon launch. If a security analyst or an automated malware sandbox executes the trojanized banking APK in isolation, the hooking engine remains entirely inert. It searches the local filesystem for a specific, transient trigger file written to external storage by the companion dropper application.
If that trigger file is absent, the hooking framework terminates its initialization routine silently. The banking application proceeds to execute its standard code paths, behaving in every respect like the genuine, unblemished banking client. It will even fail authentication or display connection errors normally, exhibiting none of the anomalous behaviors that automated threat-scoring sandboxes look for. Only when the trojanized app confirms that it is running on a compromised handset alongside its controlling RAT does the hooking engine awaken and seize control of the process runtime.
๐ญ The Architecture of Fabricated Innocence
Once awakened inside the banking process, the YAHFA and Dobby engines establish a comprehensive virtual reality layer between the banking application and the underlying Android operating system. The application believes it is speaking to an authentic, uncompromised platform, while Android believes it is hosting a compliant, secure application.
The primary defensive mechanism that banking applications use to detect tampering is signature self-inspection. Upon startup, robust financial software calls Android's package manager API to query its own package information, specifically checking the signatures or signing info structures returned by the system. If the certificate hash returned by the operating system does not match the hardcoded public key of the bank's official production release, the application terminates immediately, assuming it has been recompiled or sideloaded.
Hirudo renders this check completely obsolete through targeted method hooking. YAHFA places an inline hook on the package manager getPackageInfo method. Whenever the banking code requests its own package metadata, the hook intercepts the return value. Instead of returning the Android test certificate that was actually used to sign the installed APK on the disk, the hook substitutes the cryptographic signature of the bank's genuine, legitimate certificate, which the malware operators extracted from the official Google Play release and stored as a static byte array within the trojan's payload.
The deception does not stop at signature verification. To prevent the bank from realizing that a malicious dropper is actively controlling the device, Hirudo hooks the system services responsible for reporting accessibility state. When the banking application queries the list of enabled accessibility services, the hook intercepts the execution pipeline and scrubs the list, removing any entry corresponding to the dropper or the trojan's background services. The banking application evaluates the filtered list, concludes that no suspicious screen-reading services are active on the device, and disables its internal overlay defense shields.
Simultaneously, the hooking engine addresses visual security controls. Standard banking applications protect sensitive interfaces, such as account numbers, balances, and credential entry fields, by setting the secure window flag on their window instances. This flag instructs Android's SurfaceFlinger compositor to block screen capture, preventing local applications from recording the display and causing remote desktop tools to render a completely black screen.
Hirudo uses its native Dobby hooks to intercept calls to the window flag manipulation routines. When the application passes the secure flag, the hook masks the bitwise argument, stripping the flag before it reaches the window management service. To the banking code, the method call executed successfully without throwing an exception. To the operating system, the secure window flag was never set. As a result, the trojan's background operator can stream high-definition video of the victim's banking session directly to a remote command-and-control server, capturing PINs, biometric authentication prompts, and multi-factor SMS codes as they appear on the glass.
๐ก๏ธ The Play Integrity Relay and the Illusion of Attestation
To counter the rise of sophisticated on-device tampering, the Android ecosystem has increasingly converged on Google Play Integrity API. Play Integrity is designed specifically to solve the problem of client trust. Instead of asking the application to inspect itself, Play Integrity delegates the evaluation to Google Play Services and secure hardware elements such as ARM TrustZone or dedicated hardware security modules like the Titan M chip.
The API produces a cryptographically signed token containing three distinct verdicts:
- App licensing verdict: verifies whether the application was obtained through Google Play.
- App integrity verdict: verifies whether the running binary matches the exact cryptographic hash of the package registered by the developer in the Google Play Console.
- Device integrity verdict: verifies whether the application is running on a certified Android device with an intact, locked bootloader and hardware-backed trust anchors.
In theory, Play Integrity should have stopped Hirudo in its tracks. Because the trojanized application was signed with a test key and sideloaded via an unauthorized dropper, any genuine call to Play Integrity should return an unrecognized version or unlicensed verdict, prompting the bank's backend servers to reject the session.

ThreatFabric's analysis revealed how Hirudo's operators successfully subverted this defense. Rather than attempting to break Google's cryptographic token signing, Hirudo exploits a widespread architectural flaw in how financial institutions implement Play Integrity: client-side evaluation and unsecured token relaying.
When the trojanized banking application initiates an integrity handshake, the hooking engine intercepts the network request. Instead of allowing the device's local Google Play Services client to generate a fresh hardware-attested token, Hirudo routes the request over plain HTTP to an external attestation server controlled by the malware infrastructure. This remote server acts as an integrity proxy.
ThreatFabric's forensic investigation uncovered an even more alarming detail regarding Hirudo's attestation infrastructure. The remote server was utilizing a leaked, public keybox containing compromised device certificates to forge attestation structures. Google had already identified this specific keybox leak and added two of its primary certificates to the Android revocation list months earlier.
Had the targeted banks performed rigorous, real-time server-side validation of the Play Integrity token against Google's verification APIs, the presence of revoked certificates in the token chain would have immediately triggered a high-severity alert. However, because several targeted institutions either evaluated the integrity payload on the handset itself or performed superficial client-side response checks, the forged verdict was accepted as authentic proof of a pristine device.
This finding exposes a critical vulnerability in the modern API security lifecycle. A cryptographic integrity token is not an amulet that wards off evil through its mere existence. If an application accepts an integrity response without validating its cryptographic signature, nonce freshness, and revocation status on a hardened backend server, the entire integrity architecture collapses into theater.
๐ฏ The Indonesian Proving Ground
While Hirudo's underlying codebase contains references and targeting registries for 42 financial institutions across multiple continents, including China, India, Mexico, Morocco, and Thailand, ThreatFabric observed that the active deployment campaign was overwhelmingly concentrated on one specific market: Indonesia.
Of the 42 tracked financial targets, exactly eight mobile banking applications, spanning seven major Indonesian commercial and regional banks, had complete, pre-compiled trojanized packages actively hosted on the attackers' distribution infrastructure. The malware authors had systematically decompiled the official Indonesian banking apps, injected the YAHFA and Dobby loader hooks, and compiled ready-to-deploy replacement APKs tailored to each bank's unique package namespace.

The operational infrastructure supporting this Indonesian campaign was remarkably sophisticated, leveraging enterprise-grade cloud services to maximize delivery speed and evasion. The malicious droppers and tailored banking packages were not distributed through obscure, suspicious web forums. They were hosted on Amazon CloudFront content delivery networks, utilizing dynamic URL routing and domain fronting to ensure high availability and bypass local Indonesian ISP filtering.
Furthermore, the operators integrated commercial mobile marketing and attribution frameworks directly into the malware deployment pipeline. ThreatFabric discovered that the campaign utilized OpenInstall attribution SDKs to track infection funnels, monitor conversion rates across specific advertising channels, and link individual device infections to specific Meta Pixel tracking IDs. The attackers were running their malware distribution with the operational rigor of a venture-backed growth marketing agency, analyzing which landing pages and lure creatives yielded the highest rates of successful app uninstallation and replacement.
A catastrophic operational security failure on the part of the attackers provided researchers with an unprecedented look inside Hirudo's operational scale. The command-and-control dashboard and administrative APK-processing pipeline were discovered exposed to the public internet without authentication. Inside the exposed cloud storage buckets, researchers identified thousands of active victim records dating through August, September, and October 2026.
These database entries were not mere collections of usernames and passwords. The operators maintained meticulously structured financial dossiers on their victims. Each record was tagged with device identifiers, operating system build versions, screen-lock histories, and extracted transaction limits. Most tellingly, the database contained dedicated fields for estimated monthly income and financial risk scoring, alongside manual operator annotations labeling specific records as phished and ready for balance liquidation. The operation was not engaged in opportunistic data collection; it was executing a systematic, industrial-scale financial extraction pipeline aimed directly at Indonesian banking customers.
๐๏ธ The Fallacy of the Self-Witnessing Client
The emergence of Hirudo forces a fundamental re-examination of the foundational assumptions that govern mobile application security. For years, the mobile security industry has peddled the concept of in-app protection or Runtime Application Self-Protection. Vendors sell SDKs that promise to make an application self-defending by embedding routines that check for root access, detect debugging bridges, inspect running processes, and verify binary integrity.
Hirudo exposes the fatal theoretical flaw at the heart of this approach: an application running within an execution context controlled by an attacker cannot be trusted to report its own state.
In computer science, this principle was articulated with devastating clarity by Turing Award laureate Ken Thompson in his landmark 1984 paper, Reflections on Trusting Trust. Thompson demonstrated that you cannot trust code that you did not entirely create yourself, and more importantly, you cannot trust the output of a program if the underlying compiler or interpreter has been compromised. In the context of modern mobile operating systems, the application is entirely at the mercy of its runtime. If an adversary can modify the binary or hook the process execution space, any question the application asks about its own integrity will be answered by the adversary.
When an application relies on client-side security checks to make critical decisions, it engages in circular reasoning. It asks a compromised runtime whether the runtime is compromised. If the hooking framework is competent, it simply intercepts the query and returns the expected, benign answer.
The failure of client-side self-attestation is not an Android-specific vulnerability; it is an unavoidable property of client-server distributed computing. The moment an executable file resides on physical hardware owned and operated by a third party, the integrity of that client must be treated as zero until proven otherwise by external, unfalsifiable evidence. The fact that the financial sector relied so heavily on client-side checks for so long is a testament to the convenience of the abstraction, not its cryptographic validity.
๐ The Post-Handset Security Architecture
If an application running on a smartphone can no longer serve as a witness to its own integrity, how can mobile financial institutions protect their systems and their customers from threats like Hirudo? The answer requires a decisive migration toward a zero-trust, server-side defensive architecture where security decisions are decoupled from client-reported verdicts.

The first and most urgent reform is the mandatory implementation of rigorous, server-side cryptographic verification for mobile attestation tokens. Google Play Integrity API remains a powerful defensive instrument, but only when its tokens are decrypted, parsed, and validated on the bank's backend servers through Google's official REST APIs.
A compliant server-side implementation must verify three non-negotiable parameters:
- Cryptographic signature verification: The backend must independently verify the Google-signed certificate chain accompanying the integrity payload, rejecting any token signed with revoked or unauthorized keys.
- Nonce freshness and session binding: The integrity request must originate from the server with a cryptographically random, single-use nonce that is inextricably bound to the specific banking transaction or authentication session. This prevents replay attacks where an attacker captures a valid integrity token from a clean device and relays it to validate an unverified session.
- Direct Google API verification: Rather than trusting pre-computed token claims, the bank's backend must query Google's verification endpoints directly, ensuring that the package name, certificate sha256 digest, and licensing status match production records with zero tolerance for deviations.
Beyond attestation token verification, financial institutions must abandon binary security gates in favor of continuous, behavioral risk scoring. A banking application should never authorize a high-value transfer simply because a login screen was completed successfully. Modern risk engines must evaluate contextual telemetry that cannot be easily faked by a local hooking engine: the network autonomous system number, the behavioral cadence of user input such as keystroke dynamics, touch surface area, accelerometer stability during interaction, and the velocity of transactions relative to historical baselines.
For smartphone users and banking consumers, Hirudo serves as a sobering reminder of the physical limits of mobile security. The single most effective defensive habit against this new breed of trojan is simple: never allow an application to be uninstalled as part of an update routine.
Legitimate software updates on Android, whether distributed through Google Play or direct enterprise channels, never require the user to uninstall the existing application first. An update that demands an uninstallation is, by definition, an update that cannot satisfy Android's cryptographic signature check. If an application informs you that it must be uninstalled to receive a new version, that prompt is not an update; it is an eviction notice served by an intruder preparing to move into your digital home.
As mobile operating systems continue to evolve, the boundary between legitimate functionality and malicious capability will remain contested. By dismantling the illusion of client-side integrity, Hirudo has performed an involuntary service for the cybersecurity community. It has forced the industry to confront an uncomfortable truth that software architects should have embraced long ago: security that depends on the honesty of a compromised machine is no security at all.
Sources: ThreatFabric Research (Hirudo: from fake updates to patched banking apps, October 2026); SecurityAffairs (Hirudo Android Trojan Replaces Banking Apps to Steal Credentials); Approov Mobile Security Analysis (Ted Miracco, October 2026); Android Open Source Project (APK Signature Scheme v2/v3/v4 Documentation); Google Play Integrity API Architecture Guide.


