Code refactoring

This commit is contained in:
topjohnwu
2022-02-13 07:24:34 -08:00
parent c09b4dabc4
commit b7fc15d399
5 changed files with 142 additions and 176 deletions
@@ -1,33 +1,124 @@
package com.topjohnwu.magisk;
import android.app.job.JobService;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.ServiceInfo;
import com.topjohnwu.magisk.dummy.DummyProvider;
import com.topjohnwu.magisk.dummy.DummyReceiver;
import com.topjohnwu.magisk.dummy.DummyService;
import com.topjohnwu.magisk.utils.DynamicClassLoader;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import io.michaelrocks.paranoid.Obfuscate;
// Wrap the actual classloader as we only want to resolve classname
// mapping when loading from platform (via LoadedApk.mClassLoader)
class InjectedClassLoader extends ClassLoader {
@Obfuscate
class AppClassLoader extends ClassLoader {
InjectedClassLoader(File apk) {
final Map<String, String> mapping = new HashMap<>();
AppClassLoader(File apk) {
super(new DynamicClassLoader(apk));
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
String clz = DynLoad.componentMap.get(name);
String clz = mapping.get(name);
name = clz != null ? clz : name;
return super.loadClass(name, resolve);
}
void updateComponentMap(PackageInfo stub, PackageInfo app) {
{
var src = stub.activities;
var dest = app.activities;
final ActivityInfo sa;
final ActivityInfo da;
final ActivityInfo sb;
final ActivityInfo db;
if (src[0].exported) {
sa = src[0];
sb = src[1];
} else {
sa = src[1];
sb = src[0];
}
if (dest[0].exported) {
da = dest[0];
db = dest[1];
} else {
da = dest[1];
db = dest[0];
}
mapping.put(sa.name, da.name);
mapping.put(sb.name, db.name);
}
{
var src = stub.services;
var dest = app.services;
final ServiceInfo sa;
final ServiceInfo da;
final ServiceInfo sb;
final ServiceInfo db;
if (JobService.PERMISSION_BIND.equals(src[0].permission)) {
sa = src[0];
sb = src[1];
} else {
sa = src[1];
sb = src[0];
}
if (JobService.PERMISSION_BIND.equals(dest[0].permission)) {
da = dest[0];
db = dest[1];
} else {
da = dest[1];
db = dest[0];
}
mapping.put(sa.name, da.name);
mapping.put(sb.name, db.name);
}
{
var src = stub.receivers;
var dest = app.receivers;
mapping.put(src[0].name, dest[0].name);
}
{
var src = stub.providers;
var dest = app.providers;
mapping.put(src[0].name, dest[0].name);
}
}
}
class RedirectClassLoader extends ClassLoader {
class StubClassLoader extends ClassLoader {
private final Map<String, Class<?>> mapping;
private final Map<String, Class<?>> mapping = new HashMap<>();
RedirectClassLoader(Map<String, Class<?>> m) {
super(RedirectClassLoader.class.getClassLoader());
mapping = m;
StubClassLoader(PackageInfo info) {
super(StubClassLoader.class.getClassLoader());
for (var c : info.activities) {
mapping.put(c.name, DownloadActivity.class);
}
for (var c : info.services) {
mapping.put(c.name, DummyService.class);
}
for (var c : info.providers) {
mapping.put(c.name, DummyProvider.class);
}
for (var c : info.receivers) {
mapping.put(c.name, DummyReceiver.class);
}
}
@Override
@@ -39,12 +130,15 @@ class RedirectClassLoader extends ClassLoader {
class DelegateClassLoader extends ClassLoader {
// The active classloader
static ClassLoader cl = DelegateClassLoader.class.getClassLoader();
DelegateClassLoader() {
super(null);
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
return DynLoad.loader.loadClass(name);
return cl.loadClass(name);
}
}