Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dex Modification Modes #19

Merged
merged 13 commits into from
Nov 20, 2024
3 changes: 3 additions & 0 deletions manager/src/main/java/org/lsposed/lspatch/Patcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import org.lsposed.lspatch.share.PatchConfig
import org.lsposed.patch.LSPatch
import org.lsposed.patch.util.Logger
import java.io.IOException
import java.util.Collections.addAll

object Patcher {

class Options(
private val injectDex: Boolean,
private val config: PatchConfig,
private val apkPaths: List<String>,
private val embeddedModules: List<String>?
Expand All @@ -31,6 +33,7 @@ object Patcher {
embeddedModules?.forEach {
add("-m"); add(it)
}
if(injectDex) add("--injectdex")
if (!MyKeyStore.useDefault) {
addAll(arrayOf("-k", MyKeyStore.file.path, Configs.keyStorePassword, Configs.keyStoreAlias, Configs.keyStoreAliasPassword))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,15 @@ private fun PatchOptionsBody(modifier: Modifier, onAddEmbed: () -> Unit) {
title = stringResource(R.string.patch_override_version_code),
desc = stringResource(R.string.patch_override_version_code_desc)
)

SettingsCheckBox(
modifier = Modifier.clickable { viewModel.injectDex = !viewModel.injectDex },
checked = viewModel.injectDex,
icon = Icons.Outlined.Code,
title = stringResource(R.string.patch_inject_dex),
desc = stringResource(R.string.patch_inject_dex_desc)
)

var bypassExpanded by remember { mutableStateOf(false) }
AnywhereDropdown(
expanded = bypassExpanded,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class NewPatchViewModel : ViewModel() {
var debuggable by mutableStateOf(false)
var overrideVersionCode by mutableStateOf(false)
var sigBypassLevel by mutableStateOf(2)
var injectDex by mutableStateOf(false)
var embeddedModules = emptyList<AppInfo>()

lateinit var patchApp: AppInfo
Expand Down Expand Up @@ -90,6 +91,7 @@ class NewPatchViewModel : ViewModel() {
Log.d(TAG, "Submit patch")
if (useManager) embeddedModules = emptyList()
patchOptions = Patcher.Options(
injectDex = injectDex,
config = PatchConfig(useManager, debuggable, overrideVersionCode, sigBypassLevel, null, null),
apkPaths = listOf(patchApp.app.sourceDir) + (patchApp.app.splitSourceDirs ?: emptyArray()),
embeddedModules = embeddedModules.flatMap { listOf(it.app.sourceDir) + (it.app.splitSourceDirs ?: emptyArray()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class AppManageViewModel : ViewModel() {
}
}
}
Patcher.patch(logger, Patcher.Options(config, patchPaths, embeddedModulePaths))
Patcher.patch(logger, Patcher.Options(false, config, patchPaths, embeddedModulePaths))
val (status, message) = LSPPackageManager.install()
if (status != PackageInstaller.STATUS_SUCCESS) throw RuntimeException(message)
}
Expand Down
2 changes: 2 additions & 0 deletions manager/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@
<string name="settings_keystore_wrong_alias">别名错误</string>
<string name="settings_keystore_wrong_alias_password">别名密码错误</string>
<string name="settings_detail_patch_logs">详细修补日志</string>
<string name="patch_inject_dex">注入加载器 Dex</string>
<string name="patch_inject_dex_desc">对那些需要孤立服务进程的应用程序,譬如说浏览器的渲染引擎,请勾选此选项以确保他们正常运行</string>
</resources>
2 changes: 2 additions & 0 deletions manager/src/main/res/values-zh-rTW/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@
<string name="settings_keystore_wrong_alias">別名錯誤</string>
<string name="settings_keystore_wrong_alias_password">別名密碼錯誤</string>
<string name="settings_detail_patch_logs">詳細打包日誌</string>
<string name="patch_inject_dex">注入加載器 Dex</string>
<string name="patch_inject_dex_desc">對那些需要孤立服務進程的應用程序,譬如說瀏覽器的渲染引擎,請勾選此選項以確保他們正常運行</string>
</resources>
2 changes: 2 additions & 0 deletions manager/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,6 @@
<string name="settings_keystore_wrong_alias">Wrong alias name</string>
<string name="settings_keystore_wrong_alias_password">Wrong alias password</string>
<string name="settings_detail_patch_logs">Detail patch logs</string>
<string name="patch_inject_dex">Inject loader dex</string>
<string name="patch_inject_dex_desc">For applications with isolated services, such as the render engines of browsers, please turn on this option to ensure that they work properly.</string>
</resources>
24 changes: 16 additions & 8 deletions patch/src/main/java/org/lsposed/patch/LSPatch.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

public class LSPatch {
Expand Down Expand Up @@ -79,6 +78,9 @@ public PatchError(String message, Throwable cause) {
@Parameter(names = {"-l", "--sigbypasslv"}, description = "Signature bypass level. 0 (disable), 1 (pm), 2 (pm+openat). default 0")
private int sigbypassLevel = 0;

@Parameter(names = {"--injectdex"}, description = "Inject directly the loder dex file into the original application package")
private boolean injectDex = false;

@Parameter(names = {"-k", "--keystore"}, arity = 4, description = "Set custom signature keystore. Followed by 4 arguments: keystore path, keystore password, keystore alias, keystore alias password")
private List<String> keystoreArgs = Arrays.asList(null, "123456", "key0", "123456");

Expand Down Expand Up @@ -208,7 +210,7 @@ public void patch(File srcApkFile, File outputFile) throws PatchError, IOExcepti

String originalSignature = null;
if (sigbypassLevel > 0) {
originalSignature = ApkSignatureHelper.getApkSignInfo(srcApkFile.getAbsolutePath());
originalSignature = ApkSignatureHelper.getApkSignInfo(srcApkFile.getAbsolutePath());
if (originalSignature == null || originalSignature.isEmpty()) {
throw new PatchError("get original signature failed");
}
Expand Down Expand Up @@ -239,7 +241,8 @@ public void patch(File srcApkFile, File outputFile) throws PatchError, IOExcepti
for (StoredEntry entry : srcZFile.entries()) {
String name = entry.getCentralDirectoryHeader().getName();
if (dstZFile.get(name) != null) continue;
if (name.startsWith("META-INF") && (name.endsWith(".SF") || name.endsWith(".MF") || name.endsWith(".RSA"))) continue;
if (name.startsWith("META-INF") && (name.endsWith(".SF") || name.endsWith(".MF") || name.endsWith(".RSA")))
continue;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a newline here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDEA code optimization

srcZFile.addFileLink(name, name);
}
return;
Expand All @@ -266,11 +269,15 @@ public void patch(File srcApkFile, File outputFile) throws PatchError, IOExcepti

logger.i("Adding metaloader dex...");
try (var is = getClass().getClassLoader().getResourceAsStream(Constants.META_LOADER_DEX_ASSET_PATH)) {
var dexCount = srcZFile.entries().stream().filter(entry -> {
var name = entry.getCentralDirectoryHeader().getName();
return name.startsWith("classes") && name.endsWith(".dex");
}).collect(Collectors.toList()).size() + 1;
dstZFile.add("classes" + dexCount + ".dex", is);
if (!injectDex) {
dstZFile.add("classes.dex", is);
} else {
var dexCount = srcZFile.entries().stream().filter(entry -> {
var name = entry.getCentralDirectoryHeader().getName();
return name.startsWith("classes") && name.endsWith(".dex");
}).collect(Collectors.toList()).size() + 1;
dstZFile.add("classes" + dexCount + ".dex", is);
}
} catch (Throwable e) {
throw new PatchError("Error when adding dex", e);
}
Expand Down Expand Up @@ -307,6 +314,7 @@ public void patch(File srcApkFile, File outputFile) throws PatchError, IOExcepti
for (StoredEntry entry : srcZFile.entries()) {
String name = entry.getCentralDirectoryHeader().getName();
if (dstZFile.get(name) != null) continue;
if (!injectDex && name.startsWith("classes") && name.endsWith(".dex")) continue;
if (name.equals("AndroidManifest.xml")) continue;
if (name.startsWith("META-INF") && (name.endsWith(".SF") || name.endsWith(".MF") || name.endsWith(".RSA"))) continue;
srcZFile.addFileLink(name, name);
Expand Down