An LSPosed/Xposed module for com.facebook.katana that removes ads from the Facebook app without relying on hardcoded obfuscated class or method names.
- News Feed sponsored units
- Story ads and in-disc story ads
- Reels / upstream ad-backed story append paths
- Quicksilver game ad requests
- Audience Network and Neko playable ad activities used by games
- Obfuscated names such as
AiD,A84,A8t,ADF, orAueare too unstable to hardcode. They changed across builds and caused broken hooks. - Stable strings and structural signatures are much more reliable than direct obfuscated names.
- Feed ads are inserted at multiple layers. Blocking only one layer is not enough.
- Game ads are not a single pipeline either. Quicksilver request hooks, postMessage hooks, and UI activity fallbacks all matter.
- Blocking
AudienceNetworkActivityatstartActivity(...)was too early and caused game hangs. Letting it launch and closing it immediately from activity lifecycle hooks worked better.
- Resolve classes with DexKit using stable strings and method shapes.
- Remove ad-backed stories from the upstream list builder append path.
- Sanitize feed CSR filter inputs and outputs.
- Sanitize late-stage feed lists before they reach rendering.
- Block sponsored entries from the sponsored pool and story pool.
- Block story ad providers by intercepting merge/fetch/update style methods.
- Resolve Quicksilver ad request methods by their stable JSON error strings.
- Hook the Quicksilver
postMessage(String, String)bridge as a second request-layer fallback. - Resolve ad requests as a no-op success payload where possible so the caller does not hang waiting on the bridge.
- Close
AudienceNetworkActivity,AudienceNetworkRemoteActivity, andNekoPlayableAdActivityfrom lifecycle hooks as UI-level fallbacks. - Only hard-block the playable activity launch path directly; Audience Network activity launches are allowed so their internal close/error flow can run before the activity is closed.
- Runtime logs are debug-only.
Patches.ktandModule.javanow gate logging behindBuildConfig.DEBUG.- Release builds should stay quiet unless you re-enable logging yourself.
The startup line:
DexKit groups: ... feedCsr=0 ...
is normal in the current implementation.
That number is only the result of the initial batch string-group search. Feed CSR hooks are also resolved by later structural and fallback matchers, so feedCsr=0 does not mean feed CSR filtering is disabled.
The line that actually matters is:
Resolved feed CSR filters=...
If that later line contains resolved classes, the CSR filtering path is active even when the earlier batch count is zero.
- Android app module:
app - Host package:
com.facebook.katana - Application ID:
tn.loukious.facebookappadsremover
Build the debug APK with:
./gradlew :app:assembleDebug- Prefer stable strings, type signatures, and runtime structure over obfuscated identifiers.
- Keep debug instrumentation available in debug builds only.
- Treat feed, story, and game ads as separate pipelines with separate fallbacks.