Pure 64bit support

This commit is contained in:
vvb2060 2021-05-12 13:40:53 +08:00 committed by John Wu
parent 12aa5838d9
commit 66cc9bc545
13 changed files with 116 additions and 100 deletions

View File

@ -1,3 +1,4 @@
import com.android.build.gradle.internal.api.ApkVariantOutputImpl
import org.apache.tools.ant.filters.FixCrLfFilter
import java.io.PrintStream
@ -41,6 +42,13 @@ android {
}
}
splits {
abi {
isEnable = true
isUniversalApk = true
}
}
buildFeatures {
dataBinding = true
}
@ -88,27 +96,35 @@ val syncLibs by tasks.registering(Sync::class) {
rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" }
}
}
into("arm64-v8a") {
from(rootProject.file("native/out/arm64-v8a")) {
include("busybox", "magiskboot", "magiskinit", "magisk")
rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" }
}
from(rootProject.file("native/out/armeabi-v7a")) {
include("magisk")
rename { if (it == "magisk") "libmagisk32.so" else "lib$it.so" }
}
}
into("x86_64") {
from(rootProject.file("native/out/x86_64")) {
include("busybox", "magiskboot", "magiskinit", "magisk")
rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" }
}
from(rootProject.file("native/out/x86")) {
include("magisk")
rename { if (it == "magisk") "libmagisk32.so" else "lib$it.so" }
}
}
onlyIf {
if (inputs.sourceFiles.files.size != 10)
if (inputs.sourceFiles.files.size != 16)
throw StopExecutionException("Please build binaries first! (./build.py binary)")
true
}
}
val createStubLibs by tasks.registering {
dependsOn(syncLibs)
doLast {
val arm64 = project.file("src/main/jniLibs/arm64-v8a/libstub.so")
arm64.parentFile.mkdirs()
arm64.createNewFile()
val x64 = project.file("src/main/jniLibs/x86_64/libstub.so")
x64.parentFile.mkdirs()
x64.createNewFile()
}
}
val syncAssets by tasks.registering(Sync::class) {
dependsOn(createStubLibs)
dependsOn(syncLibs)
inputs.property("version", Config.version)
inputs.property("versionCode", Config.versionCode)
into("src/main/assets")
@ -123,9 +139,11 @@ val syncAssets by tasks.registering(Sync::class) {
}
filesMatching("**/util_functions.sh") {
filter {
it.replace("#MAGISK_VERSION_STUB",
it.replace(
"#MAGISK_VERSION_STUB",
"MAGISK_VER='${Config.version}'\n" +
"MAGISK_VER_CODE=${Config.versionCode}")
"MAGISK_VER_CODE=${Config.versionCode}"
)
}
filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))
}
@ -178,6 +196,13 @@ android.applicationVariants.all {
}
}
registerJavaGeneratingTask(genSrcTask.get(), outSrcDir)
outputs.all {
val output = this as ApkVariantOutputImpl
output.filters.forEach {
output.versionNameOverride += "-${it.identifier}"
}
}
}
dependencies {

View File

@ -9,7 +9,6 @@
android:name=".core.App"
android:extractNativeLibs="true"
android:icon="@drawable/ic_launcher"
android:multiArch="true"
tools:ignore="UnusedAttribute,GoogleAppIndexingWarning">
<!-- Splash -->

View File

@ -17,7 +17,6 @@ import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.unwrap
import com.topjohnwu.superuser.Shell
import timber.log.Timber
import java.io.File
import kotlin.system.exitProcess
open class App() : Application() {
@ -56,12 +55,6 @@ open class App() : Application() {
val wrapped = impl.wrap()
super.attachBaseContext(wrapped)
val info = base.applicationInfo
val libDir = runCatching {
info.javaClass.getDeclaredField("secondaryNativeLibraryDir").get(info) as String?
}.getOrNull() ?: info.nativeLibraryDir
Const.NATIVE_LIB_DIR = File(libDir)
ServiceLocator.context = wrapped
AssetHack.init(impl)
app.registerActivityLifecycleCallbacks(ForegroundTracker)

View File

@ -3,7 +3,6 @@ package com.topjohnwu.magisk.core
import android.os.Build
import android.os.Process
import com.topjohnwu.magisk.BuildConfig
import java.io.File
@Suppress("DEPRECATION")
object Const {
@ -13,7 +12,6 @@ object Const {
// Paths
lateinit var MAGISKTMP: String
lateinit var NATIVE_LIB_DIR: File
val MAGISK_PATH get() = "$MAGISKTMP/modules"
const val TMPDIR = "/dev/tmp"
const val MAGISK_LOG = "/cache/magisk.log"

View File

@ -11,14 +11,13 @@ import com.topjohnwu.magisk.ktx.getProperty
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils.fastCmd
import com.topjohnwu.superuser.internal.UiThreadHandler
import java.io.File
import java.io.IOException
val isRunningAsStub get() = Info.stub != null
object Info {
var stub: DynAPK.Data? = null
var stubArch = "lib/${Const.CPU_ABI}"
val EMPTY_REMOTE = UpdateInfo()
var remote = EMPTY_REMOTE
@ -49,20 +48,6 @@ object Info {
}
}
val isNewReboot by lazy {
try {
val id = File("/proc/sys/kernel/random/boot_id").readText()
if (id != Config.bootId) {
Config.bootId = id
true
} else {
false
}
} catch (e: IOException) {
false
}
}
private fun loadState() = Env(
fastCmd("magisk -v").split(":".toRegex())[0],
runCatching { fastCmd("magisk -V").toInt() }.getOrDefault(-1),

View File

@ -94,7 +94,7 @@ abstract class MagiskInstallImpl protected constructor(
if (isRunningAsStub) {
val zf = ZipFile(DynAPK.current(context))
zf.entries().asSequence().filter {
!it.isDirectory && it.name.startsWith("lib/${Const.CPU_ABI_32}/")
!it.isDirectory && it.name.startsWith(Info.stubArch)
}.forEach {
val n = it.name.substring(it.name.lastIndexOf('/') + 1)
val name = n.substring(3, n.length - 3)
@ -102,7 +102,7 @@ abstract class MagiskInstallImpl protected constructor(
zf.getInputStream(it).writeTo(dest)
}
} else {
val libs = Const.NATIVE_LIB_DIR.listFiles { _, name ->
val libs = File(context.applicationInfo.nativeLibraryDir).listFiles { _, name ->
name.startsWith("lib") && name.endsWith(".so")
} ?: emptyArray()
for (lib in libs) {
@ -250,7 +250,7 @@ abstract class MagiskInstallImpl protected constructor(
src.reset()
val alpha = "abcdefghijklmnopqrstuvwxyz"
val alphaNum = "$alpha${alpha.toUpperCase(Locale.ROOT)}0123456789"
val alphaNum = "$alpha${alpha.uppercase(Locale.ROOT)}0123456789"
val random = SecureRandom()
val filename = StringBuilder("magisk_patched-${BuildConfig.VERSION_CODE}_").run {
for (i in 1..5) {

View File

@ -1,7 +1,6 @@
package com.topjohnwu.magisk.core.utils
import android.content.Context
import android.os.Build
import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.*
@ -34,13 +33,17 @@ class BusyBoxInit : BaseShellInit() {
if (!shell.isRoot)
return true
val jar = JarFile(DynAPK.current(context))
val bb = jar.getJarEntry("lib/${Const.CPU_ABI_32}/libbusybox.so")
var bb = jar.getJarEntry("${Info.stubArch}/libbusybox.so")
if (bb == null) {
Info.stubArch = "lib/${Const.CPU_ABI_32}"
bb = jar.getJarEntry("${Info.stubArch}/libbusybox.so")
}
localBB = context.deviceProtectedContext.cachedFile("busybox")
localBB.delete()
jar.getInputStream(bb).writeTo(localBB)
localBB.setExecutable(true)
} else {
localBB = File(Const.NATIVE_LIB_DIR, "libbusybox.so")
localBB = File(context.applicationInfo.nativeLibraryDir, "libbusybox.so")
}
if (shell.isRoot) {

View File

@ -48,9 +48,9 @@ subprojects {
ndkPath = "${System.getenv("ANDROID_SDK_ROOT")}/ndk/magisk"
defaultConfig {
if (minSdkVersion == null)
minSdkVersion(21)
targetSdkVersion(30)
if (minSdk == null)
minSdk = 21
targetSdk = 30
}
compileOptions {

View File

@ -1,17 +1,17 @@
#!/usr/bin/env python3
import sys
import os
import subprocess
import argparse
import multiprocessing
import zipfile
import errno
import shutil
import lzma
import platform
import urllib.request
import multiprocessing
import os
import os.path as op
import platform
import shutil
import stat
import subprocess
import sys
import urllib.request
import zipfile
from distutils.dir_util import copy_tree
@ -40,6 +40,7 @@ is_ci = 'CI' in os.environ and os.environ['CI'] == 'true'
if not is_ci and is_windows:
import colorama
colorama.init()
# Environment checks
@ -56,10 +57,9 @@ except FileNotFoundError:
error('Please install JDK and make sure \'javac\' is available in PATH')
cpu_count = multiprocessing.cpu_count()
archs = ['armeabi-v7a', 'x86']
arch64 = ['arm64-v8a', 'x86_64']
support_targets = ['magisk', 'magiskinit', 'magiskboot', 'magiskpolicy', 'resetprop', 'busybox', 'test']
archs = ['armeabi-v7a', 'x86', 'arm64-v8a', 'x86_64']
default_targets = ['magisk', 'magiskinit', 'magiskboot', 'busybox']
support_targets = default_targets + ['magiskpolicy', 'resetprop', 'test']
ndk_root = op.join(os.environ['ANDROID_SDK_ROOT'], 'ndk')
ndk_path = op.join(ndk_root, 'magisk')
@ -178,7 +178,7 @@ def load_config(args):
def collect_binary():
for arch in archs + arch64:
for arch in archs:
mkdir_p(op.join('native', 'out', arch))
for bin in support_targets:
source = op.join('native', 'libs', arch, bin)
@ -196,7 +196,7 @@ def clean_elf():
'-o', elf_cleaner])
args = [elf_cleaner]
args.extend(op.join('native', 'out', arch, 'magisk')
for arch in archs + arch64)
for arch in archs)
execv(args)
@ -211,6 +211,7 @@ def find_build_tools():
build_tools = op.join(build_tools_root, ls[-1])
return build_tools
# Unused but keep this code
def sign_zip(unsigned):
if 'keyStore' not in config:
@ -220,18 +221,18 @@ def sign_zip(unsigned):
apksigner = op.join(find_build_tools(), 'apksigner' + ('.bat' if is_windows else ''))
exec_args = [apksigner, 'sign',
'--ks', config['keyStore'],
'--ks-pass', f'pass:{config["keyStorePass"]}',
'--ks-key-alias', config['keyAlias'],
'--key-pass', f'pass:{config["keyPass"]}',
'--v1-signer-name', 'CERT',
'--v4-signing-enabled', 'false']
'--ks', config['keyStore'],
'--ks-pass', f'pass:{config["keyStorePass"]}',
'--ks-key-alias', config['keyAlias'],
'--key-pass', f'pass:{config["keyPass"]}',
'--v1-signer-name', 'CERT',
'--v4-signing-enabled', 'false']
if unsigned.endswith('.zip'):
msg = '* Signing zip'
exec_args.extend(['--min-sdk-version', '17',
'--v2-signing-enabled', 'false',
'--v3-signing-enabled', 'false'])
'--v2-signing-enabled', 'false',
'--v3-signing-enabled', 'false'])
exec_args.append(unsigned)
@ -264,6 +265,7 @@ def dump_bin_headers():
stub = op.join(config['outdir'], 'stub-release.apk')
if not op.exists(stub):
error('Build stub APK before building "magiskinit"')
mkdir_p(op.join('native', 'out'))
with open(op.join('native', 'out', 'binaries.h'), 'w') as out:
with open(stub, 'rb') as src:
binary_dump(src, out, 'manager_xz')
@ -304,18 +306,13 @@ def build_binary(args):
if not args.release:
base_flags += ' MAGISK_DEBUG=1'
flag = ''
if 'magisk' in args.target:
run_ndk_build('B_MAGISK=1 B_64BIT=1')
clean_elf()
flag += ' B_MAGISK=1'
if 'test' in args.target:
run_ndk_build('B_TEST=1 B_64BIT=1')
if 'busybox' in args.target:
run_ndk_build('B_BB=1')
# 32-bit only targets can be built in one command
flag = ''
flag += ' B_TEST=1'
if 'magiskinit' in args.target:
dump_bin_headers()
@ -333,6 +330,12 @@ def build_binary(args):
if flag:
run_ndk_build(flag)
if 'magisk' in args.target:
clean_elf()
if 'busybox' in args.target:
run_ndk_build('B_BB=1')
def build_apk(args, module):
build_type = 'Release' if args.release or module == 'stub' else 'Debug'
@ -343,13 +346,20 @@ def build_apk(args, module):
error(f'Build {module} failed!')
build_type = build_type.lower()
apk = f'{module}-{build_type}.apk'
source = op.join(module, 'build', 'outputs', 'apk', build_type, apk)
target = op.join(config['outdir'], apk)
mv(source, target)
header('Output: ' + target)
return target
if module == 'app':
for arch in archs + ['universal']:
apk = f'{module}-{arch}-{build_type}.apk'
source = op.join(module, 'build', 'outputs', 'apk', build_type, apk)
target = op.join(config['outdir'], apk)
mv(source, target)
header('Output: ' + target)
else:
apk = f'{module}-{build_type}.apk'
source = op.join(module, 'build', 'outputs', 'apk', build_type, apk)
target = op.join(config['outdir'], apk)
mv(source, target)
header('Output: ' + target)
def build_app(args):

View File

@ -1,4 +1,4 @@
APP_ABI := armeabi-v7a x86
APP_ABI := armeabi-v7a x86 arm64-v8a x86_64
APP_CFLAGS := -Wall -Oz -fomit-frame-pointer -flto \
-D__MVSTR=${MAGISK_VERSION} -D__MCODE=${MAGISK_VER_CODE}
APP_LDFLAGS := -flto
@ -10,11 +10,6 @@ ifdef MAGISK_DEBUG
APP_CFLAGS += -D__MDBG
endif
# Build 64 bit binaries
ifdef B_64BIT
APP_ABI += arm64-v8a x86_64
endif
# Busybox should use stock libc.a
ifdef B_BB
APP_PLATFORM := android-22

View File

@ -52,12 +52,14 @@ api_level_arch_detect
ui_print "- Device platform: $ARCH"
BINDIR=$INSTALLER/lib/$ARCH32
[ ! -d "$BINDIR" ] && BINDIR=$INSTALLER/lib/armeabi-v7a
BINDIR=$INSTALLER/lib/$ABILONG
[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/$ARCH32
[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/armeabi-v7a
cd $BINDIR
for file in lib*.so; do mv "$file" "${file:3:${#file}-6}"; done
cd /
chmod -R 755 $CHROMEDIR $BINDIR
cp -af $CHROMEDIR/. $BINDIR/chromeos
# Check if system root is installed and remove
$BOOTMODE || remove_system_su

View File

@ -57,8 +57,9 @@ api_level_arch_detect
ui_print "- Device platform: $ARCH"
BINDIR=$INSTALLER/lib/$ARCH32
[ ! -d "$BINDIR" ] && BINDIR=$INSTALLER/lib/armeabi-v7a
BINDIR=$INSTALLER/lib/$ABILONG
[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/$ARCH32
[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/armeabi-v7a
cd $BINDIR
for file in lib*.so; do mv "$file" "${file:3:${#file}-6}"; done
cd /

View File

@ -5,10 +5,15 @@ rm -rf $TMPDIR
mkdir -p $TMPDIR 2>/dev/null
export BBBIN=$TMPDIR/busybox
unzip -o "$3" lib/x86/libbusybox.so lib/armeabi-v7a/libbusybox.so -d $TMPDIR >&2
unzip -o "$3" "lib/*/libbusybox.so" -d $TMPDIR >&2
chmod -R 755 $TMPDIR/lib
mv -f $TMPDIR/lib/x86/libbusybox.so $BBBIN
$BBBIN >/dev/null 2>&1 || mv -f $TMPDIR/lib/armeabi-v7a/libbusybox.so $BBBIN
for arch in "x86_64" "x86" "arm64-v8a" "armeabi-v7a"; do
libpath="$TMPDIR/lib/$arch/libbusybox.so"
if [ -x $libpath ] && $libpath >/dev/null 2>&1; then
mv -f $libpath $BBBIN
break
fi
done
$BBBIN rm -rf $TMPDIR/lib
export INSTALLER=$TMPDIR/install