Primer paso de la investigacion. Se aportan el .apk, las carpetas con el apk extraido y el apk descompilado. El archivo API_DOCUMENTATION.md es un archivo donde se anotaran los descubrimientos del funcionamiento de la API, y los .py son scripts para probar la funcionalidad de la API con los métodos que vayamos encontrando. Finalmente, los archivos .js son scripts de Frida para extraer informacion de la APP durante la ejecucion.

This commit is contained in:
2025-12-04 13:59:54 +01:00
parent f2fd1c3bf5
commit e0133d2ca2
10432 changed files with 1019085 additions and 1 deletions

View File

@@ -0,0 +1,186 @@
package com.google.firebase.messaging;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import com.google.android.gms.cloudmessaging.Rpc;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.FirebaseApp;
import com.google.firebase.heartbeatinfo.HeartBeatInfo;
import com.google.firebase.inject.Provider;
import com.google.firebase.installations.FirebaseInstallationsApi;
import com.google.firebase.installations.InstallationTokenResult;
import com.google.firebase.platforminfo.UserAgentPublisher;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.ExecutionException;
import n.ExecutorC0507a;
/* loaded from: classes3.dex */
public class GmsRpc {
static final String CMD_RST = "RST";
static final String CMD_RST_FULL = "RST_FULL";
static final String CMD_SYNC = "SYNC";
static final String ERROR_INSTANCE_ID_RESET = "INSTANCE_ID_RESET";
static final String ERROR_INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR";
static final String ERROR_INTERNAL_SERVER_ERROR_ALT = "InternalServerError";
static final String ERROR_SERVICE_NOT_AVAILABLE = "SERVICE_NOT_AVAILABLE";
private static final String EXTRA_DELETE = "delete";
private static final String EXTRA_ERROR = "error";
private static final String EXTRA_IID_OPERATION = "iid-operation";
private static final String EXTRA_REGISTRATION_ID = "registration_id";
private static final String EXTRA_SCOPE = "scope";
private static final String EXTRA_SENDER = "sender";
private static final String EXTRA_SUBTYPE = "subtype";
private static final String EXTRA_TOPIC = "gcm.topic";
private static final String EXTRA_UNREGISTERED = "unregistered";
static final String FIREBASE_IID_HEARTBEAT_TAG = "fire-iid";
private static final String PARAM_APP_VER_CODE = "app_ver";
private static final String PARAM_APP_VER_NAME = "app_ver_name";
private static final String PARAM_CLIENT_VER = "cliv";
private static final String PARAM_FIREBASE_APP_NAME_HASH = "firebase-app-name-hash";
private static final String PARAM_FIS_AUTH_TOKEN = "Goog-Firebase-Installations-Auth";
private static final String PARAM_GMP_APP_ID = "gmp_app_id";
private static final String PARAM_GMS_VER = "gmsv";
private static final String PARAM_HEARTBEAT_CODE = "Firebase-Client-Log-Type";
private static final String PARAM_INSTANCE_ID = "appid";
private static final String PARAM_OS_VER = "osv";
private static final String PARAM_USER_AGENT = "Firebase-Client";
private static final String SCOPE_ALL = "*";
static final String TAG = "FirebaseMessaging";
private static final String TOPIC_PREFIX = "/topics/";
private final FirebaseApp app;
private final FirebaseInstallationsApi firebaseInstallations;
private final Provider<HeartBeatInfo> heartbeatInfo;
private final Metadata metadata;
private final Rpc rpc;
private final Provider<UserAgentPublisher> userAgentPublisher;
public GmsRpc(FirebaseApp firebaseApp, Metadata metadata, Provider<UserAgentPublisher> provider, Provider<HeartBeatInfo> provider2, FirebaseInstallationsApi firebaseInstallationsApi) {
this(firebaseApp, metadata, new Rpc(firebaseApp.getApplicationContext()), provider, provider2, firebaseInstallationsApi);
}
private static String base64UrlSafe(byte[] bArr) {
return Base64.encodeToString(bArr, 11);
}
private Task<String> extractResponseWhenComplete(Task<Bundle> task) {
return task.continueWith(new ExecutorC0507a(1), new k(this));
}
private String getHashedFirebaseAppName() {
try {
return base64UrlSafe(MessageDigest.getInstance("SHA-1").digest(this.app.getName().getBytes()));
} catch (NoSuchAlgorithmException unused) {
return "[HASH-ERROR]";
}
}
private String handleResponse(Bundle bundle) throws IOException {
if (bundle == null) {
throw new IOException(ERROR_SERVICE_NOT_AVAILABLE);
}
String string = bundle.getString(EXTRA_REGISTRATION_ID);
if (string != null) {
return string;
}
String string2 = bundle.getString(EXTRA_UNREGISTERED);
if (string2 != null) {
return string2;
}
String string3 = bundle.getString("error");
if (CMD_RST.equals(string3)) {
throw new IOException(ERROR_INSTANCE_ID_RESET);
}
if (string3 != null) {
throw new IOException(string3);
}
Log.w("FirebaseMessaging", "Unexpected response: " + bundle, new Throwable());
throw new IOException(ERROR_SERVICE_NOT_AVAILABLE);
}
public static boolean isErrorMessageForRetryableError(String str) {
return ERROR_SERVICE_NOT_AVAILABLE.equals(str) || ERROR_INTERNAL_SERVER_ERROR.equals(str) || ERROR_INTERNAL_SERVER_ERROR_ALT.equals(str);
}
public /* synthetic */ String lambda$extractResponseWhenComplete$0(Task task) throws Exception {
return handleResponse((Bundle) task.getResult(IOException.class));
}
private void setDefaultAttributesToBundle(String str, String str2, Bundle bundle) throws ExecutionException, InterruptedException {
HeartBeatInfo.HeartBeat heartBeatCode;
bundle.putString(EXTRA_SCOPE, str2);
bundle.putString(EXTRA_SENDER, str);
bundle.putString(EXTRA_SUBTYPE, str);
bundle.putString(PARAM_GMP_APP_ID, this.app.getOptions().getApplicationId());
bundle.putString(PARAM_GMS_VER, Integer.toString(this.metadata.getGmsVersionCode()));
bundle.putString(PARAM_OS_VER, Integer.toString(Build.VERSION.SDK_INT));
bundle.putString(PARAM_APP_VER_CODE, this.metadata.getAppVersionCode());
bundle.putString(PARAM_APP_VER_NAME, this.metadata.getAppVersionName());
bundle.putString(PARAM_FIREBASE_APP_NAME_HASH, getHashedFirebaseAppName());
try {
String token = ((InstallationTokenResult) Tasks.await(this.firebaseInstallations.getToken(false))).getToken();
if (TextUtils.isEmpty(token)) {
Log.w("FirebaseMessaging", "FIS auth token is empty");
} else {
bundle.putString(PARAM_FIS_AUTH_TOKEN, token);
}
} catch (InterruptedException | ExecutionException e4) {
Log.e("FirebaseMessaging", "Failed to get FIS auth token", e4);
}
bundle.putString(PARAM_INSTANCE_ID, (String) Tasks.await(this.firebaseInstallations.getId()));
bundle.putString(PARAM_CLIENT_VER, "fcm-23.4.0");
HeartBeatInfo heartBeatInfo = this.heartbeatInfo.get();
UserAgentPublisher userAgentPublisher = this.userAgentPublisher.get();
if (heartBeatInfo == null || userAgentPublisher == null || (heartBeatCode = heartBeatInfo.getHeartBeatCode(FIREBASE_IID_HEARTBEAT_TAG)) == HeartBeatInfo.HeartBeat.NONE) {
return;
}
bundle.putString(PARAM_HEARTBEAT_CODE, Integer.toString(heartBeatCode.getCode()));
bundle.putString(PARAM_USER_AGENT, userAgentPublisher.getUserAgent());
}
private Task<Bundle> startRpc(String str, String str2, Bundle bundle) {
try {
setDefaultAttributesToBundle(str, str2, bundle);
return this.rpc.send(bundle);
} catch (InterruptedException | ExecutionException e4) {
return Tasks.forException(e4);
}
}
public Task<?> deleteToken() {
Bundle bundle = new Bundle();
bundle.putString(EXTRA_DELETE, "1");
return extractResponseWhenComplete(startRpc(Metadata.getDefaultSenderId(this.app), "*", bundle));
}
public Task<String> getToken() {
return extractResponseWhenComplete(startRpc(Metadata.getDefaultSenderId(this.app), "*", new Bundle()));
}
public Task<?> subscribeToTopic(String str, String str2) {
Bundle bundle = new Bundle();
bundle.putString(EXTRA_TOPIC, TOPIC_PREFIX + str2);
return extractResponseWhenComplete(startRpc(str, TOPIC_PREFIX + str2, bundle));
}
public Task<?> unsubscribeFromTopic(String str, String str2) {
Bundle bundle = new Bundle();
bundle.putString(EXTRA_TOPIC, TOPIC_PREFIX + str2);
bundle.putString(EXTRA_DELETE, "1");
return extractResponseWhenComplete(startRpc(str, TOPIC_PREFIX + str2, bundle));
}
public GmsRpc(FirebaseApp firebaseApp, Metadata metadata, Rpc rpc, Provider<UserAgentPublisher> provider, Provider<HeartBeatInfo> provider2, FirebaseInstallationsApi firebaseInstallationsApi) {
this.app = firebaseApp;
this.metadata = metadata;
this.rpc = rpc;
this.userAgentPublisher = provider;
this.heartbeatInfo = provider2;
this.firebaseInstallations = firebaseInstallationsApi;
}
}