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 org.apache.tools.ant.filters.FixCrLfFilter
import java.io.PrintStream import java.io.PrintStream
@ -41,6 +42,13 @@ android {
} }
} }
splits {
abi {
isEnable = true
isUniversalApk = true
}
}
buildFeatures { buildFeatures {
dataBinding = true dataBinding = true
} }
@ -88,27 +96,35 @@ val syncLibs by tasks.registering(Sync::class) {
rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" } 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 { onlyIf {
if (inputs.sourceFiles.files.size != 10) if (inputs.sourceFiles.files.size != 16)
throw StopExecutionException("Please build binaries first! (./build.py binary)") throw StopExecutionException("Please build binaries first! (./build.py binary)")
true 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) { val syncAssets by tasks.registering(Sync::class) {
dependsOn(createStubLibs) dependsOn(syncLibs)
inputs.property("version", Config.version) inputs.property("version", Config.version)
inputs.property("versionCode", Config.versionCode) inputs.property("versionCode", Config.versionCode)
into("src/main/assets") into("src/main/assets")
@ -123,9 +139,11 @@ val syncAssets by tasks.registering(Sync::class) {
} }
filesMatching("**/util_functions.sh") { filesMatching("**/util_functions.sh") {
filter { filter {
it.replace("#MAGISK_VERSION_STUB", it.replace(
"#MAGISK_VERSION_STUB",
"MAGISK_VER='${Config.version}'\n" + "MAGISK_VER='${Config.version}'\n" +
"MAGISK_VER_CODE=${Config.versionCode}") "MAGISK_VER_CODE=${Config.versionCode}"
)
} }
filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf")) filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))
} }
@ -178,6 +196,13 @@ android.applicationVariants.all {
} }
} }
registerJavaGeneratingTask(genSrcTask.get(), outSrcDir) registerJavaGeneratingTask(genSrcTask.get(), outSrcDir)
outputs.all {
val output = this as ApkVariantOutputImpl
output.filters.forEach {
output.versionNameOverride += "-${it.identifier}"
}
}
} }
dependencies { dependencies {

View File

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

View File

@ -17,7 +17,6 @@ import com.topjohnwu.magisk.di.ServiceLocator
import com.topjohnwu.magisk.ktx.unwrap import com.topjohnwu.magisk.ktx.unwrap
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import timber.log.Timber import timber.log.Timber
import java.io.File
import kotlin.system.exitProcess import kotlin.system.exitProcess
open class App() : Application() { open class App() : Application() {
@ -56,12 +55,6 @@ open class App() : Application() {
val wrapped = impl.wrap() val wrapped = impl.wrap()
super.attachBaseContext(wrapped) 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 ServiceLocator.context = wrapped
AssetHack.init(impl) AssetHack.init(impl)
app.registerActivityLifecycleCallbacks(ForegroundTracker) app.registerActivityLifecycleCallbacks(ForegroundTracker)

View File

@ -3,7 +3,6 @@ package com.topjohnwu.magisk.core
import android.os.Build import android.os.Build
import android.os.Process import android.os.Process
import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.BuildConfig
import java.io.File
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
object Const { object Const {
@ -13,7 +12,6 @@ object Const {
// Paths // Paths
lateinit var MAGISKTMP: String lateinit var MAGISKTMP: String
lateinit var NATIVE_LIB_DIR: File
val MAGISK_PATH get() = "$MAGISKTMP/modules" val MAGISK_PATH get() = "$MAGISKTMP/modules"
const val TMPDIR = "/dev/tmp" const val TMPDIR = "/dev/tmp"
const val MAGISK_LOG = "/cache/magisk.log" 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.Shell
import com.topjohnwu.superuser.ShellUtils.fastCmd import com.topjohnwu.superuser.ShellUtils.fastCmd
import com.topjohnwu.superuser.internal.UiThreadHandler import com.topjohnwu.superuser.internal.UiThreadHandler
import java.io.File
import java.io.IOException
val isRunningAsStub get() = Info.stub != null val isRunningAsStub get() = Info.stub != null
object Info { object Info {
var stub: DynAPK.Data? = null var stub: DynAPK.Data? = null
var stubArch = "lib/${Const.CPU_ABI}"
val EMPTY_REMOTE = UpdateInfo() val EMPTY_REMOTE = UpdateInfo()
var remote = EMPTY_REMOTE 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( private fun loadState() = Env(
fastCmd("magisk -v").split(":".toRegex())[0], fastCmd("magisk -v").split(":".toRegex())[0],
runCatching { fastCmd("magisk -V").toInt() }.getOrDefault(-1), runCatching { fastCmd("magisk -V").toInt() }.getOrDefault(-1),

View File

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

View File

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

View File

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

View File

@ -1,17 +1,17 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys
import os
import subprocess
import argparse import argparse
import multiprocessing
import zipfile
import errno import errno
import shutil
import lzma import lzma
import platform import multiprocessing
import urllib.request import os
import os.path as op import os.path as op
import platform
import shutil
import stat import stat
import subprocess
import sys
import urllib.request
import zipfile
from distutils.dir_util import copy_tree 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: if not is_ci and is_windows:
import colorama import colorama
colorama.init() colorama.init()
# Environment checks # Environment checks
@ -56,10 +57,9 @@ except FileNotFoundError:
error('Please install JDK and make sure \'javac\' is available in PATH') error('Please install JDK and make sure \'javac\' is available in PATH')
cpu_count = multiprocessing.cpu_count() cpu_count = multiprocessing.cpu_count()
archs = ['armeabi-v7a', 'x86'] archs = ['armeabi-v7a', 'x86', 'arm64-v8a', 'x86_64']
arch64 = ['arm64-v8a', 'x86_64']
support_targets = ['magisk', 'magiskinit', 'magiskboot', 'magiskpolicy', 'resetprop', 'busybox', 'test']
default_targets = ['magisk', 'magiskinit', 'magiskboot', 'busybox'] default_targets = ['magisk', 'magiskinit', 'magiskboot', 'busybox']
support_targets = default_targets + ['magiskpolicy', 'resetprop', 'test']
ndk_root = op.join(os.environ['ANDROID_SDK_ROOT'], 'ndk') ndk_root = op.join(os.environ['ANDROID_SDK_ROOT'], 'ndk')
ndk_path = op.join(ndk_root, 'magisk') ndk_path = op.join(ndk_root, 'magisk')
@ -178,7 +178,7 @@ def load_config(args):
def collect_binary(): def collect_binary():
for arch in archs + arch64: for arch in archs:
mkdir_p(op.join('native', 'out', arch)) mkdir_p(op.join('native', 'out', arch))
for bin in support_targets: for bin in support_targets:
source = op.join('native', 'libs', arch, bin) source = op.join('native', 'libs', arch, bin)
@ -196,7 +196,7 @@ def clean_elf():
'-o', elf_cleaner]) '-o', elf_cleaner])
args = [elf_cleaner] args = [elf_cleaner]
args.extend(op.join('native', 'out', arch, 'magisk') args.extend(op.join('native', 'out', arch, 'magisk')
for arch in archs + arch64) for arch in archs)
execv(args) execv(args)
@ -211,6 +211,7 @@ def find_build_tools():
build_tools = op.join(build_tools_root, ls[-1]) build_tools = op.join(build_tools_root, ls[-1])
return build_tools return build_tools
# Unused but keep this code # Unused but keep this code
def sign_zip(unsigned): def sign_zip(unsigned):
if 'keyStore' not in config: if 'keyStore' not in config:
@ -264,6 +265,7 @@ def dump_bin_headers():
stub = op.join(config['outdir'], 'stub-release.apk') stub = op.join(config['outdir'], 'stub-release.apk')
if not op.exists(stub): if not op.exists(stub):
error('Build stub APK before building "magiskinit"') 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(op.join('native', 'out', 'binaries.h'), 'w') as out:
with open(stub, 'rb') as src: with open(stub, 'rb') as src:
binary_dump(src, out, 'manager_xz') binary_dump(src, out, 'manager_xz')
@ -304,18 +306,13 @@ def build_binary(args):
if not args.release: if not args.release:
base_flags += ' MAGISK_DEBUG=1' base_flags += ' MAGISK_DEBUG=1'
flag = ''
if 'magisk' in args.target: if 'magisk' in args.target:
run_ndk_build('B_MAGISK=1 B_64BIT=1') flag += ' B_MAGISK=1'
clean_elf()
if 'test' in args.target: if 'test' in args.target:
run_ndk_build('B_TEST=1 B_64BIT=1') flag += ' B_TEST=1'
if 'busybox' in args.target:
run_ndk_build('B_BB=1')
# 32-bit only targets can be built in one command
flag = ''
if 'magiskinit' in args.target: if 'magiskinit' in args.target:
dump_bin_headers() dump_bin_headers()
@ -333,6 +330,12 @@ def build_binary(args):
if flag: if flag:
run_ndk_build(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): def build_apk(args, module):
build_type = 'Release' if args.release or module == 'stub' else 'Debug' 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!') error(f'Build {module} failed!')
build_type = build_type.lower() build_type = build_type.lower()
apk = f'{module}-{build_type}.apk'
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) source = op.join(module, 'build', 'outputs', 'apk', build_type, apk)
target = op.join(config['outdir'], apk) target = op.join(config['outdir'], apk)
mv(source, target) mv(source, target)
header('Output: ' + target) header('Output: ' + target)
return target
def build_app(args): 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 \ APP_CFLAGS := -Wall -Oz -fomit-frame-pointer -flto \
-D__MVSTR=${MAGISK_VERSION} -D__MCODE=${MAGISK_VER_CODE} -D__MVSTR=${MAGISK_VERSION} -D__MCODE=${MAGISK_VER_CODE}
APP_LDFLAGS := -flto APP_LDFLAGS := -flto
@ -10,11 +10,6 @@ ifdef MAGISK_DEBUG
APP_CFLAGS += -D__MDBG APP_CFLAGS += -D__MDBG
endif endif
# Build 64 bit binaries
ifdef B_64BIT
APP_ABI += arm64-v8a x86_64
endif
# Busybox should use stock libc.a # Busybox should use stock libc.a
ifdef B_BB ifdef B_BB
APP_PLATFORM := android-22 APP_PLATFORM := android-22

View File

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

View File

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

View File

@ -5,10 +5,15 @@ rm -rf $TMPDIR
mkdir -p $TMPDIR 2>/dev/null mkdir -p $TMPDIR 2>/dev/null
export BBBIN=$TMPDIR/busybox 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 chmod -R 755 $TMPDIR/lib
mv -f $TMPDIR/lib/x86/libbusybox.so $BBBIN for arch in "x86_64" "x86" "arm64-v8a" "armeabi-v7a"; do
$BBBIN >/dev/null 2>&1 || mv -f $TMPDIR/lib/armeabi-v7a/libbusybox.so $BBBIN 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 $BBBIN rm -rf $TMPDIR/lib
export INSTALLER=$TMPDIR/install export INSTALLER=$TMPDIR/install