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:
@@ -0,0 +1,189 @@
|
||||
package com.google.firebase.remoteconfig.internal;
|
||||
|
||||
import android.util.Log;
|
||||
import com.google.android.gms.tasks.OnCanceledListener;
|
||||
import com.google.android.gms.tasks.OnFailureListener;
|
||||
import com.google.android.gms.tasks.OnSuccessListener;
|
||||
import com.google.android.gms.tasks.SuccessContinuation;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
import com.google.android.gms.tasks.Tasks;
|
||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import n.ExecutorC0507a;
|
||||
|
||||
/* loaded from: classes3.dex */
|
||||
public class ConfigCacheClient {
|
||||
static final long DISK_READ_TIMEOUT_IN_SECONDS = 5;
|
||||
private Task<ConfigContainer> cachedContainerTask = null;
|
||||
private final Executor executor;
|
||||
private final ConfigStorageClient storageClient;
|
||||
private static final Map<String, ConfigCacheClient> clientInstances = new HashMap();
|
||||
private static final Executor DIRECT_EXECUTOR = new ExecutorC0507a(1);
|
||||
|
||||
/* loaded from: classes3.dex */
|
||||
public static class AwaitListener<TResult> implements OnSuccessListener<TResult>, OnFailureListener, OnCanceledListener {
|
||||
private final CountDownLatch latch;
|
||||
|
||||
private AwaitListener() {
|
||||
this.latch = new CountDownLatch(1);
|
||||
}
|
||||
|
||||
public void await() throws InterruptedException {
|
||||
this.latch.await();
|
||||
}
|
||||
|
||||
@Override // com.google.android.gms.tasks.OnCanceledListener
|
||||
public void onCanceled() {
|
||||
this.latch.countDown();
|
||||
}
|
||||
|
||||
@Override // com.google.android.gms.tasks.OnFailureListener
|
||||
public void onFailure(Exception exc) {
|
||||
this.latch.countDown();
|
||||
}
|
||||
|
||||
@Override // com.google.android.gms.tasks.OnSuccessListener
|
||||
public void onSuccess(TResult tresult) {
|
||||
this.latch.countDown();
|
||||
}
|
||||
|
||||
public boolean await(long j4, TimeUnit timeUnit) throws InterruptedException {
|
||||
return this.latch.await(j4, timeUnit);
|
||||
}
|
||||
|
||||
public /* synthetic */ AwaitListener(AnonymousClass1 anonymousClass1) {
|
||||
this();
|
||||
}
|
||||
}
|
||||
|
||||
private ConfigCacheClient(Executor executor, ConfigStorageClient configStorageClient) {
|
||||
this.executor = executor;
|
||||
this.storageClient = configStorageClient;
|
||||
}
|
||||
|
||||
private static <TResult> TResult await(Task<TResult> task, long j4, TimeUnit timeUnit) throws ExecutionException, InterruptedException, TimeoutException {
|
||||
AwaitListener awaitListener = new AwaitListener();
|
||||
Executor executor = DIRECT_EXECUTOR;
|
||||
task.addOnSuccessListener(executor, awaitListener);
|
||||
task.addOnFailureListener(executor, awaitListener);
|
||||
task.addOnCanceledListener(executor, awaitListener);
|
||||
if (!awaitListener.await(j4, timeUnit)) {
|
||||
throw new TimeoutException("Task await timed out.");
|
||||
}
|
||||
if (task.isSuccessful()) {
|
||||
return task.getResult();
|
||||
}
|
||||
throw new ExecutionException(task.getException());
|
||||
}
|
||||
|
||||
public static synchronized void clearInstancesForTest() {
|
||||
synchronized (ConfigCacheClient.class) {
|
||||
clientInstances.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized ConfigCacheClient getInstance(Executor executor, ConfigStorageClient configStorageClient) {
|
||||
ConfigCacheClient configCacheClient;
|
||||
synchronized (ConfigCacheClient.class) {
|
||||
try {
|
||||
String fileName = configStorageClient.getFileName();
|
||||
Map<String, ConfigCacheClient> map = clientInstances;
|
||||
if (!map.containsKey(fileName)) {
|
||||
map.put(fileName, new ConfigCacheClient(executor, configStorageClient));
|
||||
}
|
||||
configCacheClient = map.get(fileName);
|
||||
} catch (Throwable th) {
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
return configCacheClient;
|
||||
}
|
||||
|
||||
public /* synthetic */ Void lambda$put$0(ConfigContainer configContainer) throws Exception {
|
||||
return this.storageClient.write(configContainer);
|
||||
}
|
||||
|
||||
public /* synthetic */ Task lambda$put$1(boolean z3, ConfigContainer configContainer, Void r32) throws Exception {
|
||||
if (z3) {
|
||||
updateInMemoryConfigContainer(configContainer);
|
||||
}
|
||||
return Tasks.forResult(configContainer);
|
||||
}
|
||||
|
||||
private synchronized void updateInMemoryConfigContainer(ConfigContainer configContainer) {
|
||||
this.cachedContainerTask = Tasks.forResult(configContainer);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
synchronized (this) {
|
||||
this.cachedContainerTask = Tasks.forResult(null);
|
||||
}
|
||||
this.storageClient.clear();
|
||||
}
|
||||
|
||||
public synchronized Task<ConfigContainer> get() {
|
||||
try {
|
||||
Task<ConfigContainer> task = this.cachedContainerTask;
|
||||
if (task != null) {
|
||||
if (task.isComplete() && !this.cachedContainerTask.isSuccessful()) {
|
||||
}
|
||||
}
|
||||
Executor executor = this.executor;
|
||||
ConfigStorageClient configStorageClient = this.storageClient;
|
||||
Objects.requireNonNull(configStorageClient);
|
||||
this.cachedContainerTask = Tasks.call(executor, new com.google.firebase.installations.b(configStorageClient, 2));
|
||||
} catch (Throwable th) {
|
||||
throw th;
|
||||
}
|
||||
return this.cachedContainerTask;
|
||||
}
|
||||
|
||||
public ConfigContainer getBlocking() {
|
||||
return getBlocking(DISK_READ_TIMEOUT_IN_SECONDS);
|
||||
}
|
||||
|
||||
public synchronized Task<ConfigContainer> getCachedContainerTask() {
|
||||
return this.cachedContainerTask;
|
||||
}
|
||||
|
||||
public Task<ConfigContainer> put(ConfigContainer configContainer) {
|
||||
return put(configContainer, true);
|
||||
}
|
||||
|
||||
public ConfigContainer getBlocking(long j4) {
|
||||
synchronized (this) {
|
||||
try {
|
||||
Task<ConfigContainer> task = this.cachedContainerTask;
|
||||
if (task != null && task.isSuccessful()) {
|
||||
return this.cachedContainerTask.getResult();
|
||||
}
|
||||
try {
|
||||
return (ConfigContainer) await(get(), j4, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException e4) {
|
||||
Log.d(FirebaseRemoteConfig.TAG, "Reading from storage file failed.", e4);
|
||||
return null;
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task<ConfigContainer> put(final ConfigContainer configContainer, final boolean z3) {
|
||||
return Tasks.call(this.executor, new com.google.firebase.crashlytics.internal.metadata.a(2, this, configContainer)).onSuccessTask(this.executor, new SuccessContinuation() { // from class: com.google.firebase.remoteconfig.internal.b
|
||||
@Override // com.google.android.gms.tasks.SuccessContinuation
|
||||
public final Task then(Object obj) {
|
||||
Task lambda$put$1;
|
||||
lambda$put$1 = ConfigCacheClient.this.lambda$put$1(z3, configContainer, (Void) obj);
|
||||
return lambda$put$1;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user