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