Commit 52cf7200 authored by vvb2060's avatar vvb2060 Committed by John Wu

Update resources load

addAssetPath supports apk and directory
parent 68874bf5
...@@ -3,6 +3,7 @@ package com.topjohnwu.magisk; ...@@ -3,6 +3,7 @@ package com.topjohnwu.magisk;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
...@@ -57,12 +58,24 @@ public class StubApk { ...@@ -57,12 +58,24 @@ public class StubApk {
return new File(getDynDir(info), "update.apk"); return new File(getDynDir(info), "update.apk");
} }
@TargetApi(Build.VERSION_CODES.R)
private static ResourcesLoader getResourcesLoader(File path) throws IOException {
var loader = new ResourcesLoader();
ResourcesProvider provider;
if (path.isDirectory()) {
provider = ResourcesProvider.loadFromDirectory(path.getPath(), null);
} else {
var fd = ParcelFileDescriptor.open(path, MODE_READ_ONLY);
provider = ResourcesProvider.loadFromApk(fd);
}
loader.addProvider(provider);
return loader;
}
public static void addAssetPath(Resources res, String path) { public static void addAssetPath(Resources res, String path) {
if (SDK_INT >= Build.VERSION_CODES.R) { if (SDK_INT >= Build.VERSION_CODES.R) {
try (var fd = ParcelFileDescriptor.open(new File(path), MODE_READ_ONLY)) { try {
var loader = new ResourcesLoader(); res.addLoaders(getResourcesLoader(new File(path)));
loader.addProvider(ResourcesProvider.loadFromApk(fd));
res.addLoaders(loader);
} catch (IOException ignored) {} } catch (IOException ignored) {}
} else { } else {
AssetManager asset = res.getAssets(); AssetManager asset = res.getAssets();
......
...@@ -35,9 +35,6 @@ import java.io.FileOutputStream; ...@@ -35,9 +35,6 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.zip.InflaterInputStream; import java.util.zip.InflaterInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.CipherInputStream; import javax.crypto.CipherInputStream;
...@@ -162,47 +159,36 @@ public class DownloadActivity extends Activity { ...@@ -162,47 +159,36 @@ public class DownloadActivity extends Activity {
} }
private void decryptResources(OutputStream out) throws Exception { private void decryptResources(OutputStream out) throws Exception {
try (var zip = new ZipOutputStream(out)) { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
zip.putNextEntry(new ZipEntry("resources.arsc")); SecretKey key = new SecretKeySpec(Bytes.key(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec iv = new IvParameterSpec(Bytes.iv());
SecretKey key = new SecretKeySpec(Bytes.key(), "AES"); cipher.init(Cipher.DECRYPT_MODE, key, iv);
IvParameterSpec iv = new IvParameterSpec(Bytes.iv()); var is = new InflaterInputStream(new CipherInputStream(
cipher.init(Cipher.DECRYPT_MODE, key, iv); new ByteArrayInputStream(Bytes.res()), cipher));
var is = new InflaterInputStream(new CipherInputStream( try (is; out) {
new ByteArrayInputStream(Bytes.res()), cipher)); APKInstall.transfer(is, out);
try (is) {
APKInstall.transfer(is, zip);
}
zip.closeEntry();
zip.putNextEntry(new ZipEntry("AndroidManifest.xml"));
var apk = new ZipFile(getPackageResourcePath());
var xml = apk.getInputStream(apk.getEntry("AndroidManifest.xml"));
try (apk; xml) {
APKInstall.transfer(xml, zip);
}
zip.closeEntry();
} }
} }
private void loadResources() throws Exception { private void loadResources() throws Exception {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
var fd = Os.memfd_create("res.apk", 0); var fd = Os.memfd_create("res", 0);
try { try {
decryptResources(new FileOutputStream(fd)); decryptResources(new FileOutputStream(fd));
Os.lseek(fd, 0, OsConstants.SEEK_SET); Os.lseek(fd, 0, OsConstants.SEEK_SET);
try (var pfd = ParcelFileDescriptor.dup(fd)) { var loader = new ResourcesLoader();
var loader = new ResourcesLoader(); try (var pfd = ParcelFileDescriptor.dup(fd);
loader.addProvider(ResourcesProvider.loadFromApk(pfd)); var provider = ResourcesProvider.loadFromTable(pfd, null)) {
loader.addProvider(provider);
getResources().addLoaders(loader); getResources().addLoaders(loader);
} }
} finally { } finally {
Os.close(fd); Os.close(fd);
} }
} else { } else {
File apk = new File(getCacheDir(), "res.apk"); File dir = new File(getCodeCacheDir(), "res");
decryptResources(new FileOutputStream(apk)); decryptResources(new FileOutputStream(new File(dir, "resources.arsc")));
StubApk.addAssetPath(getResources(), apk.getPath()); StubApk.addAssetPath(getResources(), dir.getPath());
} }
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment