Magisk/stub/src/main/java/com/topjohnwu/magisk/InjectAPK.java

76 lines
2.6 KiB
Java

package com.topjohnwu.magisk;
import android.app.AppComponentFactory;
import android.app.Application;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import com.topjohnwu.magisk.utils.DynamicClassLoader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class InjectAPK {
static DelegateComponentFactory factory;
static Application setup(Context context) {
File apk = DynAPK.current(context);
File update = DynAPK.update(context);
if (update.exists())
update.renameTo(apk);
Application delegate = null;
if (!apk.exists()) {
// Try copying APK
Uri uri = new Uri.Builder().scheme("content")
.authority("com.topjohnwu.magisk.provider")
.encodedPath("apk_file").build();
ContentResolver resolver = context.getContentResolver();
try (InputStream is = resolver.openInputStream(uri)) {
if (is != null) {
try (OutputStream out = new FileOutputStream(apk)) {
byte[] buf = new byte[4096];
for (int read; (read = is.read(buf)) >= 0;) {
out.write(buf, 0, read);
}
}
}
} catch (Exception e) {
Log.e(InjectAPK.class.getSimpleName(), "", e);
}
}
if (apk.exists()) {
ClassLoader cl = new DynamicClassLoader(apk, factory.loader);
try {
// Create the delegate AppComponentFactory
AppComponentFactory df = (AppComponentFactory)
cl.loadClass("androidx.core.app.CoreComponentFactory").newInstance();
// Create the delegate Application
delegate = (Application) cl.loadClass("a.e").getConstructor(Object.class)
.newInstance(DynAPK.pack(dynData()));
// If everything went well, set our loader and delegate
factory.delegate = df;
factory.loader = cl;
} catch (Exception e) {
Log.e(InjectAPK.class.getSimpleName(), "", e);
apk.delete();
}
}
return delegate;
}
private static DynAPK.Data dynData() {
DynAPK.Data data = new DynAPK.Data();
data.version = BuildConfig.STUB_VERSION;
data.classToComponent = Mapping.inverseMap;
return data;
}
}