Drop v1 signature & UI improvement

This commit is contained in:
Nullptr 2022-09-06 21:20:06 +08:00
parent b1691a95e2
commit 2e2c818de6
No known key found for this signature in database
7 changed files with 15 additions and 67 deletions

View File

@ -25,8 +25,6 @@ object Patcher {
add("-o"); add(lspApp.tmpApkDir.absolutePath)
if (config.debuggable) add("-d")
add("-l"); add(config.sigBypassLevel.toString())
add("--v1"); add(config.v1.toString())
add("--v2"); add(config.v2.toString())
if (config.useManager) add("--manager")
if (config.overrideVersionCode) add("-r")
if (Configs.detailPatchLogs) add("-v")

View File

@ -176,7 +176,6 @@ private fun sigBypassLvStr(level: Int) = when (level) {
else -> throw IllegalArgumentException("Invalid sigBypassLv: $level")
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun PatchOptionsBody(modifier: Modifier, onAddEmbed: () -> Unit) {
val viewModel = viewModel<NewPatchViewModel>()
@ -236,34 +235,6 @@ private fun PatchOptionsBody(modifier: Modifier, onAddEmbed: () -> Unit) {
title = stringResource(R.string.patch_override_version_code),
desc = stringResource(R.string.patch_override_version_code_desc)
)
var signExpanded by remember { mutableStateOf(false) }
AnywhereDropdown(
expanded = signExpanded,
onDismissRequest = { signExpanded = false },
onClick = { signExpanded = true },
surface = {
SettingsItem(
icon = Icons.Outlined.Edit,
title = stringResource(R.string.patch_sign),
desc = viewModel.sign
.mapIndexedNotNull { index, on -> if (on) "V" + (index + 1) else null }
.joinToString(" + ")
.ifEmpty { "None" }
)
}
) {
repeat(2) { index ->
DropdownMenuItem(
text = {
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(checked = viewModel.sign[index], onCheckedChange = { viewModel.sign[index] = !viewModel.sign[index] })
Text("V" + (index + 1))
}
},
onClick = { viewModel.sign[index] = !viewModel.sign[index] }
)
}
}
var bypassExpanded by remember { mutableStateOf(false) }
AnywhereDropdown(
expanded = bypassExpanded,

View File

@ -37,7 +37,6 @@ class NewPatchViewModel : ViewModel() {
var useManager by mutableStateOf(true)
var debuggable by mutableStateOf(false)
var overrideVersionCode by mutableStateOf(false)
val sign = mutableStateListOf(false, true)
var sigBypassLevel by mutableStateOf(2)
var embeddedModules = emptyList<AppInfo>()
@ -89,7 +88,7 @@ class NewPatchViewModel : ViewModel() {
Log.d(TAG, "Submit patch")
if (useManager) embeddedModules = emptyList()
patchOptions = Patcher.Options(
config = PatchConfig(useManager, debuggable, overrideVersionCode, sign[0], sign[1], sigBypassLevel, null, null),
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()) }
)

View File

@ -21,12 +21,10 @@ import org.lsposed.lspatch.Constants.PATCH_FILE_SUFFIX
import org.lsposed.lspatch.config.ConfigManager
import org.lsposed.lspatch.config.Configs
import org.lsposed.lspatch.lspApp
import org.lsposed.patch.util.ManifestParser
import java.io.File
import java.io.IOException
import java.text.Collator
import java.util.*
import java.util.zip.ZipFile
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
@ -150,9 +148,8 @@ object LSPPackageManager {
suspend fun getAppInfoFromApks(apks: List<Uri>): Result<AppInfo> {
return withContext(Dispatchers.IO) {
runCatching {
val app = ApplicationInfo()
if (apks.size > 1) app.splitSourceDirs = Array<String?>(apks.size - 1) { null }
apks.forEachIndexed { index, uri ->
var primary: ApplicationInfo? = null
val splits = apks.mapNotNull { uri ->
val src = DocumentFile.fromSingleUri(lspApp, uri)
?: throw IOException("DocumentFile is null")
val dst = lspApp.tmpApkDir.resolve(src.name!!)
@ -163,21 +160,18 @@ object LSPPackageManager {
input.copyTo(output)
}
}
ZipFile(dst).use { zip ->
val entry = zip.getEntry("AndroidManifest.xml")
?: throw IOException("AndroidManifest.xml is not found")
zip.getInputStream(entry).use {
val info = ManifestParser.parseManifestFile(it)
if (app.packageName != null && app.packageName != info.packageName) {
throw IOException("Selected apks are not of the same app")
if (primary == null) {
primary = lspApp.packageManager.getPackageArchiveInfo(dst.absolutePath, 0)?.applicationInfo
if (primary != null) return@mapNotNull null
}
app.packageName = info.packageName
dst.absolutePath
}
}
if (index == 0) app.sourceDir = dst.absolutePath
else app.splitSourceDirs[index - 1] = dst.absolutePath
}
AppInfo(app, app.packageName)
// TODO: Check selected apks are from the same app
if (primary == null) throw IllegalArgumentException("No primary apk")
val label = lspApp.packageManager.getApplicationLabel(primary!!).toString()
if (splits.isNotEmpty()) primary!!.splitSourceDirs = splits.toTypedArray()
AppInfo(primary!!, label)
}.recoverCatching { t ->
cleanTmpApkDir()
Log.e(TAG, "Failed to load apks", t)

View File

@ -53,7 +53,6 @@
<string name="patch_portable_desc">Patch an app with modules embedded.\nThe patched app can run without the manager, but cannot be managed dynamically.\nPortable patched apps can be used on devices that do not have LSPatch Manager installed.</string>
<string name="patch_embed_modules">Embed modules</string>
<string name="patch_debuggable">Debuggable</string>
<string name="patch_sign">Sign</string>
<string name="patch_sigbypass">Signature bypass</string>
<string name="patch_sigbypasslv0">lv0: Off</string>
<string name="patch_sigbypasslv1">lv1: Bypass PM</string>

View File

@ -79,12 +79,6 @@ public class LSPatch {
@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");
@Parameter(names = {"--v1"}, arity = 1, description = "Sign with v1 signature")
private boolean v1 = false;
@Parameter(names = {"--v2"}, arity = 1, description = "Sign with v2 signature")
private boolean v2 = true;
@Parameter(names = {"--manager"}, description = "Use manager (Cannot work with embedding modules)")
private boolean useManager = false;
@ -207,8 +201,7 @@ public class LSPatch {
var entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(keystoreArgs.get(2), new KeyStore.PasswordProtection(keystoreArgs.get(3).toCharArray()));
new SigningExtension(SigningOptions.builder()
.setMinSdkVersion(28)
.setV1SigningEnabled(v1)
.setV2SigningEnabled(v2)
.setV2SigningEnabled(true)
.setCertificates((X509Certificate[]) entry.getCertificateChain())
.setKey(entry.getPrivateKey())
.build()).register(dstZFile);
@ -239,7 +232,7 @@ public class LSPatch {
logger.i("Patching apk...");
// modify manifest
final var config = new PatchConfig(useManager, debuggableFlag, overrideVersionCode, v1, v2, sigbypassLevel, originalSignature, appComponentFactory);
final var config = new PatchConfig(useManager, debuggableFlag, overrideVersionCode, sigbypassLevel, originalSignature, appComponentFactory);
final var configBytes = new Gson().toJson(config).getBytes(StandardCharsets.UTF_8);
final var metadata = Base64.getEncoder().encodeToString(configBytes);
try (var is = new ByteArrayInputStream(modifyManifestFile(manifestEntry.open(), metadata))) {

View File

@ -5,8 +5,6 @@ public class PatchConfig {
public final boolean useManager;
public final boolean debuggable;
public final boolean overrideVersionCode;
public final boolean v1;
public final boolean v2;
public final int sigBypassLevel;
public final String originalSignature;
public final String appComponentFactory;
@ -16,8 +14,6 @@ public class PatchConfig {
boolean useManager,
boolean debuggable,
boolean overrideVersionCode,
boolean v1,
boolean v2,
int sigBypassLevel,
String originalSignature,
String appComponentFactory
@ -25,8 +21,6 @@ public class PatchConfig {
this.useManager = useManager;
this.debuggable = debuggable;
this.overrideVersionCode = overrideVersionCode;
this.v1 = v1;
this.v2 = v2;
this.sigBypassLevel = sigBypassLevel;
this.originalSignature = originalSignature;
this.appComponentFactory = appComponentFactory;