CrackMe.apk
Download file
package com.facebook.soloader;
import android.content.Context;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.annotation.Nullable;
import org.apache.commons.io.FilenameUtils;
public final class NativeDeps {
private static final float HASHMAP_LOAD_FACTOR = 1.0f;
private static final int INITIAL_HASH = 5381;
private static final int LIB_PREFIX_LEN = 3;
private static final int LIB_PREFIX_SUFFIX_LEN = (3 + 3);
private static final int LIB_SUFFIX_LEN = 3;
private static final String LOG_TAG = "NativeDeps";
private static final int WAITING_THREADS_WARNING_THRESHOLD = 3;
@Nullable
private static byte[] sEncodedDeps = null;
private static volatile boolean sInitialized = false;
private static Map<Integer, List<Integer>> sPrecomputedDeps = null;
private static List<Integer> sPrecomputedLibs = null;
/* access modifiers changed from: private */
public static volatile boolean sUseDepsFileAsync = false;
/* access modifiers changed from: private */
public static final ReentrantReadWriteLock sWaitForDepsFileLock = new ReentrantReadWriteLock();
public static String[] getDependencies(String str, File file) throws IOException {
String[] awaitGetDepsFromPrecomputedDeps = awaitGetDepsFromPrecomputedDeps(str);
if (awaitGetDepsFromPrecomputedDeps != null) {
return awaitGetDepsFromPrecomputedDeps;
}
return MinElf.extract_DT_NEEDED(file);
}
public static String[] getDependencies(String str, ElfByteChannel elfByteChannel) throws IOException {
String[] awaitGetDepsFromPrecomputedDeps = awaitGetDepsFromPrecomputedDeps(str);
if (awaitGetDepsFromPrecomputedDeps != null) {
return awaitGetDepsFromPrecomputedDeps;
}
return MinElf.extract_DT_NEEDED(elfByteChannel);
}
@Nullable
private static String[] awaitGetDepsFromPrecomputedDeps(String str) {
if (sInitialized) {
return tryGetDepsFromPrecomputedDeps(str);
}
if (!sUseDepsFileAsync) {
return null;
}
ReentrantReadWriteLock reentrantReadWriteLock = sWaitForDepsFileLock;
reentrantReadWriteLock.readLock().lock();
try {
String[] tryGetDepsFromPrecomputedDeps = tryGetDepsFromPrecomputedDeps(str);
reentrantReadWriteLock.readLock().unlock();
return tryGetDepsFromPrecomputedDeps;
} catch (Throwable th) {
sWaitForDepsFileLock.readLock().unlock();
throw th;
}
}
public static boolean useDepsFile(final Context context, boolean z, final boolean z2) {
if (!z) {
return useDepsFileFromApkSync(context, z2);
}
new Thread(new Runnable() {
public void run() {
NativeDeps.sWaitForDepsFileLock.writeLock().lock();
boolean unused = NativeDeps.sUseDepsFileAsync = true;
try {
boolean unused2 = NativeDeps.useDepsFileFromApkSync(context, z2);
} finally {
int readLockCount = NativeDeps.sWaitForDepsFileLock.getReadLockCount();
if (readLockCount >= 3) {
Log.w(NativeDeps.LOG_TAG, "NativeDeps initialization finished with " + Integer.toString(readLockCount) + " threads waiting.");
}
NativeDeps.sWaitForDepsFileLock.writeLock().unlock();
boolean unused3 = NativeDeps.sUseDepsFileAsync = false;
}
}
}, "soloader-nativedeps-init").start();
return true;
}
/* access modifiers changed from: private */
public static boolean useDepsFileFromApkSync(Context context, boolean z) {
boolean z2;
try {
z2 = initDeps(context, z);
} catch (IOException unused) {
z2 = false;
}
if (!z2 && z) {
try {
NativeDepsUnpacker.ensureNativeDepsAvailable(context);
z2 = initDeps(context, z);
} catch (IOException unused2) {
}
}
if (!z2) {
Log.w(LOG_TAG, "Failed to extract native deps from APK, falling back to using MinElf to get library dependencies.");
}
return z2;
}
private static boolean initDeps(Context context, boolean z) throws IOException {
byte[] bArr;
byte[] bArr2;
verifyUninitialized();
if (z) {
bArr = SysUtil.makeApkDepBlock(new File(context.getApplicationInfo().sourceDir), context);
bArr2 = NativeDepsUnpacker.readNativeDepsFromDisk(context);
} else {
bArr2 = NativeDepsUnpacker.readNativeDepsFromApk(context);
bArr = null;
}
return processDepsBytes(bArr, bArr2);
}
private static void indexLib(int i, int i2) {
sPrecomputedLibs.add(Integer.valueOf(i2));
List list = sPrecomputedDeps.get(Integer.valueOf(i));
if (list == null) {
list = new ArrayList();
sPrecomputedDeps.put(Integer.valueOf(i), list);
}
list.add(Integer.valueOf(i2));
}
/* JADX WARNING: Removed duplicated region for block: B:24:0x003b */
/* JADX WARNING: Removed duplicated region for block: B:32:? A[RETURN, SYNTHETIC] */
/* Code decompiled incorrectly, please refer to instructions dump. */
private static void indexDepsBytes(byte[] r8, int r9) {
/*
r0 = 0
r1 = 1
r2 = 1
r3 = 0
r4 = 0
L_0x0005:
if (r2 == 0) goto L_0x0023
r3 = 5381(0x1505, float:7.54E-42)
r4 = r9
L_0x000a:
byte r5 = r8[r4] // Catch:{ IndexOutOfBoundsException -> 0x0021 }
r6 = 32
if (r5 <= r6) goto L_0x0018
int r6 = r3 << 5
int r6 = r6 + r3
int r3 = r6 + r5
int r4 = r4 + 1
goto L_0x000a
L_0x0018:
indexLib(r3, r9) // Catch:{ IndexOutOfBoundsException -> 0x0021 }
if (r5 == r6) goto L_0x001f
r2 = 1
goto L_0x0030
L_0x001f:
r2 = 0
goto L_0x0030
L_0x0021:
goto L_0x0036
L_0x0023:
byte r5 = r8[r9] // Catch:{ IndexOutOfBoundsException -> 0x0035 }
r6 = 10
if (r5 == r6) goto L_0x002c
int r9 = r9 + 1
goto L_0x0023
L_0x002c:
r2 = 1
r7 = r4
r4 = r9
r9 = r7
L_0x0030:
int r4 = r4 + r1
r7 = r4
r4 = r9
r9 = r7
goto L_0x0005
L_0x0035:
r9 = r4
L_0x0036:
if (r2 == 0) goto L_0x003e
int r8 = r8.length
if (r9 == r8) goto L_0x003e
indexLib(r3, r9)
L_0x003e:
return
*/
throw new UnsupportedOperationException("Method not decompiled: com.facebook.soloader.NativeDeps.indexDepsBytes(byte[], int):void");
}
private static int verifyBytesAndGetOffset(@Nullable byte[] bArr, @Nullable byte[] bArr2) {
if (bArr == null || bArr.length == 0 || bArr2.length < bArr.length + 4) {
return -1;
}
if (bArr2.length != bArr.length + 4 + ByteBuffer.wrap(bArr2, bArr.length, 4).getInt()) {
return -1;
}
for (int i = 0; i < bArr.length; i++) {
if (bArr[i] != bArr2[i]) {
return -1;
}
}
return bArr.length + 4;
}
private static int findNextLine(byte[] bArr, int i) {
while (i < bArr.length && bArr[i] != 10) {
i++;
}
return i < bArr.length ? i + 1 : i;
}
private static int parseLibCount(byte[] bArr, int i, int i2) {
try {
return Integer.parseInt(new String(bArr, i, i2));
} catch (NumberFormatException unused) {
return -1;
}
}
static boolean processDepsBytes(byte[] bArr, byte[] bArr2) throws IOException {
int i;
int parseLibCount;
if (bArr != null) {
i = verifyBytesAndGetOffset(bArr, bArr2);
if (i == -1) {
return false;
}
} else {
i = 0;
}
int findNextLine = findNextLine(bArr2, i);
if (findNextLine >= bArr2.length || (parseLibCount = parseLibCount(bArr2, i, (findNextLine - i) - 1)) <= 0) {
return false;
}
sPrecomputedDeps = new HashMap(((int) (((float) parseLibCount) / 1.0f)) + 1, 1.0f);
sPrecomputedLibs = new ArrayList(parseLibCount);
indexDepsBytes(bArr2, findNextLine);
if (sPrecomputedLibs.size() != parseLibCount) {
return false;
}
sEncodedDeps = bArr2;
sInitialized = true;
return true;
}
private static boolean libIsAtOffset(String str, int i) {
int i2;
int i3 = LIB_PREFIX_LEN;
while (true) {
int length = str.length();
i2 = LIB_SUFFIX_LEN;
if (i3 < length - i2 && i < sEncodedDeps.length && (str.codePointAt(i3) & 255) == sEncodedDeps[i]) {
i3++;
i++;
}
}
return i3 == str.length() - i2;
}
private static int hashLib(String str) {
int i = INITIAL_HASH;
for (int i2 = LIB_PREFIX_LEN; i2 < str.length() - LIB_SUFFIX_LEN; i2++) {
i = str.codePointAt(i2) + (i << 5) + i;
}
return i;
}
private static int getOffsetForLib(String str) {
List<Integer> list = sPrecomputedDeps.get(Integer.valueOf(hashLib(str)));
if (list == null) {
return -1;
}
for (Integer intValue : list) {
int intValue2 = intValue.intValue();
if (libIsAtOffset(str, intValue2)) {
return intValue2;
}
}
return -1;
}
@Nullable
private static String getLibString(int i) {
if (i >= sPrecomputedLibs.size()) {
return null;
}
int intValue = sPrecomputedLibs.get(i).intValue();
int i2 = intValue;
while (true) {
byte[] bArr = sEncodedDeps;
if (i2 >= bArr.length || bArr[i2] <= 32) {
int i3 = (i2 - intValue) + LIB_PREFIX_SUFFIX_LEN;
char[] cArr = new char[i3];
cArr[0] = 'l';
cArr[1] = 'i';
cArr[2] = 'b';
} else {
i2++;
}
}
int i32 = (i2 - intValue) + LIB_PREFIX_SUFFIX_LEN;
char[] cArr2 = new char[i32];
cArr2[0] = 'l';
cArr2[1] = 'i';
cArr2[2] = 'b';
for (int i4 = 0; i4 < i32 - LIB_PREFIX_SUFFIX_LEN; i4++) {
cArr2[LIB_PREFIX_LEN + i4] = (char) sEncodedDeps[intValue + i4];
}
cArr2[i32 - 3] = FilenameUtils.EXTENSION_SEPARATOR;
cArr2[i32 - 2] = 's';
cArr2[i32 - 1] = 'o';
return new String(cArr2);
}
/* JADX WARNING: Removed duplicated region for block: B:20:0x0040 */
@javax.annotation.Nullable
/* Code decompiled incorrectly, please refer to instructions dump. */
private static java.lang.String[] getDepsForLibAtOffset(int r6, int r7) {
/*
java.util.ArrayList r0 = new java.util.ArrayList
r0.<init>()
int r6 = r6 + r7
int r7 = LIB_PREFIX_SUFFIX_LEN
int r6 = r6 - r7
r7 = 0
r1 = 0
r2 = 0
L_0x000c:
byte[] r3 = sEncodedDeps
int r4 = r3.length
r5 = 0
if (r6 >= r4) goto L_0x003e
byte r3 = r3[r6]
r4 = 10
if (r3 == r4) goto L_0x003e
r4 = 32
if (r3 != r4) goto L_0x002b
if (r2 == 0) goto L_0x003a
java.lang.String r1 = getLibString(r1)
if (r1 != 0) goto L_0x0025
return r5
L_0x0025:
r0.add(r1)
r1 = 0
r2 = 0
goto L_0x003a
L_0x002b:
r2 = 48
if (r3 < r2) goto L_0x003d
r2 = 57
if (r3 <= r2) goto L_0x0034
goto L_0x003d
L_0x0034:
int r1 = r1 * 10
int r3 = r3 + -48
int r1 = r1 + r3
r2 = 1
L_0x003a:
int r6 = r6 + 1
goto L_0x000c
L_0x003d:
return r5
L_0x003e:
if (r2 == 0) goto L_0x004a
java.lang.String r6 = getLibString(r1)
if (r6 != 0) goto L_0x0047
return r5
L_0x0047:
r0.add(r6)
L_0x004a:
int r6 = r0.size()
if (r6 != 0) goto L_0x0051
return r5
L_0x0051:
int r6 = r0.size()
java.lang.String[] r6 = new java.lang.String[r6]
java.lang.Object[] r6 = r0.toArray(r6)
java.lang.String[] r6 = (java.lang.String[]) r6
return r6
*/
throw new UnsupportedOperationException("Method not decompiled: com.facebook.soloader.NativeDeps.getDepsForLibAtOffset(int, int):java.lang.String[]");
}
@Nullable
static String[] tryGetDepsFromPrecomputedDeps(String str) {
int offsetForLib;
if (sInitialized && str.length() > LIB_PREFIX_SUFFIX_LEN && (offsetForLib = getOffsetForLib(str)) != -1) {
return getDepsForLibAtOffset(offsetForLib, str.length());
}
return null;
}
private static void verifyUninitialized() {
if (sInitialized) {
synchronized (NativeDeps.class) {
if (sInitialized) {
throw new IllegalStateException("Trying to initialize NativeDeps but it was already initialized");
}
}
}
}
}
Download file