CrackMe.apk
Download file
package com.facebook.soloader;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Parcel;
import android.os.Process;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import android.util.Log;
import com.facebook.soloader.MinElf;
import dalvik.system.BaseDexClassLoader;
import java.io.DataOutput;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.annotation.Nullable;
public final class SysUtil {
private static final long APK_DEP_BLOCK_METADATA_LENGTH = 20;
private static final byte APK_SIGNATURE_VERSION = 1;
private static final String TAG = "SysUtil";
public static int findAbiScore(String[] strArr, String str) {
for (int i = 0; i < strArr.length; i++) {
if (strArr[i] != null && str.equals(strArr[i])) {
return i;
}
}
return -1;
}
public static void deleteOrThrow(File file) throws IOException {
File parentFile = file.getParentFile();
if (parentFile != null && !parentFile.canWrite() && !parentFile.setWritable(true)) {
Log.e(TAG, "Enable write permission failed: " + parentFile);
}
if (!file.delete() && file.exists()) {
throw new IOException("Could not delete file " + file);
}
}
public static String[] getSupportedAbis() {
if (Build.VERSION.SDK_INT >= 23) {
return MarshmallowSysdeps.getSupportedAbis();
}
if (Build.VERSION.SDK_INT >= 21) {
return LollipopSysdeps.getSupportedAbis();
}
return new String[]{Build.CPU_ABI, Build.CPU_ABI2};
}
public static void fallocateIfSupported(FileDescriptor fileDescriptor, long j) throws IOException {
if (Build.VERSION.SDK_INT >= 21) {
LollipopSysdeps.fallocateIfSupported(fileDescriptor, j);
}
}
public static void dumbDeleteRecursive(File file) throws IOException {
if (file.isDirectory()) {
File[] listFiles = file.listFiles();
if (listFiles != null) {
for (File dumbDeleteRecursive : listFiles) {
dumbDeleteRecursive(dumbDeleteRecursive);
}
} else {
return;
}
}
deleteOrThrow(file);
}
private static final class LollipopSysdeps {
private LollipopSysdeps() {
}
public static String[] getSupportedAbis() {
String[] strArr = Build.SUPPORTED_ABIS;
TreeSet treeSet = new TreeSet();
try {
if (is64Bit()) {
treeSet.add(MinElf.ISA.AARCH64.toString());
treeSet.add(MinElf.ISA.X86_64.toString());
} else {
treeSet.add(MinElf.ISA.ARM.toString());
treeSet.add(MinElf.ISA.X86.toString());
}
ArrayList arrayList = new ArrayList();
for (String str : strArr) {
if (treeSet.contains(str)) {
arrayList.add(str);
}
}
return (String[]) arrayList.toArray(new String[arrayList.size()]);
} catch (ErrnoException e) {
Log.e(SysUtil.TAG, String.format("Could not read /proc/self/exe. Falling back to default ABI list: %s. errno: %d Err msg: %s", new Object[]{Arrays.toString(strArr), Integer.valueOf(e.errno), e.getMessage()}));
return Build.SUPPORTED_ABIS;
}
}
public static void fallocateIfSupported(FileDescriptor fileDescriptor, long j) throws IOException {
try {
Os.posix_fallocate(fileDescriptor, 0, j);
} catch (ErrnoException e) {
if (e.errno != OsConstants.EOPNOTSUPP && e.errno != OsConstants.ENOSYS && e.errno != OsConstants.EINVAL) {
throw new IOException(e.toString(), e);
}
}
}
public static boolean is64Bit() throws ErrnoException {
return Os.readlink("/proc/self/exe").contains("64");
}
}
private static final class MarshmallowSysdeps {
private MarshmallowSysdeps() {
}
public static String[] getSupportedAbis() {
String[] strArr = Build.SUPPORTED_ABIS;
TreeSet treeSet = new TreeSet();
if (is64Bit()) {
treeSet.add(MinElf.ISA.AARCH64.toString());
treeSet.add(MinElf.ISA.X86_64.toString());
} else {
treeSet.add(MinElf.ISA.ARM.toString());
treeSet.add(MinElf.ISA.X86.toString());
}
ArrayList arrayList = new ArrayList();
for (String str : strArr) {
if (treeSet.contains(str)) {
arrayList.add(str);
}
}
return (String[]) arrayList.toArray(new String[arrayList.size()]);
}
public static boolean is64Bit() {
return Process.is64Bit();
}
public static boolean isSupportedDirectLoad(Context context, int i) throws IOException {
if (i == 2) {
return isApkUncompressedDso(context);
}
return isDisabledExtractNativeLibs(context);
}
public static boolean isDisabledExtractNativeLibs(Context context) {
return context != null && (context.getApplicationInfo().flags & 268435456) == 0;
}
private static boolean isApkUncompressedDso(Context context) throws IOException {
ZipFile zipFile = new ZipFile(new File(context.getApplicationInfo().sourceDir));
try {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (true) {
boolean z = false;
if (entries.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) entries.nextElement();
if (zipEntry != null && zipEntry.getName().endsWith(".so") && zipEntry.getName().contains("/lib")) {
if (zipEntry.getMethod() == 0) {
z = true;
}
zipFile.close();
return z;
}
} else {
zipFile.close();
return false;
}
}
} catch (Throwable th) {
th.addSuppressed(th);
}
throw th;
}
}
public static void mkdirOrThrow(File file) throws IOException {
if (!file.mkdirs() && !file.isDirectory()) {
throw new IOException("cannot mkdir: " + file);
}
}
static int copyBytes(DataOutput dataOutput, InputStream inputStream, int i, byte[] bArr) throws IOException {
int i2 = 0;
while (i2 < i) {
int read = inputStream.read(bArr, 0, Math.min(bArr.length, i - i2));
if (read == -1) {
break;
}
dataOutput.write(bArr, 0, read);
i2 += read;
}
return i2;
}
public static void fsyncRecursive(File file) throws IOException {
if (file.isDirectory()) {
File[] listFiles = file.listFiles();
if (listFiles != null) {
for (File fsyncRecursive : listFiles) {
fsyncRecursive(fsyncRecursive);
}
return;
}
throw new IOException("cannot list directory " + file);
} else if (!file.getPath().endsWith("_lock")) {
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
try {
randomAccessFile.getFD().sync();
randomAccessFile.close();
return;
} catch (Throwable th) {
th.addSuppressed(th);
}
} else {
return;
}
throw th;
}
private static long getParcelPadSize(long j) {
return j + ((4 - (j % 4)) % 4);
}
public static long getApkDepBlockLength(File file) throws IOException {
return getParcelPadSize((long) ((file.getCanonicalFile().getPath().length() + 1) * 2)) + 20;
}
public static byte[] makeApkDepBlock(File file, Context context) throws IOException {
File canonicalFile = file.getCanonicalFile();
Parcel obtain = Parcel.obtain();
try {
obtain.writeByte((byte) 1);
obtain.writeString(canonicalFile.getPath());
obtain.writeLong(canonicalFile.lastModified());
obtain.writeInt(getAppVersionCode(context));
return obtain.marshall();
} finally {
obtain.recycle();
}
}
public static int getAppVersionCode(Context context) {
PackageManager packageManager = context.getPackageManager();
if (packageManager != null) {
try {
return packageManager.getPackageInfo(context.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException | RuntimeException unused) {
}
}
return 0;
}
public static boolean is64Bit() {
if (Build.VERSION.SDK_INT >= 23) {
return MarshmallowSysdeps.is64Bit();
}
if (Build.VERSION.SDK_INT < 21) {
return false;
}
try {
return LollipopSysdeps.is64Bit();
} catch (Exception e) {
Log.e(TAG, String.format("Could not read /proc/self/exe. Err msg: %s", new Object[]{e.getMessage()}));
return false;
}
}
public static boolean isSupportedDirectLoad(Context context, int i) throws IOException {
if (Build.VERSION.SDK_INT >= 23) {
return MarshmallowSysdeps.isSupportedDirectLoad(context, i);
}
return false;
}
public static boolean isDisabledExtractNativeLibs(Context context) {
if (Build.VERSION.SDK_INT >= 23) {
return MarshmallowSysdeps.isDisabledExtractNativeLibs(context);
}
return false;
}
@Nullable
public static FileLocker getOrCreateLockOnDir(File file, File file2, boolean z) throws IOException {
boolean z2 = true;
if (!z) {
return FileLocker.tryLock(file2);
}
try {
return FileLocker.lock(file2);
} catch (FileNotFoundException e) {
if (!file.setWritable(true)) {
throw e;
} else if (z) {
FileLocker lock = FileLocker.lock(file2);
if (!file.setWritable(false)) {
Log.w(TAG, "error removing " + file.getCanonicalPath() + " write permission");
}
return lock;
} else {
FileLocker tryLock = FileLocker.tryLock(file2);
if (!file.setWritable(false)) {
Log.w(TAG, "error removing " + file.getCanonicalPath() + " write permission");
}
return tryLock;
}
} catch (Throwable th) {
th = th;
}
if (z2 && !file.setWritable(false)) {
Log.w(TAG, "error removing " + file.getCanonicalPath() + " write permission");
}
throw th;
}
public static String getBaseName(String str) {
int lastIndexOf = str.lastIndexOf(46);
return lastIndexOf > 0 ? str.substring(0, lastIndexOf) : str;
}
public static class Api14Utils {
public static String getClassLoaderLdLoadLibrary() {
ClassLoader classLoader = SoLoader.class.getClassLoader();
if (classLoader == null || (classLoader instanceof BaseDexClassLoader)) {
try {
return (String) BaseDexClassLoader.class.getMethod("getLdLibraryPath", new Class[0]).invoke((BaseDexClassLoader) classLoader, new Object[0]);
} catch (Exception e) {
throw new RuntimeException("Cannot call getLdLibraryPath", e);
}
} else {
throw new IllegalStateException("ClassLoader " + classLoader.getClass().getName() + " should be of type BaseDexClassLoader");
}
}
}
}
Download file