Library / SDK
ahmedmani/pairipfix avatar
ahmedmani/pairipfix

pairipfix: removing the Play Store install check from sideloaded APKs

A simple LSPosed module to bypass signature checks for apks installed from outside google play

691 stars50 forksJavaLicense varies

At a glance

What is it?
pairipfix is a small Java LSPosed module that stops Android apps from showing the Get this app from Play screen when they are installed as an APK, by defeating the install-source check inside Google's pairipcore library. It does not touch signature validation or anti-instrumentation checks, and the README already warns that the module is detected on some devices.
Who is it for?
Adopt pairipfix if you routinely sideload Android applications on a device you own and the install-source screen is the specific obstacle, and if you are comfortable running an LSPosed module that patches a proprietary anti-abuse library at runtime. Do not adopt it expecting a general bypass, because the module addresses one of the three checks pairipcore performs and leaves signature validation and Frida or debugger detection alone.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the module changes, and what it does not

The scope is narrow and worth stating precisely, because the repository description and the README do not say quite the same thing. The description calls it a simple LSPosed module to bypass signature checks for apks installed from outside google play. The README is more careful: it bypasses the Get this app from Play screen when installing Android apps as an APK instead of from the Google Play Store, and it names the exact check the module targets.

That distinction matters, because the security library underneath does three things, according to the README. It validates that the app was installed from Google Play, which is the check this module bypasses. It validates the app signature to prevent resigning and repackaging. And it detects and blocks Frida hooks and debuggers such as GDB.

So a module that only defeats the first of the three is not a universal sideloading enabler. An app whose protection includes signature validation will still refuse to run against a modified package, and an app that blocks Frida instrumentation is unaffected by anything this module does. The legitimate use case, installing an unmodified release build of an app you already have a licence for on a device you own, is the case where the install-source screen is the only thing standing between you and a working app.

The primary language is Java, and the tree is a standard Android library project with app/, build.gradle.kts, settings.gradle.kts, gradle.properties, gradle/, gradlew and gradlew.bat. The Gradle wrapper is checked in, so a build does not need a preinstalled Gradle.

The releases are v1.2 from 2026-04-20, v1.0.1 from 2025-06-12 and a first release from 2025-05-08. The last push to the repository was on 2026-04-20, and the repository is not archived. The licence field on the repository is not a recognised identifier, and there is no LICENSE file in the tree, which is a gap worth raising before you redistribute the module.

LSPosed itself is a framework that hooks into the Android runtime rather than replacing the system image, and a module of this kind therefore only does anything on a device that already runs that framework. The README does not document installation steps for the module, only what it does, so where you get it and how it is loaded is outside what the documentation covers.

How pairip protects an app in the first place

The mechanism is described in the README and it is unusual enough to be the most interesting part of this project.

Google's protection is called pairipcore, and it runs from a binary file named libpairpcore.so. The stated purpose is to prevent abuse during app runtime. The library works by attaching itself to app resources that it cannot run without, and it does this by rewriting some of the app's methods in encrypted or obfuscated VM code. Each time a protected method is called, a VM code file is loaded from the app's own storage and executed inside the pairip VM.

The consequence of that design is what makes the protection sticky. Simply preventing those calls would crash the app, because the resources would be missing. The app depends on the library being there in a working state, so an attacker cannot simply neutralise the checks by patching them out or by blocking the library, and the checks are effectively enforced by the app's own need to function.

For anyone writing a module against this, it explains the shape of the problem. You are not patching a single boolean check in a Java method, you are dealing with a native library that has rewritten parts of the app into code that only runs inside its own VM. The install-source validation, the signature validation and the anti-debugging checks all sit behind that same arrangement.

This is also why a module that only targets the install-source check is a modest piece of work rather than a complete defeat of the protection. The rest of the machinery still runs, still validates, and still detects.

The module is detected on some devices, and the app may not start

The README is direct about the reliability problem: the module is currently detected on some devices while it works flawlessly on others, and it points to a different module for the cases where the app crashes the moment you open it.

That is a specific failure mode rather than a vague caveat. An app that instant crashes on launch after the module is enabled has not necessarily been broken by the module in an obvious way; the likelier story is that the protection library noticed the hook and responded. Since the same library also performs anti-instrumentation checks, a module that touches the runtime is exactly the kind of thing those checks are looking for, and the same library is what the module is trying to influence.

The suggested alternative is BetterKnownInstalled, from the Pixel-Props organisation, and the README frames it as something to try when the app crashes instantly on open. Two different projects solving the same symptom in different ways is a reasonable outcome, and the existence of the alternative is itself a signal that the primary module is not universally effective.

The practical advice for an evaluator is to treat enabling the module as an experiment with a known failure rate rather than as a step in a setup procedure. The repository offers no device matrix, no list of affected models and no known-good version list, so there is no way to predict from the documentation alone whether a particular phone and a particular app will work together. The only documented signal is the crash.

There is also a stability dimension that follows from the design. A module that hooks into protected application methods is running against code that the application developer deliberately moved into a VM to make it hard to reach. The failure mode when a module is half-working is not a clean error, it is a broken app.

Where this sits against the alternatives

The obvious alternative to a runtime module is not another module, it is a different build of the app, and the choice depends on what you are actually trying to do.

If you want an app on a device that does not have the Play Store, the clean routes are an official sideload or a systemless install of an unmodified build. The install-source screen appears because the protection library can see the package was not installed by the Play installer, and the sanctioned ways to avoid that screen are to install through a channel the library accepts, or to use a build that carries no install-source restriction.

If you want to inspect or modify an app's behaviour, a runtime hook is the wrong layer, because the app's own code has been moved into the pairip VM and a hook at the Java level will not reach it. Work that belongs in the native layer, at the library boundary, belongs there instead.

Where pairipfix earns its place is the narrow middle: an unmodified official APK, on a device without the Play Store, where the only thing stopping the install is the source check, and where you are prepared to accept that some devices will refuse to run the app afterwards. The README's own alternative recommendation, BetterKnownInstalled, sits in the same space with a different technique, and between the two you have one attempt and one fallback.

The comparison worth making is not between this module and another module. It is between this module and a device that has the Play Store, or a device you can reset, or a build with the check absent. On a device that has the Play Store, none of this is necessary.

The repository documents a mechanism but not an install procedure

It is worth noticing what the repository does not contain. The tree is small: a.gitignore, the README, an app/ directory, the Gradle files, gradle.properties, a gradle/ directory and the Gradle wrapper scripts. There is no code in the tree listing beyond the application module, no test directory, no CI configuration directory in the listing, and no changelog.

The README is entirely about what the module does and why the underlying protection works. There are no installation steps for the module itself, no instructions for installing LSPosed, and no statement about which Android versions or ROMs are supported. For a project whose entire effect depends on being loaded into a running system, that is an unusual gap, and it means the practical knowledge about deploying it lives outside the repository.

The build side is at least conventional. A checked-in gradlew and gradlew.bat means the wrapper drives the build, the Kotlin DSL files build.gradle.kts and settings.gradle.kts are the modern Gradle configuration format, and gradle.properties holds the project-wide properties. Building an Android library project this way needs an Android SDK and a JDK, which the documentation does not state either.

Two more things are absent that a reader might expect. There is no LICENSE file in the tree and the repository's licence field is not a recognised identifier, so the terms for the code are unclear from what is published. And there is no issue tracker guidance or contribution documentation beyond the README, which for a project with a handful of releases is a thin surface.

None of this makes the module wrong. It makes it a project to treat as a reference implementation of one technique rather than as a product with support behind it.

Editorial conclusion

Adopt pairipfix if you routinely sideload Android applications on a device you own and the install-source screen is the specific obstacle, and if you are comfortable running an LSPosed module that patches a proprietary anti-abuse library at runtime. Do not adopt it expecting a general bypass, because the module addresses one of the three checks pairipcore performs and leaves signature validation and Frida or debugger detection alone. Before you commit, confirm that the app you want to install is not one whose signature check matters to you, check the README's warning that the module is detected on some devices and that the app may crash instantly on those, and try the BetterKnownInstalled alternative the README points to if the app refuses to start.

Frequently asked questions

What does the pairipfix LSPosed module do?

It bypasses the Get this app from Play screen that Android apps show when they are installed as an APK rather than from the Google Play Store. It works by defeating the install-source validation inside Google's pairipcore library.

What are the three checks that pairipcore performs?

The README lists them as validating that the app was installed from Google Play, validating the app signature to prevent resigning and repackaging, and detecting and blocking Frida hooks and debuggers such as GDB. The pairipfix module targets only the first of these.

Why does an app crash instantly after installing pairipfix?

The README says the module is detected on some devices while it works on others, and suggests that an app which crashes on opening may be reacting to the hook. It recommends trying the BetterKnownInstalled module from the Pixel-Props organisation in that case.

What is the latest pairipfix release?

The releases are v1.2 from 2026-04-20, v1.0.1 from 2025-06-12 and a first release from 2025-05-08. The last push to the repository was on 2026-04-20, the project is written in Java, and the repository carries a Gradle project with a checked-in wrapper.

Official sources

  1. ahmedmani/pairipfix on GitHub
  2. Issues
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ahmedmani-pairipfix.svg)](https://hysenlabs.com/projects/ahmedmani-pairipfix)

Was this useful?