Mujde is an android app in form of Xposed module, that integrates with Xposed framework to hook apps.
Mujde lets the user manage a local repository of frida-js scripts, and select what script should it inject to which selected application.
Using android's SharedPreferences, mujde stores a map between apps to the list of scripts it should inject into them.
Using Xposed's XSharedPreferences, mujde's hook (InjectionRequester
cls) is accessible to that mapping.
Via Xposed framework, mujde gets a callback (handleLoadPackage
) whenever an app is loaded by zygote-forkAndSpeciallize.
Then, mujde fetches the list of scripts it should inject to that app (using XSharedPreferences
).
If that list isn't empty, mujde (installHookOnActivityCreation
) installs hook on Activity.onCreate
function,
Which lets us get a callback whenever a new activity is started in that app (which we already know that has scripts the user wants to inject into).
Then, from that hook, mujde sends an injection-request from the app's context to mujde's broadcast-listener named InjectionRequestHandler
.
That handler sends parses the injection-request via intent,
And creates frida-inject
subprocesses (as root user) to inject the selected scripts into the started app.
NOTE that the scripts will be re-injected whenever the app creates/re-creates any activity.
Mujde manages the local scripts repository in the app-data folder's files
subfolder.
Users with root permissions can create/remove/edit files from that folder directly,
Without using mujde's app to manage the repository: /data/data/com.rel.mujde/files/scripts
This feature is extremly usable for scripts / massive management operations on the repository.
Additional, mujde's shared-preferences are stored at Xposed-shared-preferences folder to be world-readable.
Root users can edit the shared-preferences from there to import settings from other devices,
And any user can read the contents of that folder and files. Mujde's main shared-pref can be found at /data/misc/eb08c078-3e01-43a8-8857-4e57e0f0e2e3/prefs/com.rel.mujde/mujde_prefs.xml
.
NOTE that this path might have a different guid on different android devices / between reboots.
Use this guide to compile the app by yourself (or simply download the build artifacts from github-action or releases)
NOTE you can compile the app using windows / linux / macos
- git client
- java setup (e.g. java-temurin v21) and android-sdk
- java-home (env. variable ANDROID_HOME) or local.properties set correctly with
sdk.dir
- internet connection (in order to download
frida-inject
binaries from frida's github releases) - python3 + pip +
pip install signapp buildapp && buildapp_fetch_tools
- optional, only made for release builds
Clone the project:
git clone https://github.com/mon231/com.rel.mujde mujde
Execute gradlew:
cd mujde
./gradlew assembleDebug
Find the apk at mujde/app/build/outputs/apk/debug/app-debug.apk
In order to build the app for release compilations:
./gradlew assembleRelease
signapp -a mujde/app/build/outputs/apk/release/app-release.apk -o app-signed.apk
Find the apk (release build) at app-signed.apk
The app is implemented in form of Xposed module, therefore MUST be installed on devices with Xposed-framework, like LSposed/EdXposed.
On devices with such framework (e.g. rooted devices with LSPosed over zygisk, or virtual-LSposed over normal android/vm),
Simply install the app and enjoy hooking other apps, automatically & covertly!
If the app is installed over devices with no Xposed framework, it might simply crash when opened.
Use network guides to install LSposed / root your device, or use an emulator with similar guides.
- HomeFragment: shows home screen from navbar, the first fragment of the main activity
- ScriptsFragment: show the scripts page from navbar. let the user watch existing scripts, create new, edit, delete, ...
- AppsFragment: show list of apps. when app is selected, creates the ScriptSelectionActivity for chosen app (via intent's extra)
- InjectionRequester: notified when a new injectible app is loaded,
hooks it's Activity.onCreate method to broadcast a com.rel.mujde.INJECT_REQUEST request
- InjectionRequest: simple data-holder to serialize/deserialize request content in Intent's extra
- Constants: contains consts and strings for global needs
- InjectionRequestHandler: handles broadcasted com.rel.mujde.INJECT_REQUEST requests, notifies the FridaInjectorService
- ScriptUtils: utils about scripts (repository, SharedPref, content, files, folder, ...)
- AccessibilityUtils: chmod files / folders to make sure they are readable from other users
- ActivityMain: the activity which contains the fragments and the footer navbar
- ScriptSelectionActivity: a screen where the user selects what scripts should be injected to currently selected app
- AppListAdapter: used to list all installed apps and move to ScriptSelectionActivity to choose what scripts to inejct
- ScriptCheckboxAdapter: used by ScriptSelectionActivity, to track availableScripts/selectedScripts
- ScriptAdapter: used by ScriptsFragment to view each script-item (script name, edit button, delete button)