DuckDetector reports integrity signals, and says what it cannot see
Android environment integrity inspection tool for root, hook, bootloader, SELinux, virtualization, and attestation signals
At a glance
- What is it?
- DuckDetector is an Android diagnostics app that collects evidence of tampering, root artifacts, runtime hooking, modified system properties and attestation problems, and presents each detector as a card with a status and an evidence record. The same detectors ship as a UI-free SDK AAR, and the documentation is unusually honest about the limits of what a scan can conclude.
- Who is it for?
- Adopt DuckDetector as a developer tool when you need to see what a device looks like from the point of view of an app that cares about tampering, either as the standalone app or as the embedded SDK AAR. Do not adopt it as a security verdict, because the project states the results are diagnostic signals rather than an authoritative statement that a device is secure or compromised.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Kotlin, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Signals, not verdicts, and the status vocabulary that says so
The Overview describes DuckDetector as a tool that collects and correlates security-relevant evidence on an Android device, and the framing sentence at the end of that paragraph is the one to hold on to. The results are diagnostic signals, not an authoritative statement that a device is secure or compromised.
The status table on screen makes that framing concrete, because four of the five statuses are about the limits of the evidence rather than about the verdict. Danger and Warning mean the detector observed evidence and the card lists what it saw. All Clear means the probes ran and found none of the evidence they look for, and the table adds the caveat that this does not prove the device is unmodified. Info with the Support label means a probe was unsupported or unavailable on that device, so the absence of findings says nothing at all. Info with the Error label means the check failed and the card says why.
That is a well designed vocabulary. A scanner that only distinguishes found and not found forces the reader to guess which of the two they are looking at, and the Support and Error states exist to stop a missing capability from being read as a clean result.
The areas it looks at are boot-state changes, root and SU artifacts, runtime injection or hooking, mount namespace anomalies, modified system properties, suspicious applications, KeyStore and attestation inconsistencies, and signs of virtualization.
Eighteen detectors, each with an evidence record
The detector coverage section lists seventeen feature areas, and every one of them links to an evidence record that explains what the detector looks for, why that counts as evidence, and what it cannot see.
The list is ADB Runtime, Bootloader, Custom ROM, Dangerous Apps, Kernel Check, LSPosed, Memory, Mount, Native Root, Play Integrity Fix, Root Managers, SELinux, SU, System Properties, TEE, Virtualization and Zygisk, and the directories behind them are in the feature/ directory of the repository.
The third part of that contract, what it cannot see, is the part that separates this from a checklist. Any detector on a device that an attacker controls can be fooled, and the honest way to express that is per detector rather than in a disclaimer at the bottom of the readme.
The structure also tells you how the project is built. The repository has a feature/ directory with one module per area, plus app/, core/, capability/, sdk/, uihelper/ and build-logic/ directories, and a settings.gradle.kts at the root. That is a feature oriented Gradle layout, and the Overview says the app combines a Jetpack Compose interface, feature-oriented Gradle modules, and a native C++ and assembly library. The native layer is where the low level probes live, and the assembly part suggests inline syscall level work rather than a Java API call.
Getting it onto a device, and what the first launch asks
The quick start is four steps, and the first one sets expectations about release discipline.
You download the APK from the Nightly release, which the documentation says is published from main and is also posted to the Telegram channel, and it says plainly that there is no stable release yet. So the artifact you test is built from the branch tip, which is fine for diagnostics work and is not what you would want for a release pipeline.
Second, you install it on a device running Android 10 or later. Root access is not required, which matters because a tool that needs root would only be able to look at devices that are already modified.
Third, the scan. The first launch asks you to accept a user agreement and settle a few startup choices: notifications, Live Update, the online revocation refresh used by the TEE check, and package visibility. Scanning then starts by itself, and each card fills in when its detector finishes.
The package visibility choice deserves attention. Several detectors are about what is installed on the device, and Android's own permission model restricts what an app can enumerate unless the user grants that visibility. A detector that cannot see the installed packages will report less, and the difference between a clean result and an uninformative one is exactly the kind of thing the Support and Error statuses exist to make visible.
Fourth, you read the results. To report something, the documentation says to open an issue and attach the file saved by Export Report, and it says a screenshot of the summary alone is not enough.
The same detectors ship as an SDK AAR
The Overview states that the same detectors are also published as a UI-free SDK AAR that other applications can embed, and that is the more interesting adoption path for most teams.
The repository backs this up. There is an sdk/ directory, a docs/guides/sdk-integration.md guide, and a samples/ directory with a single example, samples/sdk-consumer/, which is exactly the shape you would expect from a library that wants to prove it can be embedded.
The value of the SDK path is that it moves the check from the developer's device to the application. A user running your app on a device with a hooking framework or a spoofed integrity layer can be reported by your own code, in a way that reaches your telemetry, rather than by a tester running a separate app by hand.
The constraint is the same one the app has. The detectors produce signals, and the framework in which you consume them has to decide what a signal is worth. A card labelled All Clear is not a pass, and a Warning is not a ban, and the SDK hands you the same evidence with the same caveats attached.
The native C++ and assembly library is packaged with it, since the SDK embeds the same detectors rather than reimplementing them, which means the embedding application inherits the same native code and the same platform requirements.
The SELinux area documents the checks that cannot conclude
One part of the coverage list is worth reading in full, because it shows the standard the project holds itself to.
The SELinux area retains an app-zygote SID-table query and registration experiment. The documentation says that repeated discrepancies are supporting warnings, that synchronized policy hiding can leave no discrepancy at all, that controlled privileged-context writes run in a disposable child with malformed and stock controls, that recognition and ordinary-app timing are supporting warnings, that an app-zygote AVC lookup-count profile is informational only, and that negative observations cannot exclude hidden policy. Access failures and incomplete experiments remain explicit coverage states.
Read that as a whole and it is a description of an experiment that mostly produces inconclusive results, stated without spin. The detector tells you what it looked for, what a hit would mean, and that a miss means nothing.
That approach is what makes the rest of the tool usable. A root detector that reports a boolean will be believed by whoever reads the output, and a boolean is exactly the wrong amount of information in this domain. The evidence records and the coverage states exist so that a reader can tell a negative from an uninformative one, and the SELinux area is where that discipline is easiest to see.
Play Integrity Fix is not a Play Integrity verdict
There is a line in the documentation that will save an argument in a code review, and it concerns the detector named Play Integrity Fix.
The documentation says it refers to local indicators associated with integrity-spoofing modifications, and then says explicitly that DuckDetector does not return an official Google Play Integrity API verdict.
The distinction is not pedantry. An official verdict is issued by Google, through the Play Integrity API, and it carries a specific meaning for an application that has been configured to require it. A local indicator is DuckDetector noticing that something on the device looks like an attempt to interfere with integrity reporting, which is a different claim, made by a different party, on different evidence.
The TEE area follows the same discipline. It evaluates Android KeyStore and attestation evidence, including certificate chains, security levels, revocation data, and selected KeyMint, StrongBox and Soter behaviour where supported. The phrase where supported is doing the work, and it is consistent with the rest of the tool, where a capability that the device does not have is an Info Support card rather than a silent pass.
The Native Root area offers an optional fsnotify SRCU timing experiment, disabled by default, which requires an explicit choice and uses a temporary private dynamic permission on supported Android 12 to 14 systems. The documentation says it reports repeatable contention as supporting evidence, that its thresholds await device calibration, that it does not identify KernelSU, and that its private-process assumptions are limited.
Nightly builds, a single release tag, and a permissive licence
The repository is not archived, and the last push was on 2026-10-19, so the code is current. The release list, however, has a single entry, a nightly release of the Nightly APK and SDK AAR build dated 2026-04-14.
So the project has one rolling tag rather than a version history, which matches the documented policy of publishing nightly builds from main. For a diagnostics tool under active development that is a reasonable model, and it is also a limitation: there is no stable artefact to pin, and no release notes to diff between versions.
The licence is Apache-2.0, with the LICENSE file at the top of the repository. The repository also carries AGENTS.md, CODING_STANDARDS.md, CONTRIBUTING.md and a Chinese version of the contribution guide, a Duck Detector Solution.md document, a.gitmodules entry for the native library, and an.idea/ directory. The readme is available in English and Simplified Chinese, and there is a Telegram channel for releases and discussion alongside the GitHub issue tracker.
The project name is worth noting too. The repository is Duck-Detector-Refactoring and the application is DuckDetector, so the source tree has been restructured at some point, and the sample consumer project is the place to look if you want to see the intended embedding shape before committing to it.
Editorial conclusion
Adopt DuckDetector as a developer tool when you need to see what a device looks like from the point of view of an app that cares about tampering, either as the standalone app or as the embedded SDK AAR. Do not adopt it as a security verdict, because the project states the results are diagnostic signals rather than an authoritative statement that a device is secure or compromised. Verify first that your target devices run Android 10 or later, that the nightly build you install matches the main branch you are testing, and that the detectors you care about have a device-validated evidence record rather than only a stated coverage state.
Frequently asked questions
What does DuckDetector check on an Android device?
It collects and correlates evidence of boot-state changes, root and SU artifacts, runtime injection or hooking, mount namespace anomalies, modified system properties, suspicious applications, KeyStore and attestation inconsistencies, and virtualization. It covers seventeen feature areas, from ADB Runtime and Bootloader through LSPosed, SELinux, TEE and Zygisk.
Does DuckDetector need root access to run?
No. The quick start says to install it on a device running Android 10 or later and that root access is not required. The first launch asks you to accept a user agreement and choose startup options including notifications, Live Update, the online revocation refresh used by the TEE check, and package visibility.
Can I embed DuckDetector in my own Android app?
Yes. The same detectors are published as a UI-free SDK AAR, with an integration guide at docs/guides/sdk-integration.md and a sample consumer project under samples/sdk-consumer.
Does DuckDetector return a Google Play Integrity verdict?
No. The Play Integrity Fix detector refers to local indicators associated with integrity-spoofing modifications, and the documentation states that DuckDetector does not return an official Google Play Integrity API verdict.
How do I interpret an All Clear result?
It means the probes ran and found none of the evidence they look for, and the documentation is explicit that this does not prove the device is unmodified. An Info status with the Support label means a probe was unsupported or unavailable, so the absence of findings says nothing, and an Info status with the Error label means the check failed and the card explains why.
Is there a stable release of DuckDetector?
No. The quick start says nightly builds are published from main and are also posted to the Telegram channel, and that there is no stable release yet. The only tagged release in the list is the nightly build.
Official sources
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.
[](https://hysenlabs.com/projects/eltavine-duck-detector-refactoring)Was this useful?