Tools and techniques for troubleshooting custom module development.
# Watch only your module's logs
adb logcat | grep -i "your_module_name"
# Watch LSPosed manager logs
adb logcat | grep "LSPosed"
# Watch specific class hooks
adb logcat | grep "ClassLoader"Symptoms: Hooks never fire, no logcat output
Solutions:
# 1. Verify scope is correct (LSPosed Manager β Modules β check target app is enabled)
# 2. Check that package name is exact:
adb shell pm list packages | grep -i facebook
# 3. Force-stop and restart the app
adb shell am force-stop com.facebook.katana
adb shell am start com.facebook.katana/com.facebook.activity.LauncherActivity
# 4. Reload Zygisk (if using):
adb shell killall -9 zygoteSymptoms: Device reboots infinitely after installation
Recovery:
# Boot to TWRP recovery
adb reboot recovery
# Disable all modules:
# In TWRP: Magisk β Modules β swipe left to disable all
# OR via ADB (if Magisk is running):
adb shell magisk module disable <module_name>
# Check which module crashed:
adb logcat -c
adb logcat | head -100 # look for crash in first linesExample problem: Illegal argument to invoke-virtual
// β WRONG β trying to invoke non-virtual on interface
public static void hookInterfaceMethod() {
var MyInterface = Java.use("com.example.MyInterface");
MyInterface.someMethod.implementation = function() { ... };
}
// β
RIGHT β hook the concrete implementation class
public static void hookConcreteClass() {
var MyImpl = Java.use("com.example.MyInterfaceImpl");
MyImpl.someMethod.implementation = function() { ... };
}Symptoms: Module works but stops after user force-closes app
Fix: Add persistent scope in LSPosed:
# LSPosed Manager β Modules β [your module]
# Check: "Persistent scope" or ensure DenyList is OFF for that appadb logcat -v threadtime "YourModule:D *:S"
# Output: 05-18 17:25:33.123 12345 12345 D YourModule: messageRun Frida + Xposed hooks together to cross-validate:
// frida_debug.js
Java.perform(function() {
console.log("[Frida] Attached to app");
// Set a breakpoint that shows what Xposed is seeing
var MyClass = Java.use("com.example.MyClass");
MyClass.myMethod.implementation = function() {
console.log("[Frida] myMethod called with: " + this);
return this.myMethod.call(this);
};
});frida -U -f com.facebook.katana -l frida_debug.js --no-pauseadb shell ls /data/adb/modules/
# Your module should be listed here
adb shell cat /data/adb/modules/your_module/module.prop
# Should show: id=your_module, name=, etc.# Method 1: Soft reboot via Magisk
adb shell magisk --install-module /path/to/module.zip
# Method 2: Hard reboot (slowest)
adb reboot
# Method 3: Kill system processes
adb shell killall -9 system_server# Baseline: measure without module
adb shell am start -W com.facebook.katana
# Look at "ThisTime" value
# Disable module, remeasure
# LSPosed β your module β toggle OFF
adb shell am start -W com.facebook.katana
# Compare ThisTime values// In your module:
var startTime = java.lang.System.currentTimeMillis();
var MyClass = Java.use("com.example.MyClass");
MyClass.expensiveMethod.implementation = function() {
var callStart = java.lang.System.currentTimeMillis();
var result = this.expensiveMethod.call(this);
var callTime = java.lang.System.currentTimeMillis() - callStart;
console.log("[Profile] expensiveMethod took " + callTime + "ms");
return result;
};- Scope set correctly in LSPosed Manager
- Target app is enabled in module settings
- No typos in package/class names
- Logcat shows module is loaded ("LSPosed: Module X loaded")
- Test with simpler hook first (e.g.,
Log.d()only) - Check for
ClassNotFoundExceptionin logs - Verify method signature matches reality (
dumpMethodsAndFields()) - Try Frida for comparison if stuck