deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

Rooted-device test shows repackaged Android apps can pass Google Play Integrity

A dev.to write-up demonstrates that on a rooted Android 16 phone, swapping an app's code on disk while leaving its install record intact still returns a genuine Play Integrity verdict.

Rooted-device test shows repackaged Android apps can pass Google Play Integrity

What happened

A technical write-up published on dev.to shows a practical way to defeat Google Play Integrity on a rooted Android device: overwrite the app's actual code file on disk while leaving the original installation record in place, and the service still reports the app as genuine.

According to the author, the test ran on a rooted phone with Android 16 and Google Play Services 26.34.67. After swapping in a repackaged build, a Play Integrity request returned PLAY_RECOGNIZED, LICENSED and a Play Protect result of NO_ISSUES, even though the code executing at that moment was the author's modified version, signed with a different key.

How the verdict is made

Repackaging, as the write-up explains, means pulling an APK from a device, changing what it does (stripping ads or paywalls, faking know-your-customer checks, hiding signs of root) and distributing the result. It matters because many backends trust client-reported device signals when deciding which traffic is legitimate, and a modified client can simply lie. The author names fintech, crypto, web3 and gambling apps as the most exposed, and argues repackaging is more scalable than exotic runtime exploits because a tampered app can be handed to less technical users across many devices.

Google's answer is the Play Integrity API and its PLAY_RECOGNIZED verdict. Tracing the check on a live device, the author describes the flow: the app calls the API, Google's IntegrityService hands off to DroidGuard, which assembles the package name, version code, install source, device identifiers, SIM data and a request nonce into an attestation that Google's servers evaluate and sign. Google's documentation, quoted in the article, defines the verdict as the app and certificate matching the versions Google Play distributes.

For PLAY_RECOGNIZED, the author says, Google compares two things: the package name and the signing certificate it holds for that installation. That record is fixed when the app is installed; the verdict never re-examines the code that is actually running.

The file swap

The author re-signed a repackaged build of a test app with their own key. Android blocked a normal upgrade with INSTALL_FAILED_UPDATE_INCOMPATIBLE because the signatures differed, and the author argues this signature check is effectively where Play Integrity's protection ends.

With root access, the author instead overwrote the installed base.apk directly, leaving the system's install record, and its cached genuine certificate, untouched. The next verdict came back PLAY_RECOGNIZED, citing the genuine certificate digest rather than the repackaged build's key, together with LICENSED and NO_ISSUES.

To rule out stale compiled code, the author deleted the phone's prebuilt copy of the app so Android had to load the modified file, and inserted a marker that logged from the very process that then received the genuine verdict.

The bypass has limits: it needs root on the device where the swap happens, and a re-signed app installed as a fresh install still draws UNRECOGNIZED_VERSION. The trick is specifically decoupling the running code from the install record.

Wider gaps

The write-up lists related weaknesses. Because the cached certificate never changes, a genuinely signed app hooked at runtime also keeps a clean verdict while behaving differently. On de-Googled devices, such as custom ROMs and many China-market phones, Play Integrity cannot run at all, forcing defenders to either block all such traffic or allow all of it. And API quotas plus latency push developers to verify only at sensitive actions, opening windows in between. The author also cites a 2022 study that bypassed every on-device anti-repackaging scheme it tested, arguing that purely on-device defenses have never held on their own.

The proposed mitigation

The fix the write-up recommends, and given its framing clearly promotes, is a tool called Intakto, whose free tier computes a fresh hash of the installed APK files at runtime and compares the result with the signing certificate Android recorded at install. In the author's test on a Pixel 3a running Android 12, the tool flagged the swapped file. It does not catch a re-signed copy installed fresh, which is the case UNRECOGNIZED_VERSION already covers. According to the author, the signer is read twice, once through a native call and once through the standard Android API, so a hook that lies to one path is caught by the other.

Why it matters

Play Integrity verdicts are a load-bearing signal: backends use them to decide which clients may handle payments, identity checks and licensed content. If a rooted device can run attacker code while the verdict still says genuine, the guarantee is weaker than many integrators may assume. Developers of high-value apps likely need defense in depth, combining runtime self-verification and server-side anomaly detection rather than treating PLAY_RECOGNIZED as proof that the executing code is Google's. The demonstration also underlines why repackaging deserves attention: it is technically crude compared with sophisticated runtime attacks, but it scales to ordinary users in a way one-off exploits do not.

  • #android
  • #security
  • #google-play
  • #play-integrity
  • #mobile-apps

Related posts