• PSA: How to check Android APKs for ads, trackers & hidden ad-related SDKs

    From Maria Sophia@mariasophia@comprehension.com to comp.mobile.android on Mon Feb 16 21:36:41 2026
    From Newsgroup: comp.mobile.android

    PSA: How to check Android APKs for ads, trackers & hidden ad-related SDKs

    I invested hours in this post so I ask, if you respond, that you try
    to add value so that the spent energy is not wasted but is leveraged.

    However, I can (and do) make mistakes, so I challenge others to find
    them since the whole goal of posting this is to ask you to improve it.

    That way, everyone benefits from every action we take in this PSA.

    I (almost?) never see ads and it's hard to tell if an app has ads just
    by the listing on Google Play Store because some listings aren't honest.

    Plus, as you can see from the example below, some apps start off with
    no ads, but then ads are added secretly later, without overt notice.

    This happened to me, based on a conversation between Andy Burns &
    VanguardLH recently, where I wondered why my specific installed version 1.15.2(41) of Activity Launcher <de.szalkowski.activitylauncher>
    does not show any ads even as billing is disabled on my Android.
    <https://reports.exodus-privacy.eu.org/en/reports/search/de.szalkowski.activitylauncher/>

    They saw ads apparently.
    I did not.
    Why not?

    I (almost?) never see ads, even in apps that "say" they show ads, so my
    tests aren't conclusive since my Android phone is set up to not show them.

    But how do we know, just by 'looking' at an APK, if it "can" show ads?

    Here is my first pass at testing whether an app has ads or not. Activity Launcher is the test case but not the only one.

    1. The first thing I did was search in Muntashirakon App Manager which
    tells me for Activity Launcher <de.szalkowski.activitylauncher>
    Trackers = 0
    Where we would look for these strong indicators of ads in the app:
    Google Ads
    Facebook Ads
    Unity Ads
    AppLovin
    MoPub
    ByteDance
    The Trackers tab showed none of these strong indicators of ads
    No known ad SDKs
    No analytics SDKs
    No tracking libraries
    Note that Muntashirakon AM uses the Exodus signature list so it detects
    known tracker packages but not custom or obfuscated ones.

    We can get Muntashirakon App Manager from here:
    <https://muntashir.dev/AppManager/>

    2. In the Shared Libraries tab it tells us:
    Shared libraries = 0
    That is where we would look for ad related libraries such as:
    ads
    admob
    google.android.gms.ads
    facebook.ads
    unity.ads
    applovin
    chartboost
    inmobi
    startapp
    mopub
    bytedance
    yandex
    If any of these appear the app almost certainly contains ad code.

    Note: If Shared Libraries = 0, that means no native libraries,
    which is normal for many apps. Ad SDKs are usually Java/Kotlin,
    not native, so they often do not appear here.

    3. In the Activities, Services, and Receivers tabs we would look for:
    AdActivity
    MobileAdsInitProvider
    AdService
    InterstitialActivity
    RewardedVideoActivity
    These components are created by ad SDKs & are strong indicators of ads.

    4. In the Muntashirakon AM 'Uses Permissions' tab, we would look for:
    INTERNET
    ACCESS_NETWORK_STATE
    ACCESS_WIFI_STATE
    QUERY_ALL_PACKAGES
    READ_PHONE_STATE
    The existence of these alone do not prove ads exist but if an app has
    only these but no ad components it is most likely free of ad SDKs.

    5. The next test was Skyica App Finder (which fits next to Muntashirakon
    in terms of the most useful apps on Android) where I set the Skyica
    'In App Components Analysis' to these mutually exclusive checks:
    [x] No ads
    [x] No ads/removable ads
    Skyica detects embedded ad libraries even if they are not active.
    It also checks for in-app-purchase libraries:
    [_] No in-app purchases
    Skyica detects embedded ad SDKs, trackers & analytics libraries.
    Skyica also detects apps that contain any ad-related code.

    Important detail: Skyica detects only embedded ad libraries. If the
    app developer uses the Google Play Services dependency, the ad code
    is usually not packaged inside the app APK. It is resolved at install
    time from the system. In that case Skyica sees no embedded ad SDK &
    reports 'No ads' even if the app later loads ad code at runtime.

    We can get Skyica App Finder from here:
    <https://skyica.com/appfinder/>

    6. The next test was to make use of the Exodus Privacy web site.
    <https://exodus-privacy.eu.org/en/>
    The Exodus Privacy web site detects references to trackers, whether
    or not it's in the embedded code. This allows the web site to detect
    ads even when the SDK is not packaged inside the app APK

    Note that Exodus Privacy works differently from Skyica in that regard.

    Exodus Privacy detects trackers by scanning for package names & class
    signatures inside the APK. If the app APK contains references to ad
    sdks such as com.google.android.gms.ads or com.google.firebase.analytics
    then Exodus Privacy flags them (even if the actual code is not bundled).

    C:\> start msedge https://exodus-privacy.eu.org
    a. Press "Check an app"
    <https://reports.exodus-privacy.eu.org/en/>
    b. Paste in de.szalkowski.activitylauncher

    What's nice is that Exodus Privacy allows checking older versions of
    each app to find the definitive last-known-good versions which are
    clean of ads & trackers.

    From that list the first version with trackers is 2.0.7 from Google Play.
    All F-Droid builds remain clean because they are built without Google Play
    Services dependencies.

    7. The next test was ClassyShark3xodus which analyzes Android apps for:
    Trackers (analytics, advertising, profiling SDKs)
    Permissions the app requests
    It uses the same curated database of tracker signatures as Exodus.
    <https://f-droid.org/en/packages/com.oF2pks.classyshark3xodus/>

    This reports that version 2.1.6 has 3 trackers & 12 permissions.
    Clicking the highlighted link for the app name goes to:
    <https://reports.exodus-privacy.eu.org/en/reports/de.szalkowski.activitylauncher/latest/>

    This shows Google AdMob, Google Firebase Analytics & Google CrashLytics,
    which means tracking SDKs were apparently added after my sub-version.

    8. Since I solved problems for a living, there might also be another
    step, which is dynamic analysis to catch those apps that slip by.

    Since static analysis can miss ad code that is loaded only at
    runtime, the next logical test is dynamic analysis of network
    traffic. This catches those apps that slip by all the checks
    above because they load ads from Google Play Services or from
    remote servers instead of embedding the ad SDK inside the APK.

    The idea is simple: run the app & watch where it connects.
    If it talks to known ad networks, then it is ad-capable even
    if no ad SDKs or tracker signatures were found in the APK.

    Tools that can do this include:
    PCAPdroid
    <https://github.com/emanuele-f/PCAPdroid>
    NetGuard (log mode)
    <https://github.com/M66B/NetGuard>
    Note that NetGuard NOT loaded from Google Play can block ads too:
    <https://adaway.org/hosts.txt>
    <https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts>
    <https://big.oisd.nl/>
    <https://someonewhocares.org/hosts/hosts>
    Note NetGuard only supports plain hosts files (0.0.0.0 domain.com).
    TrackerControl
    <https://github.com/OxfordHCC/tracker-control-android>
    RethinkDNS + Firewall
    <https://rethinkdns.com/>
    <https://github.com/celzero/rethink-app>
    AdAway (log mode)
    <https://adaway.org/>
    Blokada (log mode)
    <https://blokada.org/>
    <https://github.com/blokadaorg/blokada>

    What to look for in the logs:
    Connections to ad networks
    Repeated HTTP/HTTPS calls to ad endpoints
    WebView ad URLs
    Firebase Remote Config fetches
    Google Play Services ad modules being requested

    Dynamic analysis is the only way to detect ads that are:
    Not embedded in the APK
    Not referenced by class name
    Not declared in Activities or Services
    Not detectable by Exodus Privacy
    Not detectable by Skyica
    Not detectable by ClassyShark3xodus
    Not detectable by Muntashirakon AM

    In short, dynamic analysis completes the picture by catching
    ad behavior that static analysis alone cannot reveal.

    9. ??? help me out here... what am I missing that's important ???

    If anyone sees gaps in this workflow PSA of if they know of additional techniques that can tighten the analysis, feel free to add value.

    The goal is to make this PSA as accurate & useful as possible for all
    of us who care about understanding how to find apps sans any ads.
    --
    PSAs like this exist only because a few kind, stubborn nerds still care.
    If you improve it, congratulations, you are one of the kindhearted ones.
    --- Synchronet 3.21b-Linux NewsLink 1.2