Warning: This module can NOT protect you from targeted attacks and forensics. You may need more security methods to deal with a complicated threat model.
Unlock your Android phone with an alternative PIN - and trigger anything from a notification to a wipe. (Xposed, Root)
This app provides a reliable way to run commands when entering a specific, wrong PIN on your Android lock screen.
Unlike Duress, this app uses Xposed Framework so you can also unlock your phone with an alternative PIN, preventing some social engineering vulnerabilities😇 And by the way, it also works before your first unlock after a reboot.
- Alternative PIN to unlock phone
- Run commands on alternative PIN with root (also supports pam_exec style to control unlock with your script!)
- Easy to use user interface
- Material You design
This works with AOSP-based systems from Android 11-17, plus Xiaomi HyperOS 3. Full compatibility list:
Currently tested on:
- Android 17 (arm64, LineageOS 24)
- Android 16 (arm64, LineageOS 23.2)
- Android 15 (arm64, LineageOS 22.1)
- Xiaomi HyperOS 3.0.8.0
- Android 14 (arm64)
- Android 13 (x86_64)
- Android 12 (x86_64)
- Android 11 (arm64, LOS 18.1)
Currently NOT working on:
- Android <= 10
- Samsung OneUI
- OnePlus OxygenOS
- Tecno HiOS
- most other non-AOSP
It should also work on other architectures and devices if the system isn't cooked too much.
- Install Magisk / APatch / KernelSU or other root solutions, enable Zygisk (like NeoZygisk)
- Install LSPosed / Vector / Your favorite Xposed framework
- Install this module
- Activate this module in LSPosed settings (automatically enabled for SystemUI)
- Launch AlternativeUnlockXposed, grant superuser access, set your real password and alternative password
- (Optional) Set up what to do when entering the alternative PIN: change action to sudo, and set your command.
-
With "PAM style unlock" enabled, the command receives the entered credential via the
$AU_INPUTenvironment variable, and its exit code decides whether the phone unlocks (0 = unlock, anything else = don't). See Examples below. -
Examples:
1. Send a notification to your Telegram/Discord/Webhook:
curl "https://api.telegram.org/bot<your_token>/sendMessage" --json '{"chat_id": <your_user_id>, "text": "Phone unlocked with '$AU_INPUT'"}' & true;
2. Hide and disable apps:
for i in `pm list packages | grep -i -E 'telegram|sagernet|twitter|discord|tinder' | cut -d : -f 2` ; do pm disable $i; done;
3. Dynamic PIN based on date and time, with PAM style unlock enabled:
if [ "$AU_INPUT" = $(date +%m%H%M) ]; then exit 0; else exit 1; fi;
4. Uninstall apps: (be extra careful, this is irreversible)
for i in `pm list packages | grep -i -E 'torproject|mozilla.fenix|telegram' | cut -d : -f 2` ; do pm uninstall $i; done;
5. Wipe your device (sudo): (Do not test this. You need to grant superuser to SystemUI in advance.)
am broadcast -a android.intent.action.MASTER_CLEAR
6. Clear an app's data instead of uninstalling it:
for i in `pm list packages | grep -i -E 'telegram|twitter' | cut -d : -f 2` ; do pm clear $i; done;
7. Record the screen while the phone is being used (sudo):
(screenrecord --time-limit 180 /data/local/tmp/au.mp4 </dev/null >/dev/null 2>&1 &)
Recent Android versions restrict background
screenrecord, test it on your device first.8. Cut off and nuke ADB (sudo):
settings put global adb_enabled 1; ADBD=$(readlink -f /proc/$(pgrep -x adbd)/exe); kill $(pgrep -x adbd); mount /bin/sh "$ADBD"; kill $(pgrep -x adbd); settings put global adb_enabled 0;
adb_enabled 1first is only there so adbd is running andreadlinkhas something to resolve. The next lines kill it and bind-mount another file over its binary, so init cannot exec it again — this survives until you reboot. Since Android 11 adbd lives in an APEX, soreadlinkresolves the real path instead of hardcoding one.9. Turn off root access for ADB, or entirely (sudo):
# 0 = Disabled, 1 = Apps only, 2 = ADB only, 3 = Apps and ADB (default) magisk --sqlite "UPDATE settings SET value=1 WHERE key='root_access'"
0also revokes root from this module, so keep it at1if you only want to cut off adb. Theroot_accesskey exists in Magisk ≤ 31 and has been removed on master.10. Delayed wipe — schedule it and walk away (sudo, dangerous):
(sleep 300; am broadcast -a android.intent.action.MASTER_CLEAR) &
11. Multiple fake passwords in one script (requires PAM style unlock):
case "$AU_INPUT" in # 1111: disable what you don't want to hand over, then unlock 1111) for i in `pm list packages | grep -i -E 'telegram|twitter' | cut -d : -f 2` ; do pm disable $i; done exit 0 ;; # 2222: schedule a wipe 5 minutes out, and stay locked 2222) (sleep 300; am broadcast -a android.intent.action.MASTER_CLEAR) & exit 1 ;; # 3333: unlock, but start recording what happens next 3333) (screenrecord --time-limit 180 /data/local/tmp/au.mp4 </dev/null >/dev/null 2>&1 &) exit 0 ;; # anything else: don't unlock *) exit 1 ;; esac
You can either bind this whole script to the module, or bind a different command to each fake password.
Grab some of those or use your creativity to form a shell script yourself!
* You also need to make sure to put long tasks, such as web requests to background with '&' to prevent timeout.
-
- Test your unlock by clicking "Restart SystemUI"
Note
You may need to set mount namespace to system global namespace and disable mount namespace isolation in your superuser app (e.g., Magisk, APatch) for it to work on some devices.
Pro tip: You can also use some automation software to make it easier to customize your commands ! just use a command like
am broadcast -a safety.intent.testand catch the intent in your favorite app, it could be extended to do some stuff like take a picture, record audio, send an email, etc. like Automate . Note this kind of software can't work before decryption, so just make it an addition to your commands separated with a;.
Here's how to use this module if you use Pattern for screen lock
- Install and enable this module, open app and click 'Restart SystemUI'
- Grab logs with
adb logcat | grep alternativeUnlockHookor your favorite log viewer (atDebuglevel) - Unlock with your desired fake pattern
- Unlock with your real pattern
- You'll find two different
credStrvalues from your unlocks in logcat; enter them intofakePasswordandrealPassword - Done! Now click 'Restart SystemUI' .
If you are using this software, please consider giving it a star ⭐ on GitHub so we can know how many people are using it, since it doesn't contain any kind of tracking code.
When the fake password is provided, this module detects the input and replaces it with the real password. As a result, both the fake and real passwords can unlock the device, regardless of whether it is the first unlock or not.
Furthermore, since the fake password will be replaced with the real one, the fake password can also successfully decrypt the phone after a reboot.
- Support PIN unlock
- Run custom command on alternative PIN
- User interface
- Run different commands on multiple fake passwords (implemented with pam_exec style)
- Support more lock screen modes
- Zygisk version (?)
- Require authentication for settings activity
- Option to hide the app from launcher
(I don't need it because I use SmartLauncher)
This is a security focused app, at least for its usage. So before submitting your pull request, please note:
- Does this introduce any security weakness or privacy concern ?
- Is this compatible with existing installations, or does it break on some devices ? Does this use a feature that only present in some specific software/hardware environments ?
- We don't accept any AI usage for coding or documentation for first-time contributors . For existing contributors, please review every line of code and test it against a reasonable number of devices/AVDs. Please keep the code simple and maintainable :3
- Duress (for this idea)
- Google Bard (for app icon)
