Open baltpeter opened 1 year ago
Just in case the Google Settings app has some special permissions or whatever and doesn't need GMS to get the gaid, I've now also tried My Device ID by AppsFlyer.
I've verified that this does actually include the class:
❯ dexdump 'com.appsflyer.android.deviceid.apk' | grep "Class descriptor" | grep "gms/ads"
Class descriptor : 'Lcom/google/android/gms/ads/identifier/AdvertisingIdClient$1;'
Class descriptor : 'Lcom/google/android/gms/ads/identifier/AdvertisingIdClient$Info;'
Class descriptor : 'Lcom/google/android/gms/ads/identifier/AdvertisingIdClient$zza;'
Class descriptor : 'Lcom/google/android/gms/ads/identifier/AdvertisingIdClient;'
Class descriptor : 'Lcom/google/android/gms/ads/identifier/zza;'
And yet, I'm still getting the same error.
This Gist alerted me to Java.enumerateLoadedClassesSync()
.
Let's try that:
var classes = Java.enumerateLoadedClassesSync();
classes.filter(c => c.includes('gms'));
That has a few results, no ads
, though:
[
"com.google.android.gms.common.a",
"com.google.android.gms.common.e",
"[Lcom.google.android.gms.common.v;",
"com.google.android.gms.common.f",
"com.google.android.gms.common.i",
"com.google.android.gms.common.j",
"com.google.android.gms.common.k",
"com.google.android.gms.internal.measurement.m2",
"com.google.android.gms.common.r",
"com.google.android.gms.common.s",
"com.google.android.gms.common.t",
"com.google.android.gms.common.u",
"com.google.android.gms.common.v",
"com.google.android.gms.common.w",
"com.google.android.gms.common.x",
"com.google.android.gms.common.y",
"com.google.android.gms.common.z",
"com.google.android.gms.internal.measurement.h2",
"com.google.android.gms.internal.measurement.y0",
"com.google.android.gms.dynamite.DynamiteModule",
"com.google.android.gms.internal.measurement.n2",
"com.google.android.gms.dynamite.DynamiteModule$a",
"com.google.android.gms.internal.measurement.t1",
"com.google.android.gms.dynamite.DynamiteModule$b",
"com.google.android.gms.internal.measurement.z0",
"com.google.android.gms.internal.measurement.o0",
"com.google.android.gms.internal.measurement.o1",
"com.google.android.gms.internal.measurement.o2",
"com.google.android.gms.internal.measurement.d1",
"com.google.android.gms.internal.measurement.zzcl",
"com.google.android.gms.internal.measurement.u2",
"com.google.android.gms.internal.measurement.p0",
"com.google.android.gms.dynamite.b",
"com.google.android.gms.internal.measurement.e1",
"com.google.android.gms.dynamite.c",
"com.google.android.gms.internal.measurement.e2",
"com.google.android.gms.dynamite.d",
"com.google.android.gms.dynamite.e",
"com.google.android.gms.dynamite.f",
"com.google.android.gms.dynamite.g",
"com.google.android.gms.dynamite.h",
"com.google.android.gms.dynamite.i",
"com.google.android.gms.dynamite.j",
"com.google.android.gms.dynamite.k",
"com.google.android.gms.internal.measurement.v2",
"com.google.android.gms.dynamite.n",
"com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable",
"com.google.android.gms.internal.measurement.k1",
"com.google.android.gms.common.api.internal.a",
"com.google.android.gms.internal.measurement.k2",
"com.google.android.gms.dynamite.descriptors.com.google.android.gms.measurement.dynamite.ModuleDescriptor",
"com.google.android.gms.dynamite.DynamiteModule$b$a",
"com.google.android.gms.dynamite.DynamiteModule$b$b",
"com.google.android.gms.internal.measurement.q0",
"com.google.android.gms.dynamite.DynamiteModule$DynamiteLoaderClassLoader",
"com.google.android.gms.internal.measurement.f1",
"com.google.android.gms.common.api.internal.a$a",
"com.google.android.gms.internal.measurement.w0",
"com.google.android.gms.internal.measurement.l1",
"com.google.android.gms.internal.measurement.l2",
"com.google.android.gms.chimera.container.DynamiteModuleApi",
"com.google.android.gms.dynamic.ObjectWrapper",
"com.google.android.gms.dynamiteloader.DynamiteLoaderV2",
"com.google.android.gms.common.internal.safeparcel.SafeParcelable",
"com.google.android.gms.dynamic.ObjectWrapper",
"[Lcom.google.android.gms.common.api.Scope;",
"com.google.android.gms.measurement.internal.AppMeasurementDynamiteService",
"com.google.android.gms.common.internal.safeparcel.SafeParcelable",
"com.google.android.gms.chimera.DynamiteModuleInitializer",
"com.google.android.gms.common.api.Scope",
"com.google.android.gms.common.internal.ReflectedParcelable"
]
I feel like I'm missing something here. I can't even load any of the *gms*
classes returned by Java.enumerateLoadedClassesSync()
:
var classes = Java.enumerateLoadedClassesSync();
for (const c of classes) {
if (c.includes('.gms.')) {
try {
Java.use(c);
console.log(1, c)
} catch {}
}
}
That has no output. Every Java.use()
fails with java.lang.ClassNotFoundException
.
Just for reference, here's what the Google Settings app (shows up in Frida as Google Play services
) outputs for classes.filter(c => c.includes('gms.ads'))
:
[
"com.google.android.gms.ads.admanager.a",
"com.google.android.gms.ads.admanager.b",
"com.google.android.gms.adsidentity.settings.AdsIdentityCollapseSettingsChimeraActivity",
"com.google.android.gms.ads.internal.util.aa",
"com.google.android.gms.adsidentity.settings.ui.NewAdIdCustomPreference",
"com.google.android.gms.ads.internal.util.ah",
"com.google.android.gms.ads.internal.util.ai",
"com.google.android.gms.ads.internal.util.d",
"com.google.android.gms.ads.internal.util.e",
"com.google.android.gms.ads.internal.util.h",
"com.google.android.gms.ads.internal.util.m",
"com.google.android.gms.ads.internal.util.n",
"com.google.android.gms.ads.internal.scionintegration.j",
"com.google.android.gms.ads.internal.appcontent.c",
"com.google.android.gms.ads.internal.util.client.f",
"com.google.android.gms.ads.internal.util.client.k",
"com.google.android.gms.ads.internal.util.client.n",
"com.google.android.gms.ads.internal.webview.p",
"com.google.android.gms.ads.internal.js.function.c",
"com.google.android.gms.ads.internal.mediation.c",
"com.google.android.gms.ads.internal.cache.a",
"com.google.android.gms.ads.internal.client.d",
"com.google.android.gms.ads.internal.client.f",
"com.google.android.gms.ads.internal.client.s",
"com.google.android.gms.ads.internal.client.u",
"com.google.android.gms.ads.internal.csi.c",
"com.google.android.gms.ads.interstitial.b",
"com.google.android.gms.adsidentity.settings.ui.ImageViewPreference",
"com.google.android.gms.ads.internal.overlay.a",
"com.google.android.gms.ads.internal.c",
"com.google.android.gms.ads.search.a",
"com.google.android.gms.ads.internal.overlay.c",
"com.google.android.gms.ads.internal.request.service.g",
"com.google.android.gms.ads.internal.util.client.VersionInfoParcel",
"com.google.android.gms.ads.internal.util.net.a",
"com.google.android.gms.ads.internal.state.a",
"com.google.android.gms.ads.internal.state.e",
"com.google.android.gms.ads.internal.state.f",
"com.google.android.gms.ads.internal.state.g",
"com.google.android.gms.adsidentity.settings.AdsIdentityGoogleSettingsIntentOperation",
"com.google.android.gms.ads.internal.video.gmsg.b",
"com.google.android.gms.adsidentity.settings.AdsIdentityCollapseSettingsActivity",
"com.google.android.gms.ads.internal.util.weaklisteners.a"
]
But trying to load any of those fails with java.lang.ClassNotFoundException
. shrug
Getting the IDFA is a lot easier on iOS (thanks, Copilot):
ObjC.classes.ASIdentifierManager.sharedManager().advertisingIdentifier().toString();
Only problem: You need an app that has the kTCCServiceUserTracking
permission, otherwise you just get 00000000-0000-0000-0000-000000000000
(even in system apps like SpringBoard :/).
Getting the Google Advertising ID through Frida is proving harder than I expected.
Copilot autocompleted this script which lines up with the documentation and various StackOverflow answers:
But that produces the following error:
I realize that the app we're injecting into needs to have the correct library for this to work. But I'm injecting into the Google Settings app which displays the gaid, so I would really expect this to work.