Disclaimer: This project is for educational and research purposes only. It demonstrates how split APKs can be merged, decompiled, and modified. All modifications target client-side enforcement of limits that should be server-validated.
If you find this mod useful, consider donating, to support me and my projects!
Donate

This repository contains a modified version of askUs (at.davidschindler.askus v3.1.3), originally distributed as an XAPK (3 split APKs: base.apk, config1.apk, config2.apk). The splits were merged into a single fat APK, then extensively modified to remove tracking, ads, license verification, and client-enforced limits.
askus-3.1.3-mod.apk| Change | Detail |
|—|—|
| Merged base.apk + config1.apk (arm64-v8a native libs) + config2.apk (drawable resources) | Single fat APK, no splits |
| Removed android:requiredSplitTypes from manifest | No longer a split APK |
| Added .so to doNotCompress in apktool.yml | Required for extractNativeLibs="false" |
| Component | Files Modified | Effect |
|—|—|—|
| Firebase Analytics logEvent | ~30 call sites NOP’d across 15+ files | Zero analytics events sent |
| Firebase Analytics setUserProperty | 15 call sites NOP’d | No user profiling (timezone, appstarts, auth_provider, etc.) |
| Firebase Crashlytics | AskUsApp.smali — collection disabled; recordException/setCustomKey NOP’d | No crash reports sent |
| Google AppMeasurement | AndroidManifest.xml — 3 services removed | No Google Analytics background uploads |
| Firebase Sessions | AndroidManifest.xml — service removed | No session tracking |
| Data Transport (CCT) | AndroidManifest.xml — 3 services removed | No data pipeline to Google servers |
| ProfileInstaller | AndroidManifest.xml — receiver + initializer removed | No baseline profile telemetry |
| SDK | Change |
|—|—|
| AdMob (Google Mobile Ads) | MobileAdsInitProvider, AdActivity, AdService, meta-data removed from manifest; MobileAds.initialize() NOP’d |
| IronSource / LevelPlay | 3 activities + 2 providers removed from manifest |
| Facebook Audience Network | Activity + provider removed from manifest |
| Fyber / Inneractive | 5 activities removed from manifest |
| AD_ID permission | Removed from manifest |
| File | Change |
|—|—|
| smali/com/pairip/licensecheck/LicenseContentProvider.smali | onCreate() returns true immediately — no Google Play licensing AIDL call, no paywall, no app exit |
| AndroidManifest.xml | LicenseActivity + LicenseContentProvider entries removed |
| Feature | File(s) | Change |
|—|—|—|
| Answer coin reward | F1/i0.smali | coinReward sent to sendAnswer Firebase Function set to 80,000 (was ~5–20) |
| Custom question cost | x1/f.smali (deserializer), F1/i0.smali (Function call) | Forced to 0 |
| Streak restore cost | x1/H.smali method c() | Always returns 0 |
| Group upgrade cost | x1/H.smali method m() | coinsNeededForGroupUpgrade forced to 0 |
| Profile upgrade cost | x1/H.smali method m() | coinsNeededForPersonalUpgrade forced to 0 |
| Pack purchase cost (display) | j2/d.smali method d(J), e2/j0.smali | Coin formatter always returns "0"; pack detail skips cost read |
| Pack purchase (functional) | P1/C.smali, P1/h.smali, P1/d.smali | Balance check always passes; payingCoins sent as 0 |
| Spending approval bypass | F1/S2.smali | needsApprovalToSpendCoins always false |
| Ad watch cooldown | CoinsPurchaseViewModel.smali method f() | Returns Instant.now() — button always available |
| Coin display formatting | j2/d.smali method d(J) | Always returns "0" (was “5k”, “5000”, etc.) |
| Limit | File | Change |
|—|—|—|
| Max groups (free) | x1/H.smali method h() | Returns Integer.MAX_VALUE (was 3) |
| Max groups (premium) | x1/H.smali method i() | Returns Integer.MAX_VALUE (was 10) |
| Max chat messages (free) | x1/H.smali method j() | Returns Long.MAX_VALUE (was 3) |
| Max chat messages (premium) | x1/H.smali method k() | Returns Long.MAX_VALUE (was 50) |
| Change answer timer | Q1/o0.smali | Set to Integer.MAX_VALUE seconds (~68 years, was 300s) |
| Change | File |
|—|—|
| Anonymous login always enabled | c2/d.smali, K1/S1.smali — anonym_login_active always true |
| Crash | File | Fix |
|—|—|—|
| Resources$NotFoundException (drawable 0x7f0800e8) | P4/L.smali | Skipped missing Giphy SDK drawable load |
Every coin modification in this mod works because the client is trusted with coin values. The server accepts whatever the client sends. To fix:
sendAnswer Firebase Function receives payingCoins from the client and uses it. The server should independently calculate the reward based on its own config.User/{uid} document’s coins field should only be modifiable by Cloud Functions, not by direct client writes.| Vulnerability | Fix |
|---|---|
payingCoins in sendAnswer is client-controlled |
Server should ignore client value and use server-side CoinConfig |
costs in restoreStreak is client-controlled |
Server should use its own configured cost |
payingCoins in requestConvoPack is client-controlled |
Server should validate against server-side pack price |
needsApprovalToSpendCoins is client-readable/writable |
Move to a server-only field; client should not be able to clear it |
Coin balance is directly writable via FieldValue.increment() |
Use Cloud Functions for all coin modifications; block direct client writes via Firestore Security Rules |
| Issue | Fix |
|---|---|
max_groups, max_message_count enforced in UI only |
Enforce in Cloud Functions / Firestore Security Rules |
change_answer_time used client-side for countdown |
Server should reject answer changes after the window expires |
anonym_login_active controlled by Remote Config |
Server should validate auth provider and reject anonymous sessions if desired |
| Issue | Fix |
|---|---|
| 30+ analytics events logged per session | Minimize to essential events only; provide opt-out |
| User properties include timezone, appstarts, auth_provider | Only collect what’s necessary for functionality |
| Crashlytics enabled by default | Make crash reporting opt-in |
| Data Transport (CCT) sends data to Google servers | Use self-hosted analytics or minimize third-party data sharing |
| Tool | Version | Purpose |
|---|---|---|
| apktool | 3.0.1 | Decompile/rebuild APK |
| zipalign | 36.0.0 | Align APK for installation |
| apksigner | 36.0.0 | Sign APK with debug keystore |
| adb | — | Install and test on emulator |
This project is for educational purposes only. The original app and its intellectual property belong to the original developers. This mod does not include any proprietary assets beyond what is necessary to demonstrate the modification process.
This project was made simply to mess around with AI Agents, and their usefullness in decompiling, modifying and general understanding of smali code, in android apps. Needless to say, it did a good job! What would have taken me an entire day, was done under 3 hours, tested and documented!