diff --git a/.gitattributes b/.gitattributes index 189857a66..971dee287 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11,7 +11,7 @@ *.bat text eol=crlf # Denote all files that are truly binary and should not be modified. -chromeos/** binary +tools/** binary *.jar binary *.exe binary *.apk binary diff --git a/.gitmodules b/.gitmodules index 75a1291cb..a15981a89 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "mincrypt"] path = native/jni/external/mincrypt url = https://github.com/topjohnwu/mincrypt.git +[submodule "termux-elf-cleaner"] + path = tools/termux-elf-cleaner + url = https://github.com/termux/termux-elf-cleaner.git diff --git a/build.py b/build.py index c0db8ed52..513fbe29b 100755 --- a/build.py +++ b/build.py @@ -51,7 +51,7 @@ else: os.environ['ANDROID_HOME'], 'ndk-bundle', 'ndk-build') cpu_count = multiprocessing.cpu_count() -gradlew = os.path.join('.', 'gradlew.bat' if os.name == 'nt' else 'gradlew') +gradlew = os.path.join('.', 'gradlew' + ('.bat' if os.name == 'nt' else '')) archs = ['armeabi-v7a', 'x86'] arch64 = ['arm64-v8a', 'x86_64'] keystore = 'release-key.jks' @@ -96,6 +96,18 @@ def mkdir_p(path, mode=0o777): os.makedirs(path, mode, exist_ok=True) +def execv(cmd, redirect=None): + return subprocess.run(cmd, stdout=redirect if redirect != None else STDOUT) + + +def system(cmd, redirect=None): + return subprocess.run(cmd, shell=True, stdout=redirect if redirect != None else STDOUT) + + +def xz(data): + return lzma.compress(data, preset=9, check=lzma.CHECK_NONE) + + def zip_with_msg(zip_file, source, target): if not os.path.exists(source): error(f'{source} does not exist! Try build \'binary\' and \'apk\' before zipping!') @@ -112,19 +124,23 @@ def collect_binary(): mv(source, target) -def execv(cmd, redirect=None): - return subprocess.run(cmd, stdout=redirect if redirect != None else STDOUT) - - -def system(cmd, redirect=None): - return subprocess.run(cmd, shell=True, stdout=redirect if redirect != None else STDOUT) - - -def xz(data): - return lzma.compress(data, preset=9, check=lzma.CHECK_NONE) +def clean_elf(): + if os.name == 'nt': + elf_cleaner = os.path.join('tools', 'elf-cleaner.exe') + else: + elf_cleaner = os.path.join('native', 'out', 'elf-cleaner') + if not os.path.exists(elf_cleaner): + execv(['g++', 'tools/termux-elf-cleaner/termux-elf-cleaner.cpp', '-o', elf_cleaner]) + args = [elf_cleaner] + args.extend(os.path.join('native', 'out', arch, 'magisk') for arch in archs + arch64) + execv(args) def sign_zip(unsigned, output, release): + if not release: + mv(unsigned, output) + return + signer_name = 'zipsigner-3.0.jar' zipsigner = os.path.join('signing', 'build', 'libs', signer_name) @@ -136,18 +152,15 @@ def sign_zip(unsigned, output, release): header('* Signing Zip') - if release: - proc = execv(['java', '-jar', zipsigner, keystore, config['keyStorePass'], - config['keyAlias'], config['keyPass'], unsigned, output]) - else: - proc = execv(['java', '-jar', zipsigner, unsigned, output]) + proc = execv(['java', '-jar', zipsigner, keystore, config['keyStorePass'], + config['keyAlias'], config['keyPass'], unsigned, output]) if proc.returncode != 0: error('Signing zip failed!') def binary_dump(src, out, var_name): - out.write(f'const static unsigned char {var_name}[] = {{') + out.write(f'constexpr unsigned char {var_name}[] = {{') for i, c in enumerate(xz(src.read())): if i % 16 == 0: out.write('\n') @@ -169,12 +182,12 @@ def gen_update_binary(): with open(file, 'rb') as f: script = f.read() # Align x86 busybox to bs - blkCnt = (len(x86_bb) - 1) // bs + 1 - script = script.replace(b'__X86_CNT__', b'%d' % blkCnt) + blk_cnt = (len(x86_bb) - 1) // bs + 1 + script = script.replace(b'__X86_CNT__', b'%d' % blk_cnt) update_bin[:len(script)] = script update_bin.extend(x86_bb) # Padding for alignment - update_bin.extend(b'\0' * (blkCnt * bs - len(x86_bb))) + update_bin.extend(b'\0' * (blk_cnt * bs - len(x86_bb))) update_bin.extend(arm_bb) return update_bin @@ -206,6 +219,7 @@ def build_binary(args): if 'magisk' in args.target: run_ndk_build('B_MAGISK=1 B_64BIT=1') + clean_elf() # Dump the binary to header for arch in archs: bin_file = os.path.join('native', 'out', arch, 'magisk') @@ -298,12 +312,12 @@ def zip_main(args): unsigned = tempfile.mkstemp()[1] with zipfile.ZipFile(unsigned, 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=False) as zipf: - # META-INF # update-binary target = os.path.join('META-INF', 'com', 'google', 'android', 'update-binary') vprint('zip: ' + target) zipf.writestr(target, gen_update_binary()) + # updater-script source = os.path.join('scripts', 'flash_script.sh') target = os.path.join('META-INF', 'com', 'google', @@ -323,7 +337,6 @@ def zip_main(args): target = os.path.join('common', 'magisk.apk') zip_with_msg(zipf, source, target) - # Scripts # boot_patch.sh source = os.path.join('scripts', 'boot_patch.sh') target = os.path.join('common', 'boot_patch.sh') @@ -343,10 +356,11 @@ def zip_main(args): target = os.path.join('common', 'addon.d.sh') zip_with_msg(zipf, source, target) - # Prebuilts - for chromeos in ['futility', 'kernel_data_key.vbprivk', 'kernel.keyblock']: - source = os.path.join('chromeos', chromeos) - zip_with_msg(zipf, source, source) + # chromeos + for tool in ['futility', 'kernel_data_key.vbprivk', 'kernel.keyblock']: + source = os.path.join('tools', tool) + target = os.path.join('chromeos', tool) + zip_with_msg(zipf, source, target) # End of zipping @@ -362,7 +376,6 @@ def zip_uninstaller(args): unsigned = tempfile.mkstemp()[1] with zipfile.ZipFile(unsigned, 'w', compression=zipfile.ZIP_DEFLATED, allowZip64=False) as zipf: - # META-INF # update-binary target = os.path.join('META-INF', 'com', 'google', 'android', 'update-binary') @@ -380,7 +393,6 @@ def zip_uninstaller(args): target = os.path.join(zip_dir, 'magiskboot') zip_with_msg(zipf, source, target) - # Scripts # util_functions.sh source = os.path.join('scripts', 'util_functions.sh') with open(source, 'r') as script: @@ -388,14 +400,16 @@ def zip_uninstaller(args): vprint(f'zip: {source} -> {target}') zipf.writestr(target, script.read()) - # Prebuilts - for chromeos in ['futility', 'kernel_data_key.vbprivk', 'kernel.keyblock']: - source = os.path.join('chromeos', chromeos) - zip_with_msg(zipf, source, source) + # chromeos + for tool in ['futility', 'kernel_data_key.vbprivk', 'kernel.keyblock']: + source = os.path.join('tools', tool) + target = os.path.join('chromeos', tool) + zip_with_msg(zipf, source, target) # End of zipping - output = os.path.join(config['outdir'], f'Magisk-uninstaller-{datetime.datetime.now().strftime("%Y%m%d")}.zip' + datestr = datetime.datetime.now().strftime("%Y%m%d") + output = os.path.join(config['outdir'], f'Magisk-uninstaller-{datestr}.zip' if config['prettyName'] else 'magisk-uninstaller.zip') sign_zip(unsigned, output, args.release) header('Output: ' + output) @@ -503,4 +517,6 @@ mkdir_p(config['outdir']) if args.release and not os.path.exists(keystore): error(f'Please generate a java keystore and place it in "{keystore}"') STDOUT = None if args.verbose else subprocess.DEVNULL + +# Call corresponding functions args.func(args) diff --git a/tools/elf-cleaner.exe b/tools/elf-cleaner.exe new file mode 100755 index 000000000..a3c084710 Binary files /dev/null and b/tools/elf-cleaner.exe differ diff --git a/chromeos/futility b/tools/futility similarity index 100% rename from chromeos/futility rename to tools/futility diff --git a/chromeos/kernel.keyblock b/tools/kernel.keyblock similarity index 100% rename from chromeos/kernel.keyblock rename to tools/kernel.keyblock diff --git a/chromeos/kernel_data_key.vbprivk b/tools/kernel_data_key.vbprivk similarity index 100% rename from chromeos/kernel_data_key.vbprivk rename to tools/kernel_data_key.vbprivk diff --git a/tools/termux-elf-cleaner b/tools/termux-elf-cleaner new file mode 160000 index 000000000..334efd192 --- /dev/null +++ b/tools/termux-elf-cleaner @@ -0,0 +1 @@ +Subproject commit 334efd1923c563e19d00e655dfbfb2f9f7031bb1