Exploiting Android Apps with Counterfeit Art
Philipp Mao (Security Researcher · Independent), Rokhaya Fall (Security Researcher · Independent)
OffensiveCon 2026 · Day 2 · Main Stage
Overview
This talk, "Exploiting Android Apps with Counterfeit Art," presented by Philipp Mao and Rokhaya Fall, delves into a novel and powerful technique for escalating file override vulnerabilities in Android applications to arbitrary code execution. The speakers introduce the ART image file, a core component of the Android runtime, as a universal and writable target for such exploits. While file override bugs are common, turning them into reliable code execution has historically been challenging due to restrictions on writing to executable code within an app's sandbox. Mao and Fall demonstrate that manipulating the ART image bypasses these limitations, opening a new avenue for attackers.

Key moments
- 0:00 Introduction and problem motivation
- 2:00 Introducing the 'app image' file
- 3:00 App image creation and loading mechanism
- 3:55 Handling pointers and memory relocation in app images
- 5:00 Bypassing app image header checksums
Exploiting Android Apps with Counterfeit Art
Speakers: Philipp Mao (Security Researcher, Independent), Rokhaya Fall (Security Researcher, Independent)
Conference: OffensiveCon
YouTube: https://www.youtube.com/watch?v=FikuvF6Ot_E
Overview
This talk, "Exploiting Android Apps with Counterfeit Art," presented by Philipp Mao and Rokhaya Fall, delves into a novel and powerful technique for escalating file override vulnerabilities in Android applications to arbitrary code execution. The speakers introduce the ART image file, a core component of the Android runtime, as a universal and writable target for such exploits. While file override bugs are common, turning them into reliable code execution has historically been challenging due to restrictions on writing to executable code within an app's sandbox. Mao and Fall demonstrate that manipulating the ART image bypasses these limitations, opening a new avenue for attackers.
The research unveils two distinct exploitation methods: a local attack that requires an ASLR (Address Space Layout Randomization) leak, and a remote, fully blind attack that leverages the Android runtime's internal relocation mechanisms. Both techniques ultimately lead to code execution within the context of the vulnerable application, often a critical step towards privilege escalation. The significance of this work lies in transforming a common, often underestimated vulnerability into a potent primitive for gaining control over Android apps, highlighting a fundamental weakness in how the Android runtime handles its cached C++ objects.
The findings presented are highly relevant for both offensive and defensive security researchers. For attackers, it provides a blueprint for escalating file write vulnerabilities that were previously considered less severe. For defenders, it underscores the critical importance of rigorously validating file paths in all applications and implementing robust integrity checks for sensitive system components like the ART image. The speakers illustrate the practical impact of their research with concrete proof-of-concept demonstrations against real-world Android devices and applications, including privilege escalation on OnePlus phones and exploitation of Samsung devices.
Background
▶ Watch: Introduction and problem motivation (0:00)
File override vulnerabilities in Android applications occur when an attacker can supply a file path, and the application subsequently writes attacker-controlled data to that specified location. These vulnerabilities often arise from common programming errors, such as improper handling of attacker-controlled input in scenarios like decompressing zip files without adequate path validation (leading to path traversal), or other unchecked file I/O operations. Such bugs are not uncommon; the speakers note at least four prominent instances in the last two years, including a talk at a previous OffensiveCon.
Historically, exploiting file override vulnerabilities to achieve code execution within an Android app's sandbox was more straightforward. Older Android versions allowed apps to write secondary DEX files (files containing Java bytecode) to their private directories, which could then be loaded and executed. However, this capability has been largely removed or restricted, making it much harder for an attacker to overwrite executable code by default. Modern Android apps typically either store native libraries in private directories (requiring custom app behavior) or rely on opt-in Google Play features for dynamic code loading, neither of which is a universal target. This created a significant gap: while file overrides were frequent, a reliable, generic method to turn them into code execution was missing.
Mao and Fall introduce the ART image file (with a .art extension) as the critical missing piece. The ART image is a file used by the Android Runtime (ART), the core component responsible for executing Java code on Android. ART is written in C++, and every Java concept (functions, classes, fields) has a corresponding C++ mirror object. To speed up app startup, ART caches these C++ mirror objects to disk in the ART image file. This file is stored in the app's private directory, making it writable by the app at runtime. This crucial detail means that any arbitrary file override vulnerability can target and overwrite the ART image.
The process works as follows: the first time an app starts, ART parses the app's DEX files (Dalvik Executable files containing bytecode), populates a memory region with C++ mirror objects, and then dumps this entire region, prefixed with a header, to the ART image file on disk. On subsequent app launches, instead of reparsing DEX files, ART directly loads this cached ART image from disk, theoretically accelerating the app's startup time.
A key aspect of the ART image is its structure, particularly how it handles pointers. C++ objects within the ART image memory region can point to three distinct memory regions: the app image itself, the app's OAT file (ahead-of-time compiled Java code), and the boot image (containing ART images and OAT files for the Android framework). The ART image header contains base addresses for these regions (image_begin, oat_file_begin, boot_image_begin). This allows ART to relocate pointers if ASLR shuffles memory addresses between app launches.
Before an ART image is fully loaded and processed, ART performs two checksum verifications on the header: the oat_image_checksum and the boot_image_checksum. The oat_image_checksum verification is effectively useless, as it always succeeds if the value in the header (which an attacker can control) is zero. However, the boot_image_checksum verification is critical. This checksum is an XOR sum of all ART images of the Android framework. An attacker can bypass this by calculating the correct checksum offline, provided they have access to the target phone's firmware version. This establishes a key constraint: the exploitation technique is tied to the specific firmware version of the target device.
Key Findings
▶ Watch: Introducing the 'app image' file (2:00)
The central discovery of this research is the identification of the ART image file (.art extension) as a universally available and writable target within an Android app's sandbox. This resolves the long-standing challenge of escalating file override vulnerabilities to code execution in modern Android environments, where direct modification of executable code is heavily restricted. The ART image, being a cached representation of C++ objects fundamental to the Android Runtime, provides a powerful new primitive for attackers.
The speakers developed and demonstrated two distinct methodologies for crafting a malicious ART image that achieves code execution:
- Local Attack (ASLR-Dependent): This technique leverages a vulnerability in the LZ4 decompression process used by ART. By manipulating an attacker-controlled
image_offsetin the ART image header, an out-of-bounds write can be triggered during decompression. This results in a relative arbitrary write primitive within the "low mem ART range." The attack then targets theentry_point_from_quick_compiled_codefunction pointer of a specific ArtMethod object (e.g.,java.lang.Thread.run) within the Android framework'sboot.artimage. This allows for immediate hijacking of program control flow. The primary limitation is its reliance on an ASLR leak to determine the randomized offset between the app's ART image and the framework'sboot.artimage.
- Remote Attack (Blind, ASLR-Independent): This more sophisticated technique bypasses the need for an ASLR leak by intelligently leveraging ART's relocation mechanism and a logic bug in the ClassLinker component. The core idea is to inject custom Dalvik bytecode directly into the crafted ART image. By creating a minimal app image with a custom class and an
ArtMethod(acting as a constructor), theentry_point_from_quick_compiled_codeis set to point to the Dalvik bytecode interpreter's entry point (enter_trampoline). To ensure the injected bytecode itself is properly referenced and relocated, the attackers exploit a specific interaction: they set theArtMethod'saccess_flagstoabstractto prevent theClassLinkerfrom incorrectly modifying thedataattribute (which points to the bytecode). Furthermore, they overlay an ArtField section on top of theArtMethod'sdataattribute, allowing theArtFieldvisitor to relocate this pointer to the injected bytecode within the app image's object section. This highly intricate manipulation ensures that the custom bytecode is executed when theArtMethodis initialized.
Both techniques were successfully demonstrated in real-world scenarios:
- The local attack was used to achieve zero-click privilege escalation from an untrusted app to system privileges on Oxygen OS (OnePlus 12R) by combining it with vulnerabilities allowing touch event injection and a path traversal in the OnePlus Backup app.
- The remote attack was integrated into a variant of an existing exploit chain for the Samsung Galaxy S24, targeting the Samsung Quick Share Agent to gain code execution in a platform app context.
These findings fundamentally change the risk assessment of file override vulnerabilities on Android, establishing them as a direct path to code execution and often privilege escalation, provided the ART image can be targeted.
Technical Deep Dive
▶ Watch: App image creation and loading mechanism (3:00)
The core of this research revolves around the manipulation of the Android Runtime (ART) and its ART image caching mechanism. ART is a C++ codebase that mirrors Java concepts into C++ objects. When an Android app starts, ART parses the app's DEX files and constructs these C++ mirror objects in memory. To optimize subsequent launches, ART "dumps" this memory region into a file, the ART image, which is then loaded directly. This file is critical because it contains serialized C++ objects, including pointers, which need to be correctly resolved when loaded into a new memory layout.
The ART image header contains crucial information, including image_begin, oat_file_begin, and boot_image_begin. These fields represent the base addresses where the app image itself, the app's OAT file (ahead-of-time compiled code), and the boot image (containing framework ART images and OAT files) were mapped when the ART image was created. When the ART image is loaded, these base addresses, along with corresponding sizes, define memory ranges. The relocation mechanism uses these ranges to fix pointers within the loaded ART image, adjusting them to the current ASLR-randomized base addresses.
Local Attack: ASLR-Dependent Arbitrary Relative Write
The local attack leverages a specific vulnerability during the decompression phase of ART image loading. After initial checksum verifications, the compressed body of the ART image is decompressed into a memory region referred to as the app image memory region. This region resides in the "low mem ART range," where ART-specific components like the Java heap and OAT files are mapped.
The vulnerability lies in the use of the LZ4 decompression library. The code responsible for decompression takes an out_pointer (the base address of the app image memory region) and an image_offset (uint32) from the attacker-controlled ART image header. Critically, there is no check to ensure that image_offset does not exceed the size of the app image memory region. This allows an attacker to specify an image_offset that points beyond the allocated buffer, leading to an out-of-bounds write during decompression. Since the out_pointer is the base of the app image memory region, this effectively grants a relative write primitive from that base address, with attacker-controlled size and data, anywhere within the low mem ART range.
The target for this arbitrary relative write is a specific C++ object within the framework's boot image: an ArtMethod object. ArtMethod objects represent Java functions. When Java code calls a function, the corresponding entry_point_from_quick_compiled_code function pointer within the ArtMethod object is invoked. The attackers target the ArtMethod for java.lang.Thread.run, a function guaranteed to be called almost immediately after an app starts. By overwriting this function pointer with a controlled address, the attackers can hijack the program counter (PC).
This attack requires an ASLR leak because the distance between the app image memory region (where the write originates) and the boot.art image (where the target ArtMethod resides) is randomized. Knowing this offset allows precise targeting. Once the PC is hijacked, obtaining full code execution is straightforward in an ASLR-leaked scenario. The X0 register, when the ArtMethod is called, points to the ArtMethod object itself, allowing for the setup of a ROP chain by placing controlled data near X0 and calling system(). A key advantage of this local attack is that it doesn't require the ART image loading process to complete successfully; the decompression and subsequent function call can happen even if the rest of the loading fails.
Remote Attack: Blind Code Execution via Relocation and Section Overlay
The remote attack is designed to work blindly, without an ASLR leak. It exploits ART's relocation mechanism and a subtle logic bug in the ClassLinker.
- Leveraging Relocation: ART's relocation mechanism is "object aware," meaning it understands the structure of C++ objects. It iterates through sections of the ART image, identifying pointers and attempting to relocate them to the correct memory ranges (app image, boot image, OAT file). For object pointers, it attempts to fit them into the app image range or boot image range. For code pointers, it tries the boot image range or OAT file range. If a pointer fits a range, its offset from the range's base is calculated and added to the actual loaded base address of that range, effectively fixing the pointer.
- Crafting a Malicious ART Image: The attackers create a minimal ART image containing a single class and an associated
ArtMethod. By making thisArtMethoda constructor, it's guaranteed to be invoked during app initialization. Thedeclaring_classfield of thisArtMethodis set to point back to the custom class, ensuring it's correctly relocated by theArtMethodvisitor. Theentry_point_from_quick_compiled_codeis then set to point toenter_trampoline, the entry point for the Dalvik bytecode interpreter, which resides inlibart.sowithin the boot image. This pointer will be correctly relocated by theArtMethodvisitor.
- The
dataAttribute and ClassLinker Problem: The challenge arises with thedataattribute of theArtMethod, which is supposed to point to the actual Dalvik bytecode to be executed. TheArtMethodvisitor does not relocate thisdataattribute. Instead, theClassLinkercomponent, which runs after relocation, is responsible for modifying it. If theClassLinkerdetermines a methodhas_code_item, it treats the value indataas an index intoclasses.dexand replaces it with a pointer to the bytecode withinclasses.dex. This is problematic becauseclasses.dexis outside the attacker's control and not writable.
- Bypassing ClassLinker Modification: The
ClassLinker'shas_code_itemcheck depends on theaccess_flagsof theArtMethod. By setting one of theaccess_flagstoabstract, the method is deemed not to have a code item. This prevents theClassLinkerfrom modifying thedataattribute, allowing the attacker to preserve their arbitrary pointer withindata.
- Relocating the
dataAttribute via Section Overlay: Even with theClassLinkerbypassed, thedataattribute still needs to be relocated to point to the injected Dalvik bytecode within the attacker's ART image. The solution involves an ingenious section overlay. The ART image header defines various sections (e.g., forArtMethods,ArtFields), each with an offset and size. There are no checks to prevent these sections from overlapping. The attackers overlay thedeclaring_classvalue of an ArtField section directly on top of thedataattribute of their customArtMethod. When theArtFieldvisitor processes its section, it encounters thedeclaring_class(which is now thedataattribute of theArtMethod) and relocates it. Sincedeclaring_classis an object pointer, it can be relocated to the object section of the app image itself, where the injected Dalvik bytecode resides. This ensures thedataattribute correctly points to the attacker's bytecode.
The injected Dalvik bytecode typically performs actions like Runtime.getRuntime().exec(command_string). To achieve this, the bytecode must preserve Java structure and handle strings correctly, often by dynamically building strings rather than relying on static strings in classes.dex.
Considerations and Limitations
The remote attack offers persistence across reboots, as it doesn't rely on ASLR. However, it faces two main limitations:
- BJ Dex opt: A background DEX optimization process can recompile the app image and place it in a protected directory. This newly compiled image will be preferred, rendering the overwritten ART image useless.
- Apex updates: Updates to Apex modules (system components) can change the boot images, invalidating the pre-calculated
boot_image_checksum. While this requires re-triggering the exploit with a new checksum, it's less severe than BJ Dex opt.
Furthermore, the remote attack requires the app image loading to complete successfully for the class to initialize and trigger the bytecode. A common hurdle is the app image needing to specify the correct dex_file_path, which is randomized for user-installed apps. The speakers found that an out-of-bounds read (similar to the LZ4 write vulnerability, but during reading from the mmapped ART image file) could sometimes be leveraged to extract the correct dex_file_path from a deterministic offset beneath the mmapped file, and then inject it into the malicious ART image. This, however, does not work for all apps.
Demo / Proof of Concept
▶ Watch: Handling pointers and memory relocation in app images (3:55)
The speakers provided compelling demonstrations of both their local and remote exploitation techniques against real-world Android devices and applications.
Local Demo: Zero-Click Privilege Escalation on Oxygen OS
The local attack was showcased as a zero-click privilege escalation from an untrusted application to system privileges on a OnePlus 12R running Oxygen OS (firmware versions prior to November 2023). This exploit chain leveraged two critical bugs:
- Touch Event Injection (Bug 1): On vulnerable Oxygen OS firmware, the
IATCommandForwardService(an AT command interface implementation) lacked proper permission checks. This allowed any untrusted app to send coordinates to the service, which would then inject touch events directly into the system. This capability is extremely powerful, enabling an attacker app to simulate user interaction without any user clicks, hence "zero-click." - Path Traversal in OnePlus Backup App (Bug 2): The OnePlus Backup app, when started in "new phone" mode, initiates a Wi-Fi hotspot and listens on TCP port 8940 for incoming data from an "old phone." Among the messages processed are
SaveFilemessages, which contain a file path to a temporary directory and file contents. The vulnerability stemmed from an insufficient path validation (a basic string comparison) that allowed for path traversal using../sequences. Crucially, theseSaveFilemessages were not authenticated, meaning any entity connected to the TCP port, including an attacker app, could send them.
The attack flow proceeded as follows:
- The attacker app uses the injected touch events (Bug 1) to start a screen capture. This allows the attacker app to operate more stealthily by using OCR on screen captures to determine UI states and inject precise touch events.
- The attacker app then injects touch events to initiate a backup session in the OnePlus Backup app.
- Once the backup app is listening, the attacker app sends a malicious
SaveFilemessage (Bug 2) containing a path traversal payload to overwrite the OnePlus Backup app's ART image using the local exploitation technique. - Finally, the attacker app closes and reopens the backup app via injected touch events.
- When the OnePlus Backup app restarts, it loads the attacker-controlled ART image, leading to code execution within its highly privileged context. The OnePlus Backup app runs in a special Linux context with access to a root service (a wrapper around
move/renameoperations), allowing it to write files to other apps' directories, including potentially overriding ahead-of-time compiled code for system daemons like the settings app indata/dalvik-cache. Although the live demo faced issues, a pre-recorded version was shown, successfully demonstrating the code execution.
Remote Demos
The remote attack, designed for blind exploitation, was demonstrated through two scenarios, both pre-recorded due to the inherent flakiness of race conditions and background processes.
- OnePlus Backup/Restore (Newer Version Variant): A newer version of the OnePlus Backup/Restore app exhibited a race condition during its Wi-Fi setup. Occasionally, when a user started a backup session, the TCP port 8940 would open on all network interfaces, not just the hotspot interface. If the user then minimized the app and reconnected to Wi-Fi, the port would sometimes remain open globally. In this scenario, an attacker on the same Wi-Fi network could send
SaveFilemessages to overwrite the app's ART image. The next time the user closed and reopened the backup app, the exploit would trigger. The demo showcased a Frida hook being used to win the race condition and a Python script (test.py) sending the crafted ART image over the network.
- Samsung Galaxy S24 (Quick Share Agent): This demonstration was a "remix" of an existing exploit chain presented at OffensiveCon 2023, targeting the Samsung Galaxy S24. The original chain involved four bugs to escalate from a user visiting an attacker-controlled website to a file override vulnerability in the Samsung Quick Share Agent. The original exploit then used a fifth bug to install a malicious APK. Mao and Fall adapted this: instead of installing an APK, they used the file override vulnerability in Quick Share Agent to overwrite its ART image. This granted them code execution directly within the highly privileged platform app context of Quick Share Agent, eliminating the need for further privilege escalation steps. The demo involved an attacker-controlled phone sending a file over the network to trigger Quick Share Agent, followed by a phone reboot (due to Quick Share Agent's background nature making it difficult to reliably restart) to demonstrate the persistent code execution from the overwritten ART image.
Defensive Implications
▶ Watch: Bypassing app image header checksums (5:00)
The findings presented in "Exploiting Android Apps with Counterfeit Art" carry significant implications for Android application security, particularly for developers and platform maintainers.
- Strict File Path Validation is Paramount: The most immediate and critical takeaway for developers is the urgent need to address file override vulnerabilities. These bugs, often dismissed as less severe than direct code execution, are now demonstrably a direct path to RCE via ART image manipulation. All file I/O operations, especially those involving attacker-controlled input (e.g., zip file extraction, network file transfers), must implement rigorous path validation. This includes canonicalization of paths to resolve
../sequences and strict prefix checks to ensure files are only written to expected, non-sensitive directories. Any deviation should result in an error or rejection.
- ART Image Integrity and Tampering Detection: The ART image is a fundamental component of the Android Runtime, yet it can be overwritten within an app's private directory. Google is actively patching the specific vulnerabilities identified, but the underlying attack surface remains. Android platform developers should consider more robust runtime integrity checks for the ART image. While the
boot_image_checksumexists, its reliance on pre-calculated values based on firmware versions makes it vulnerable to offline bypass. Dynamic, runtime verification of the ART image's contents and origin would significantly raise the bar for attackers.
- Rethink the Security Posture of Cached Data: The ART image is essentially cached, serialized C++ objects. This research highlights that cached data, if not adequately protected and validated, can become an attack vector. Developers should extend this lesson to other forms of cached data or serialized objects within their applications, ensuring their integrity and authenticity, especially if they can influence execution flow.
- Mitigating ASLR Leaks Remains Important: While the blind remote attack bypasses ASLR, the local attack still relies on ASLR leaks for precise targeting. Continued efforts to reduce information leaks that could reveal memory layouts are essential for thwarting a class of local privilege escalation attacks.
- Challenges with
dexoptandApexUpdates: While BJ Dex opt (background DEX optimization) and Apex updates can, by replacing or updating ART images, inadvertently "patch" an overwritten ART image, they are not a reliable defensive mechanism. Attackers can often re-trigger the file override or adapt to new checksums, maintaining persistence. This indicates that relying on these mechanisms for security is insufficient; proactive prevention is key.
- Hardening
dex_file_pathHandling: The issue with randomizeddex_file_pathfor user apps and the need for an out-of-bounds read to obtain it highlights complexities in ART image loading. Platform developers could explore ways to make this path less predictable or to cryptographically bind it to the app's identity, preventing malicious ART images from claiming incorrectdex_file_pathvalues.
In essence, this research compels a re-evaluation of the criticality of file override vulnerabilities and emphasizes the need for a holistic security approach that extends beyond direct executable code to include crucial runtime components and cached data structures.
Key Takeaways
- The ART image file (
.artextension) is a novel and universal target for escalating arbitrary file override vulnerabilities to code execution in Android applications. - Two distinct exploitation techniques were developed: a local attack leveraging an LZ4 decompression out-of-bounds write (requiring an ASLR leak) and a remote, blind attack exploiting ART's relocation mechanism and a ClassLinker logic bug.
- The local attack involved overwriting the
entry_point_from_quick_compiled_codefunction pointer in a framework ArtMethod object (e.g.,java.lang.Thread.run) withinboot.art. - The remote attack achieved code execution by injecting Dalvik bytecode into the custom ART image, bypassing ClassLinker modifications by setting the
ArtMethodtoabstract, and then relocating the bytecode pointer using a section overlay trick involving an ArtField. - The techniques were demonstrated on real-world devices, including OnePlus phones (Oxygen OS) for zero-click privilege escalation to system context and Samsung Galaxy S24 (Quick Share Agent) for code execution in a platform app context.
- This research underscores the critical importance of fixing all file override vulnerabilities, as they now directly enable powerful code execution primitives against Android apps.
About the Speaker(s)
Philipp Mao is a PhD student at EPFL in Switzerland. His research focuses on Android security and trusted execution environments (TEEs).
Rokhaya Fall is a Master's student at EPFL. The work presented in this talk was a significant part of her semester project, showcasing her early contributions to Android security research.
Reviews
Dr. Zero (Offensive Security Researcher) — SOLID
This is the kind of talk that redefines how you think about a vulnerability class. Mao and Fall took file override bugs—something most people treat as 'meh, just a file write'—and built a universal code execution primitive out of the ART image. The blind remote attack is genuinely clever, and the demos on OnePlus and Samsung devices prove this isn't academic hand-waving.
Heather Calloway (CISO) — SOLID
This is serious Android exploit research that changes the risk calculus for file override vulnerabilities across your entire mobile fleet. Any CISO with Android devices in sensitive roles—executives, finance, legal—needs to understand that file write bugs are now code execution bugs. The technical execution is rigorous and the implications are immediate.