Compare commits

...

32 Commits
v25.1 ... v25.2

Author SHA1 Message Date
topjohnwu
6066b5cf86 Release Magisk v25.2 2022-07-20 20:13:26 -07:00
topjohnwu
5cdf95a4d0 Update v25.2 docs 2022-07-20 20:09:02 -07:00
topjohnwu
910a36fdc1 Make sepolicy.rules relative if possible 2022-07-20 19:28:38 -07:00
topjohnwu
8331206acb Clean only java projects when clean java 2022-07-20 11:20:03 -07:00
canyie
8423dc8d63 Later check persistent_properties
`daemon_entry` calls `getprop` which initializes sysprop impl and checks whether we need to load persistent property file. On FDE devices, magiskd starts before /data is actually decrypted, and the check always fails. Thus `persist_getprop("persist.sys.safemode")` will always fail.
2022-07-20 09:58:20 -07:00
Yann
6077c989a7 app: fix typo 2022-07-20 03:34:48 -07:00
topjohnwu
c97d1044fa Release new canary build 2022-07-19 17:44:19 -07:00
Hen_Ry
f42c089b26 Fix 2022-07-18 13:34:14 -07:00
Andrew Gunnerson
1f8c063dc6 Fix booting into recovery with Android 13 GKI kernels
With Android 13 GKI kernels, the boot partition has no ramdisk, so
Magisk constructs one from scratch. In this scenario, there's no backup
init binary at /.backup/init. For normal boot, magiskinit will symlink
/init -> /system/bin/init if needed. This commit implements the same
for booting into recovery. Before, magiskinit would just exec itself
over and over again because it couldn't restore the backup init.

Signed-off-by: Andrew Gunnerson <chillermillerlong@hotmail.com>
2022-07-18 13:33:50 -07:00
Hen_Ry
4874520d65 Update german translation 2022-07-14 12:32:55 -07:00
Nguyen Hoang The Vi
5e53639969 Add Bengali translation 2022-07-14 12:32:33 -07:00
Grammatopoulos Apostolos
83ab0ca6cd Greek translation updated 2022-07-14 12:31:47 -07:00
topjohnwu
70fd03d5fc Rearchitect logging 2022-07-06 01:16:08 -07:00
topjohnwu
2e52875b50 Move all logging into Rust 2022-07-05 21:13:09 -07:00
topjohnwu
fd9b990ad7 Update to ONDK r24.2 2022-07-05 01:34:48 -07:00
LONE DEVIL
69978a9442 Update russian translation 2022-07-01 15:16:44 -07:00
残页
d155da52ce More friendly and clear error message 2022-07-01 15:15:54 -07:00
Weslley Almeida
9c5b131913 Update Brazilian translation 2022-07-01 15:15:07 -07:00
Syuugo
9d740cec1a Partially fixed Japanese translation 2022-07-01 15:14:18 -07:00
vvb2060
c2978eb9c3 More log for get_manager 2022-07-01 15:13:38 -07:00
vvb2060
38abad1e44 Fix app state 2022-07-01 15:12:50 -07:00
topjohnwu
b4863eb51b Setup logging infra in the Rust side 2022-07-01 04:54:00 -07:00
LoveSy
3817167ba1 Correct ro.crypto.state check
Fix #6042

Co-authored-by: vvb2060 <vvb2060@gmail.com>
2022-06-30 19:32:43 -07:00
topjohnwu
d1a35dd2ba Fix cargo builds on Windows 2022-06-30 18:12:07 -07:00
topjohnwu
26116ac414 Setup preliminary rust infrastructure 2022-06-30 14:50:21 -07:00
topjohnwu
0b26882fce Build dynamic stub resource APK at runtime
Close #6013

Co-authored-by: vvb2060 <vvb2060@gmail.com>
2022-06-22 05:19:27 -07:00
Nicolás
a2495fb5fb Update spanish translations 2022-06-22 04:08:52 -07:00
vvb2060
0beb3bf16a Make CI builds reproducible 2022-06-22 04:08:18 -07:00
vvb2060
b68658e974 Rebuild manifest 2022-06-22 04:06:22 -07:00
LoveSy
3ae7344747 Create /dev on stub cpio 2022-06-22 04:05:50 -07:00
topjohnwu
4eb71830b3 Release new canary build 2022-06-19 03:24:36 -07:00
topjohnwu
9183a0a6ea Update README 2022-06-19 03:06:14 -07:00
64 changed files with 1233 additions and 273 deletions

3
.gitmodules vendored
View File

@@ -40,3 +40,6 @@
[submodule "zopfli"]
path = native/jni/external/zopfli
url = https://github.com/google/zopfli.git
[submodule "cxx-rs"]
path = native/jni/external/cxx-rs
url = https://github.com/topjohnwu/cxx.git

View File

@@ -18,8 +18,8 @@ Some highlight features:
[Github](https://github.com/topjohnwu/Magisk/) is the only source where you can get official Magisk information and downloads.
[![](https://img.shields.io/badge/Magisk-v24.3-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v24.3)
[![](https://img.shields.io/badge/Magisk%20Beta-v25.0-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v25.0)
[![](https://img.shields.io/badge/Magisk-v25.1-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v25.1)
[![](https://img.shields.io/badge/Magisk%20Beta-v25.1-blue)](https://github.com/topjohnwu/Magisk/releases/tag/v25.1)
[![](https://img.shields.io/badge/Magisk-Canary-red)](https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-release.apk)
[![](https://img.shields.io/badge/Magisk-Debug-red)](https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-debug.apk)
@@ -51,7 +51,7 @@ For Magisk app crashes, record and upload the logcat when the crash occurs.
- Run `./build.py ndk` to let the script download and install NDK for you
- To start building, run `build.py` to see your options. \
For each action, use `-h` to access help (e.g. `./build.py all -h`)
- To start development, open the project with Android Studio. The IDE can be used for both app (Kotlin/Java) and native (C++/C) sources.
- To start development, open the project with Android Studio. The IDE can be used for both app (Kotlin/Java) and native sources.
- Optionally, set custom configs with `config.prop`. A sample `config.prop.sample` is provided.
## Signing and Distribution

View File

@@ -94,6 +94,7 @@ class HomeViewModel(
("${magisk.version} (${magisk.versionCode}) (${stub.versionCode})" +
if (isDebug) " (D)" else "").asText()
} ?: run {
appState = State.INVALID
managerRemoteVersion = R.string.not_available.asText()
}
ensureEnv()
@@ -112,7 +113,7 @@ class HomeViewModel(
fun onDeletePressed() = UninstallDialog().publish()
fun onManagerPressed() = when (magiskState) {
fun onManagerPressed() = when (appState) {
State.LOADING -> SnackbarEvent(R.string.loading).publish()
State.INVALID -> SnackbarEvent(R.string.no_connection).publish()
else -> withExternalRW {

View File

@@ -54,8 +54,8 @@ public class ConcealableBottomNavigationView extends BottomNavigationView {
toHidden.setDuration(175);
toHidden.setInterpolator(new FastOutLinearInInterpolator());
Animator toUnhidden = ObjectAnimator.ofFloat(this, "translationY", 0);
toHidden.setDuration(225);
toHidden.setInterpolator(new FastOutLinearInInterpolator());
toUnhidden.setDuration(225);
toUnhidden.setInterpolator(new FastOutLinearInInterpolator());
StateListAnimator animator = new StateListAnimator();

View File

@@ -0,0 +1,240 @@
<resources>
<!--Sections-->
<string name="modules">মডিউল</string>
<string name="superuser">সুপার ইউজার</string>
<string name="logs">লগ</string>
<string name="settings">সেটিংস</string>
<string name="install">ইনস্টল করুন</string>
<string name="section_home">বাড়ি</string>
<string name="section_theme">থিম</string>
<string name="denylist">তালিকা অস্বীকার করুন</string>
<!--Home-->
<string name="no_connection">কোন সংযোগ উপলব্ধ নেই</string>
<string name="app_changelog">চেঞ্জলগ</string>
<string name="loading">লোড হচ্ছে…</string>
<string name="update">হালনাগাদ</string>
<string name="not_available">N/A</string>
<string name="hide">লুকান</string>
<string name="home_package">প্যাকেজ</string>
<string name="home_app_title">অ্যাপ</string>
<string name="home_notice_content">শুধুমাত্র অফিসিয়াল গিটহাব পৃষ্ঠা থেকে ম্যাজিস্ক ডাউনলোড করুন। অজানা উৎস থেকে ফাইল দূষিত হতে পারে!</string>
<string name="home_support_title">আমাদের সমর্থন</string>
<string name="home_follow_title">আমাদের অনুসরণ করো</string>
<string name="home_item_source">সূত্র</string>
<string name="home_support_content">ম্যাজিস্ক হল, এবং সবসময় থাকবে, বিনামূল্যে, এবং ওপেন সোর্স। তবে আপনি দান করার মাধ্যমে আমাদের দেখাতে পারেন যে আপনি যত্নশীল.</string>
<string name="home_installed_version">ইনস্টল করা হয়েছে</string>
<string name="home_latest_version">সর্বশেষ</string>
<string name="invalid_update_channel">অবৈধ আপডেট চ্যানেল</string>
<string name="uninstall_magisk_title">ম্যাজিস্ক আনইনস্টল করুন</string>
<string name="uninstall_magisk_msg">সমস্ত মডিউল নিষ্ক্রিয়/মুছে ফেলা হবে!\nরুট সরানো হবে!\nম্যাজিস্ক ব্যবহারের মাধ্যমে এনক্রিপ্ট করা যে কোনও অভ্যন্তরীণ স্টোরেজ পুনরায় এনক্রিপ্ট করা হবে!</string>
<!--Install-->
<string name="keep_force_encryption">বল এনক্রিপশন সংরক্ষণ করুন</string>
<string name="keep_dm_verity">AVB 2.0/dm-verity সংরক্ষণ করুন</string>
<string name="patch_vbmeta">বুট ইমেজে vbmeta প্যাচ করুন</string>
<string name="recovery_mode">পুনরুদ্ধার অবস্থা</string>
<string name="install_options_title">অপশন</string>
<string name="install_method_title">পদ্ধতি</string>
<string name="install_next">পরবর্তী</string>
<string name="install_start">চলো যাই</string>
<string name="manager_download_install">ডাউনলোড এবং ইনস্টল করতে টিপুন</string>
<string name="direct_install">সরাসরি ইনস্টল (প্রস্তাবিত)</string>
<string name="install_inactive_slot">Iনিষ্ক্রিয় স্লটে ইনস্টল করুন (OTA পরে)</string>
<string name="install_inactive_slot_msg">রিবুট করার পরে আপনার ডিভাইসটিকে বর্তমান নিষ্ক্রিয় স্লটে বুট করতে বাধ্য করা হবে!\It হয়ে গেলেই এই বিকল্পটি ব্যবহার করুন।\চালিয়ে রাখবেন?</string>
<string name="setup_title">অতিরিক্ত সেটআপ</string>
<string name="select_patch_file">একটি ফাইল নির্বাচন করুন এবং প্যাচ করুন</string>
<string name="patch_file_msg">একটি কাঁচা চিত্র (*.img) বা একটি ODIN টারফাইল (*.tar) নির্বাচন করুন</string>
<string name="reboot_delay_toast">5 সেকেন্ডের মধ্যে রিবুট হচ্ছে...</string>
<string name="flash_screen_title">স্থাপন</string>
<!--Superuser-->
<string name="su_request_title">সুপার ইউজার অনুরোধ/স্ট্রিং</string>
<string name="touch_filtered_warning">যেহেতু একটি অ্যাপ সুপার ব্যবহারকারীর অনুরোধকে অস্পষ্ট করছে, ম্যাজিস্ক আপনার প্রতিক্রিয়া যাচাই করতে পারে না</string>
<string name="deny">অস্বীকার করুন</string>
<string name="prompt">শীঘ্র</string>
<string name="grant">প্রদান</string>
<string name="su_warning">আপনার ডিভাইসে সম্পূর্ণ অ্যাক্সেস মঞ্জুর করে৷\nআপনি নিশ্চিত না হলে অস্বীকার করুন!</string>
<string name="forever">চিরতরে</string>
<string name="once">একদা</string>
<string name="tenmin">১০ মিনিট</string>
<string name="twentymin">২০ মিনিট</string>
<string name="thirtymin">৩০ মিনিট</string>
<string name="sixtymin">৬০ মিনিট</string>
<string name="su_allow_toast">%1$s সুপার ইউজার অধিকার দেওয়া হয়েছিল</string>
<string name="su_deny_toast">%1$s সুপার ইউজার অধিকার অস্বীকার করা হয়েছিল</string>
<string name="su_snack_grant">%1$s-এর সুপার ব্যবহারকারীর অধিকার মঞ্জুর করা হয়েছে</string>
<string name="su_snack_deny">%1$s-এর সুপার ব্যবহারকারীর অধিকার অস্বীকার করা হয়েছে৷</string>
<string name="su_snack_notif_on">%1$s-এর বিজ্ঞপ্তিগুলি সক্ষম করা হয়েছে৷</string>
<string name="su_snack_notif_off">%1$s-এর বিজ্ঞপ্তিগুলি অক্ষম করা হয়েছে৷</string>
<string name="su_snack_log_on">%1$s এর লগিং সক্ষম করা হয়েছে৷</string>
<string name="su_snack_log_off">%1$s এর লগিং অক্ষম করা হয়েছে৷</string>
<string name="su_revoke_title">প্রত্যাহার করুন?</string>
<string name="su_revoke_msg">%1$s সুপার ব্যবহারকারীর অধিকার প্রত্যাহার করতে নিশ্চিত করুন৷</string>
<string name="toast">টোস্ট</string>
<string name="none">কোনোটিই নয়</string>
<string name="superuser_toggle_notification">বিজ্ঞপ্তি</string>
<string name="superuser_toggle_revoke">প্রত্যাহার করুন</string>
<string name="superuser_policy_none">কোনো অ্যাপ এখনও সুপার ইউজারের অনুমতি চায়নি।</string>
<!--Logs-->
<string name="log_data_none">আপনি লগ-মুক্ত, আপনার রুট অ্যাপগুলি আরও ব্যবহার করার চেষ্টা করুন৷</string>
<string name="log_data_magisk_none">ম্যাজিস্ক লগগুলি খালি, এটি অদ্ভুত</string>
<string name="menuSaveLog">লগ সংরক্ষণ</string>
<string name="menuClearLog">এখন লগ সাফ করুন</string>
<string name="logs_cleared">লগ সফলভাবে সাফ করা হয়েছে৷</string>
<string name="pid">PID: %1$d</string>
<string name="target_uid">লক্ষ্য UID: %1$d</string>
<!--SafetyNet-->
<!--MagiskHide-->
<string name="show_system_app">সিস্টেম অ্যাপ দেখান</string>
<string name="show_os_app">ওএস অ্যাপ দেখান</string>
<string name="hide_filter_hint">নাম অনুসারে ফিল্টার করুন</string>
<string name="hide_search">অনুসন্ধান করুন</string>
<!--Module-->
<string name="no_info_provided">(কোন তথ্য প্রদান করা হয়</string>
<string name="reboot_userspace">নরম রিবুট</string>
<string name="reboot_recovery">রিকভারিতে রিবুট করুন</string>
<string name="reboot_bootloader">বুটলোডারে রিবুট করুন</string>
<string name="reboot_download">ডাউনলোড করতে রিবুট করুন</string>
<string name="reboot_edl">EDL এ রিবুট করুন</string>
<string name="module_version_author">%1$s by %2$s</string>
<string name="module_state_remove">অপসারণ</string>
<string name="module_state_restore">পুনরুদ্ধার করুন</string>
<string name="module_action_install_external">স্টোরেজ থেকে ইনস্টল করুন</string>
<string name="update_available">আপডেট উপলব্ধ</string>
<string name="suspend_text_riru">মডিউল সাসপেন্ড করা হয়েছে কারণ %1$s সক্ষম হয়েছে৷</string>
<string name="suspend_text_zygisk">মডিউল সাসপেন্ড করা হয়েছে কারণ %1$s সক্ষম করা নেই৷</string>
<string name="zygisk_module_unloaded">অসামঞ্জস্যতার কারণে জাইগিস্ক মডিউল লোড করা হয়নি</string>
<string name="module_empty">কোন মডিউল ইনস্টল করা নেই</string>
<!--Settings-->
<string name="settings_dark_mode_title">থিম মোড</string>
<string name="settings_dark_mode_message">আপনার শৈলী সবচেয়ে উপযুক্ত মোড নির্বাচন করুন!</string>
<string name="settings_dark_mode_light">সবসময় আলো</string>
<string name="settings_dark_mode_system">সিস্টেম অনুসরণ করুন</string>
<string name="settings_dark_mode_dark">সবসময় অন্ধকার</string>
<string name="settings_download_path_title">পাথ ডাউনলোড করুন</string>
<string name="settings_download_path_message">ফাইলগুলি %1$s এ সংরক্ষণ করা হবে৷</string>
<string name="settings_hide_app_title">ম্যাজিস্ক অ্যাপটি লুকান</string>
<string name="settings_hide_app_summary">একটি র্যান্ডম প্যাকেজ আইডি এবং কাস্টম অ্যাপ লেব সহ একটি প্রক্সি অ্যাপ ইনস্টল করুনl</string>
<string name="settings_restore_app_title">ম্যাজিস্ক অ্যাপটি পুনরুদ্ধার করুন</string>
<string name="settings_restore_app_summary">অ্যাপটি আড়াল করুন এবং আসলটি পুনরুদ্ধার করুন</string>
<string name="language">ভাষা</string>
<string name="system_default">(সিস্টেমের ডিফল্ট)</string>
<string name="settings_check_update_title">আপডেট চেক করুন</string>
<string name="settings_check_update_summary">পর্যায়ক্রমে পটভূমিতে আপডেটের জন্য চেক করুন</string>
<string name="settings_update_channel_title">চ্যানেল আপডেট করুন</string>
<string name="settings_update_stable">স্থিতিশীল</string>
<string name="settings_update_beta">বেটা</string>
<string name="settings_update_custom">কাস্টম</string>
<string name="settings_update_custom_msg">একটি কাস্টম চ্যানেল URL সন্নিবেশ করুন</string>
<string name="settings_zygisk_summary">জাইগোট ডেমনে ম্যাজিস্কের অংশগুলি চালান</string>
<string name="settings_denylist_title">তালিকা অস্বীকার করুন প্রয়োগ করুন</string>
<string name="settings_denylist_summary">ডিনালিস্টের প্রসেসগুলিতে সমস্ত ম্যাজিস্ক পরিবর্তনগুলি ফিরিয়ে দেওয়া হবে</string>
<string name="settings_denylist_error">এই বৈশিষ্ট্যটির জন্য %1$s সক্ষম করা প্রয়োজন৷</string>
<string name="settings_denylist_config_title">অস্বীকার তালিকা কনফিগার করুন</string>
<string name="settings_denylist_config_summary">অস্বীকৃত তালিকায় অন্তর্ভুক্ত করার জন্য প্রক্রিয়াগুলি নির্বাচন করুন৷</string>
<string name="settings_hosts_title">সিস্টেমহীন হোস্ট</string>
<string name="settings_hosts_summary">বিজ্ঞাপন ব্লকিং অ্যাপের জন্য সিস্টেমলেস হোস্ট সমর্থন</string>
<string name="settings_hosts_toast">সিস্টেমহীন হোস্ট মডিউল যোগ করা হয়েছে</string>
<string name="settings_app_name_hint">নতুন নাম</string>
<string name="settings_app_name_helper">অ্যাপটি এই নামের সাথে পুনরায় প্যাকেজ করা হবে</string>
<string name="settings_app_name_error">ভুল ফরম্যাট</string>
<string name="settings_su_app_adb">অ্যাপস এবং এডিবি</string>
<string name="settings_su_app">শুধুমাত্র অ্যাপস</string>
<string name="settings_su_adb">শুধুমাত্র এডিবি</string>
<string name="settings_su_disable">অক্ষম</string>
<string name="settings_su_request_10">১০ সেকেন্ড</string>
<string name="settings_su_request_15">১৫ সেকেন্ড</string>
<string name="settings_su_request_20">২০ সেকেন্ড</string>
<string name="settings_su_request_30">৩০ সেকেন্ড</string>
<string name="settings_su_request_45">৪৫ সেকেন্ড</string>
<string name="settings_su_request_60">৬০ সেকেন্ড</string>
<string name="superuser_access">সুপার ইউজার অ্যাক্সেস</string>
<string name="auto_response">স্বয়ংক্রিয় প্রতিক্রিয়া</string>
<string name="request_timeout">অনুরোধের সময়সীমা শেষ</string>
<string name="superuser_notification">সুপার ইউজার বিজ্ঞপ্তি</string>
<string name="settings_su_reauth_title">আপগ্রেড করার পরে পুনরায় প্রমাণীকরণ করুন</string>
<string name="settings_su_reauth_summary">অ্যাপগুলি আপগ্রেড করার পরে আবার সুপার ইউজার অনুমতির জন্য জিজ্ঞাসা করুন</string>
<string name="settings_su_tapjack_title">ট্যাপজ্যাকিং সুরক্ষা</string>
<string name="settings_su_tapjack_summary">সুপার ইউজার প্রম্পট ডায়ালগ অন্য কোনো উইন্ডো বা ওভারলে দ্বারা অস্পষ্ট থাকাকালীন ইনপুটটিতে সাড়া দেবে না</string>
<string name="settings_su_biometric_title">বায়োমেট্রিক প্রমাণীকরণ</string>
<string name="settings_su_biometric_summary">সুপার ইউজার অনুরোধের অনুমতি দিতে বায়োমেট্রিক প্রমাণীকরণ ব্যবহার করুন</string>
<string name="no_biometric">অসমর্থিত ডিভাইস বা কোনো বায়োমেট্রিক সেটিংস সক্ষম করা নেই৷</string>
<string name="settings_customization">কাস্টমাইজেশন</string>
<string name="setting_add_shortcut_summary">অ্যাপটি লুকানোর পরে নাম এবং আইকন সনাক্ত করা কঠিন হলে হোম স্ক্রিনে একটি সুন্দর শর্টকাট যোগ করুন</string>
<string name="settings_doh_title">HTTPS এর উপর ডিএনএস</string>
<string name="settings_doh_description">কিছু দেশে ডিএনএস বিষক্রিয়ার সমাধান</string>
<string name="multiuser_mode">মাল্টিউজার মোড</string>
<string name="settings_owner_only">শুধুমাত্র ডিভাইসের মালিক</string>
<string name="settings_owner_manage">ডিভাইস মালিক পরিচালিত</string>
<string name="settings_user_independent">ব্যবহারকারী-স্বাধীন</string>
<string name="owner_only_summary">শুধুমাত্র মালিকের রুট অ্যাক্সেস আছে</string>
<string name="owner_manage_summary">শুধুমাত্র মালিকই রুট অ্যাক্সেস পরিচালনা করতে পারে এবং অনুরোধ প্রম্পট গ্রহণ করতে পারে</string>
<string name="user_independent_summary">প্রতিটি ব্যবহারকারীর নিজস্ব পৃথক রুট নিয়ম আছে</string>
<string name="mount_namespace_mode">মাউন্ট নেমস্পেস মোড</string>
<string name="settings_ns_global">গ্লোবাল নেমস্পেস</string>
<string name="settings_ns_requester">নেমস্পেস ইনহেরিট করুন</string>
<string name="settings_ns_isolate">বিচ্ছিন্ন নামস্থান</string>
<string name="global_summary">সমস্ত রুট সেশন গ্লোবাল মাউন্ট নেমস্পেস ব্যবহার করে</string>
<string name="requester_summary">রুট সেশন অনুরোধকারীর নামস্থান উত্তরাধিকারী হবে</string>
<string name="isolate_summary">প্রতিটি রুট সেশনের নিজস্ব বিচ্ছিন্ন নামস্থান থাকবে</string>
<!--Notifications-->
<string name="update_channel">ম্যাজিস্ক আপডেট</string>
<string name="progress_channel">অগ্রগতি বিজ্ঞপ্তি</string>
<string name="updated_channel">আপডেট সম্পূর্ণ</string>
<string name="download_complete">ডাউনলোড শেষ</string>
<string name="download_file_error">ফাইল ডাউনলোড করার সময় ত্রুটি</string>
<string name="magisk_update_title">ম্যাজিস্ক আপডেট উপলব্ধ!</string>
<string name="updated_title">ম্যাজিস্ক আপডেট</string>
<string name="updated_text">অ্যাপ খুলতে আলতো চাপুন</string>
<!--Toasts, Dialogs-->
<string name="yes">হ্যাঁ</string>
<string name="no">না</string>
<string name="repo_install_title">ইনস্টল করুন %1$s %2$s(%3$d)</string>
<string name="download">ডাউনলোড করুন</string>
<string name="reboot">রিবুট করুন</string>
<string name="release_notes">অব্যাহতি পত্র</string>
<string name="flashing">ঝলকানি…</string>
<string name="done">সম্পন্ন!</string>
<string name="failure">ব্যর্থ হয়েছে!</string>
<string name="hide_app_title">ম্যাজিস্ক অ্যাপটি লুকিয়ে রাখছে…</string>
<string name="open_link_failed_toast">লিঙ্ক খোলার জন্য কোনো অ্যাপ পাওয়া যায়নি</string>
<string name="complete_uninstall">সম্পূর্ণ আনইনস্টল করুন</string>
<string name="restore_img">ছবি পুনরুদ্ধার করুন</string>
<string name="restore_img_msg">পুনরুদ্ধার করা হচ্ছে…</string>
<string name="restore_done">পুনরুদ্ধার করা হয়েছে!</string>
<string name="restore_fail">স্টক ব্যাকআপ বিদ্যমান নেই!</string>
<string name="setup_fail">সেটআপ ব্যর্থ হয়েছে৷</string>
<string name="env_fix_title">অতিরিক্ত সেটআপ প্রয়োজন</string>
<string name="env_fix_msg">ম্যাজিস্ক সঠিকভাবে কাজ করার জন্য আপনার ডিভাইসের অতিরিক্ত সেটআপ প্রয়োজন। আপনি কি এগিয়ে যেতে এবং রিবুট করতে চান??</string>
<string name="setup_msg">চলমান পরিবেশ সেটআপ…</string>
<string name="authenticate">প্রমাণীকরণ</string>
<string name="unsupport_magisk_title">অসমর্থিত ম্যাজিস্ক সংস্করণ</string>
<string name="unsupport_magisk_msg">অ্যাপটির এই সংস্করণটি %1$s-এর চেয়ে কম ম্যাগিস্ক সংস্করণগুলিকে সমর্থন করে না৷\n\nঅ্যাপটি এমন আচরণ করবে যেন কোনও ম্যাজিস্ক ইনস্টল করা নেই, দয়া করে যত তাড়াতাড়ি সম্ভব ম্যাজিস্ক আপগ্রেড করুন.</string>
<string name="unsupport_general_title">অস্বাভাবিক অবস্থা</string>
<string name="unsupport_system_app_msg">এই অ্যাপটিকে একটি সিস্টেম অ্যাপ হিসেবে চালানো সমর্থিত নয়। অনুগ্রহ করে অ্যাপটিকে একটি ব্যবহারকারী অ্যাপে ফিরিয়ে দিন.</string>
<string name="unsupport_other_su_msg">ম্যাজিস্ক থেকে নয় একটি \"su\" বাইনারি সনাক্ত করা হয়েছে। অনুগ্রহ করে কোনো প্রতিযোগী রুট সমাধান সরান এবং/অথবা ম্যাজিস্ক পুনরায় ইনস্টল করুন।</string>
<string name="unsupport_external_storage_msg">ম্যাজিস্ক বহিরাগত স্টোরেজ ইনস্টল করা হয়. অনুগ্রহ করে অ্যাপটিকে অভ্যন্তরীণ সঞ্চয়স্থানে সরান৷</string>
<string name="unsupport_nonroot_stub_msg">লুকানো ম্যাজিস্ক অ্যাপটি কাজ চালিয়ে যেতে পারে না কারণ রুট হারিয়ে গেছে। অনুগ্রহ করে আসল APK পুনরুদ্ধার করুন।</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">এই কার্যকারিতা সক্ষম করতে স্টোরেজ অনুমতি দিন</string>
<string name="install_unknown_denied">এই কার্যকারিতা সক্ষম করতে "অজানা অ্যাপগুলি ইনস্টল করুন" এর অনুমতি দিন</string>
<string name="add_shortcut_title">হোম স্ক্রিনে শর্টকাট যোগ করুন</string>
<string name="add_shortcut_msg">এই অ্যাপটি লুকানোর পরে, এর নাম এবং আইকন চিনতে অসুবিধা হতে পারে। আপনি কি হোম স্ক্রিনে একটি সুন্দর শর্টকাট যোগ করতে চান?</string>
<string name="app_not_found">এই ক্রিয়াটি পরিচালনা করার জন্য কোনো অ্যাপ পাওয়া যায়নি</string>
<string name="reboot_apply_change">পরিবর্তনগুলি প্রয়োগ করতে রিবুট করুন</string>
<string name="restore_app_confirmation">এটি লুকানো অ্যাপটিকে মূল অ্যাপে ফিরিয়ে আনবে। আপনি কি সত্যিই এটি করতে চান?</string>
</resources>

View File

@@ -22,6 +22,7 @@
<string name="home_notice_content">Laden Sie Magisk NUR von der offiziellen Github Seite herunter. Dateien aus unbekannten Quellen können bösartig sein!</string>
<string name="home_support_title">Unterstützen Sie uns</string>
<string name="home_follow_title">Folgen Sie uns</string>
<string name="home_item_source">Quelle</string>
<string name="home_support_content">Magisk ist und wird immer frei und quelloffen sein. Sie können uns jedoch jederzeit mit einer kleinen Spende unterstützen.</string>
<string name="home_installed_version">Installiert</string>
@@ -111,6 +112,7 @@
<string name="suspend_text_riru">Modul ausgesetzt, weil %1$s aktiviert ist</string>
<string name="suspend_text_zygisk">Modul ausgesetzt, weil %1$s nicht aktiviert ist</string>
<string name="zygisk_module_unloaded">Zygisk-Modul aufgrund von Inkompatibilität nicht geladen</string>
<string name="module_empty">Kein Modul installiert</string>
<!--Settings-->
<string name="settings_dark_mode_title">Themen-Modus</string>
@@ -190,9 +192,12 @@
<!--Notifications-->
<string name="update_channel">Magisk Updates</string>
<string name="progress_channel">Fortschrittsmitteilungen</string>
<string name="updated_channel">Update abgeschlossen</string>
<string name="download_complete">Download abgeschlossen</string>
<string name="download_file_error">Fehler beim Herunterladen der Datei</string>
<string name="magisk_update_title">Magisk Update verfügbar!</string>
<string name="updated_title">Magisk aktualisiert</string>
<string name="updated_text">Tippen, um die App zu öffnen</string>
<!--Toasts, Dialogs-->
<string name="yes">Ja</string>
@@ -225,6 +230,8 @@
<string name="unsupport_nonroot_stub_msg">App kann im versteckten Zustand nicht weiter funktionieren, da Root verloren gegangen ist. Ursprüngliche APK bitte wiederherstellen.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Speichererlaubnis erteilen, um diese Funktion zu aktivieren</string>
<string name="install_unknown_denied">Unbekannte Apps installieren erlauben, um diese Funktion zu aktivieren</string>
<string name="add_shortcut_title">Verknüpfung zum Startbildschirm hinzufügen</string>
<string name="add_shortcut_msg">Nachdem Sie diese App verstecken, wird der Name und das Symbol eventuell schwer zu erkennen sein. Möchten Sie zum Startbildschirm eine schöne Verknüpfung hinzufügen?</string>
<string name="app_not_found">Keine App gefunden, die diese Aktion verarbeitet</string>

View File

@@ -8,6 +8,7 @@
<string name="install">Εγκατάσταση</string>
<string name="section_home">Αρχική</string>
<string name="section_theme">Θέματα</string>
<string name="denylist">Λίστα Απορρίψεων</string>
<!--Home-->
<string name="no_connection">Δεν υπάρχει διαθέσιμη σύνδεση</string>
@@ -21,6 +22,7 @@
<string name="home_notice_content">Κάντε λήψη του Magisk ΜΟΝΟ από την επίσημη σελίδα του GitHub. Τα αρχεία από άγνωστες πηγές μπορεί να είναι κακόβουλα!</string>
<string name="home_support_title">Υποστήριξη</string>
<string name="home_follow_title">Ακολούθησε μας</string>
<string name="home_item_source">Πηγή</string>
<string name="home_support_content">Το Magisk είναι, και θα είναι για πάντα, δωρεάν και ανοιχτού κώδικα. Μπορείτε ωστόσο να μας δείξετε ότι ενδιαφέρεστε στέλνοντας μια μικρή δωρεά.</string>
<string name="home_installed_version">Τρέχουσα έκδοση</string>
@@ -32,6 +34,7 @@
<!--Install-->
<string name="keep_force_encryption">Διατήρηση επιβεβλημένης κρυπτογράφησης</string>
<string name="keep_dm_verity">Διατήρηση AVB 2.0/dm-verity</string>
<string name="patch_vbmeta">Patch vbmeta στην εικόνα του boot</string>
<string name="recovery_mode">Μέσω Recovery mode</string>
<string name="install_options_title">Επιλογές</string>
<string name="install_method_title">Μέθοδος</string>
@@ -76,6 +79,7 @@
<string name="superuser_toggle_notification">Ειδοποιήσεις</string>
<string name="superuser_toggle_revoke">Ανακάλεσε</string>
<string name="superuser_policy_none">Καμία εφαρμογή δεν έχει ζητήσει άδεια υπερχρήστη.</string>
<!--Logs-->
<string name="log_data_none">Δεν υπάρχουν αρχεία καταγραφής, δοκιμάστε να χρησιμοποιήσετε περισσότερο τις εφαρμογές με δυνατότητα SU</string>
<string name="log_data_magisk_none">Τα αρχεία καταγραφής του Magisk είναι κενά, αυτό είναι περίεργο</string>
@@ -105,6 +109,10 @@
<string name="module_state_restore">Επαναφορά</string>
<string name="module_action_install_external">Εγκατάσταση από χώρο αποθήκευσης</string>
<string name="update_available">Διαθέσιμη Ενημέρωση</string>
<string name="suspend_text_riru">Η επέκταση έχει ανασταλεί επειδή το %1$s είναι ενεργοποιημένο</string>
<string name="suspend_text_zygisk">Η επέκταση έχει ανασταλεί επειδή το %1$s δεν είναι ενεργοποιημένο</string>
<string name="zygisk_module_unloaded">Zygisk module not loaded due to incompatibility</string>
<string name="module_empty">Δεν υπάρχουν εγκατεστημένες επεκτάσεις</string>
<!--Settings-->
<string name="settings_dark_mode_title">Λειτουργία θέματος</string>
@@ -127,6 +135,12 @@
<string name="settings_update_beta">Δοκιμαστικό</string>
<string name="settings_update_custom">Προσαρμοσμένο</string>
<string name="settings_update_custom_msg">Εισαγωγή ενός custom URL</string>
<string name="settings_zygisk_summary">Εκτέλεση μέρους του Magisk μέσα στο zygote daemon</string>
<string name="settings_denylist_title">Επιβολή Λίστας Απορρίψεων</string>
<string name="settings_denylist_summary">Επαναφορά όλων των τροποποιήσεων του Magisk για της διεργασίες στην λίστα απορρίψεων</string>
<string name="settings_denylist_error">Αυτή η λειτουργεία απαιτεί τη %1$s να είναι ενεργοποιημένη</string>
<string name="settings_denylist_config_title">Τροποποίηση της Λίστας Απορρίψεων</string>
<string name="settings_denylist_config_summary">Επιλογή διεργασίας για να συμπεριληφθεί στη λίστα απορρίψεων</string>
<string name="settings_hosts_title">Systemless hosts</string>
<string name="settings_hosts_summary">Υποστήριξη Systemless hosts για εφαρμογές Adblock</string>
<string name="settings_hosts_toast">Προσθήκη αρθρώματος systemless hosts</string>
@@ -178,9 +192,12 @@
<!--Notifications-->
<string name="update_channel">Ενημερώσεις Magisk</string>
<string name="progress_channel">Ειδοποιήσεις προόδου</string>
<string name="updated_channel">Η Αναβάθμηση Ολοκληρώθηκε</string>
<string name="download_complete">Η λήψη ολοκληρώθηκε</string>
<string name="download_file_error">Σφάλμα στη λήψη του αρχείου</string>
<string name="magisk_update_title">Νέα Ενημέρωση Magisk Διαθέσιμη!</string>
<string name="updated_title">Το Magisk Ενημερώθηκε</string>
<string name="updated_text">Πατήστε για άνοιγμα εφαρμογής</string>
<!--Toasts, Dialogs-->
<string name="yes">Ναι</string>
@@ -206,10 +223,18 @@
<string name="authenticate">Αυθεντικοποίηση</string>
<string name="unsupport_magisk_title">Μη υποστηριζόμενη έκδοση Magisk</string>
<string name="unsupport_magisk_msg">Αυτή η έκδοση της εφαρμογής δεν υποστηρίζει έκδοση Magisk χαμηλότερη από %1$s.\n\nΗ εφαρμογή θα συμπεριφέρεται σαν να μην έχει εγκατασταθεί το Magisk, αναβαθμίστε το Magisk το συντομότερο δυνατό.</string>
<string name="external_rw_permission_denied">Παραχωρήστε άδεια αποθήκευσης για να ενεργοποιήσετε αυτήν τη λειτουργία</string>
<string name="unsupport_general_title">Μη Φυσιολογική Κατάσταση</string>
<string name="unsupport_system_app_msg">Η εκτέλεση αυτής της εφαρμογής ως εφαρμογής συστήματος δεν υποστηρίζεται. Επαναφέρετε την εφαρμογή σε εφαρμογή χρήστη.</string>
<string name="unsupport_other_su_msg">Εντοπίστηκε ένα \"su\" binary που δεν είναι από το Magisk. Καταργήστε οποιαδήποτε άλλη root μέθοδο και/ή επανεγκαταστήστε το Magisk.</string>
<string name="unsupport_external_storage_msg">Το Magisk είναι εγκατεστημένο σε εξωτερικό χώρο αποθήκευσης. Μετακινήστε την εφαρμογή στον εσωτερικό χώρο αποθήκευσης.</string>
<string name="unsupport_nonroot_stub_msg">Η κρυφή εφαρμογή Magisk δεν μπορεί να συνεχίσει να λειτουργεί επειδή χάθηκε το root. Παρακαλώ επαναφέρετε το αρχικό APK.</string>
<string name="external_rw_permission_denied">Παραχωρήστε άδεια αποθήκευσης για να ενεργοποιήσετε αυτήν τη λειτουργία</string>
<string name="install_unknown_denied">Επιτρέψτε την "εγκατάσταση άγνωστων εφαρμογών" για να ενεργοποιήσετε αυτήν τη λειτουργία</string>
<string name="add_shortcut_title">Προσθέστε συντόμευση στην αρχική οθόνη</string>
<string name="add_shortcut_msg">Μετά την απόκρυψη αυτής της εφαρμογής, το όνομα και το εικονίδιο της ενδέχεται να είναι δύσκολο να αναγνωριστούν. Θέλετε να προσθέσετε μια όμορφη συντόμευση στην αρχική οθόνη;</string>
<string name="app_not_found">Δεν βρέθηκε εφαρμογή που να χειρίζεται αυτήν την ενέργεια</string>
<string name="reboot_apply_change">Επανεκκινήστε για να εφαρμόσετε της αλλαγές</string>
<string name="restore_app_confirmation">Αυτό θα επαναφέρει την κρυφή εφαρμογή πίσω στην αρχική εφαρμογή. Θέλετε πραγματικά να το κάνετε αυτό;</string>
</resources>

View File

@@ -22,6 +22,7 @@
<string name="home_notice_content">Descarga Magisk SÓLO de la página de GitHub oficial. Archivos de fuentes desconocidas pueden resultar maliciosos!</string>
<string name="home_support_title">Apóyenos</string>
<string name="home_follow_title">Síganos</string>
<string name="home_item_source">Código fuente</string>
<string name="home_support_content">Magisk es, y siempre será gratuito y de código abierto. Sin embargo, puede apoyarnos enviando una pequeña donación.</string>
<string name="home_installed_version">Instalado</string>
@@ -33,6 +34,7 @@
<!--Install-->
<string name="keep_force_encryption">Mantener cifrado forzado</string>
<string name="keep_dm_verity">Mantener AVB 2.0/dm-verity</string>
<string name="patch_vbmeta">Parche vbmeta en la imagen de arranque</string>
<string name="recovery_mode">Modo recovery</string>
<string name="install_options_title">Opciones</string>
<string name="install_method_title">Método</string>
@@ -109,6 +111,8 @@
<string name="update_available">Actualización disponible</string>
<string name="suspend_text_riru">Módulo suspendido porque %1$s está habilitado</string>
<string name="suspend_text_zygisk">Módulo suspendido porque %1$s no está habilitado</string>
<string name="zygisk_module_unloaded">Módulo Zygisk no cargado debido a incompatibilidad</string>
<string name="module_empty">Ningún módulo instalado</string>
<!--Settings -->
<string name="settings_dark_mode_title">Elegir modo</string>
@@ -188,9 +192,12 @@
<!--Notifications-->
<string name="update_channel">Actualización de Magisk</string>
<string name="progress_channel">Notificaciones de progreso</string>
<string name="updated_channel">Actualización completa</string>
<string name="download_complete">Descarga Completa</string>
<string name="download_file_error">Error descargando archivo</string>
<string name="magisk_update_title">¡Actualización de Magisk disponible!</string>
<string name="updated_title">Magisk Actualizado</string>
<string name="updated_text">Toca para abrir la aplicación</string>
<!--Toasts, Dialogs-->
<string name="yes"></string>
@@ -216,10 +223,18 @@
<string name="authenticate">Autenticar</string>
<string name="unsupport_magisk_title">Versión de Magisk no soportada</string>
<string name="unsupport_magisk_msg">Esta versión de la app no soporta versiones de Magisk inferiores a la %1$s.\n\nLa aplicación se comportará como si no tuvieses Magisk instalado, por favor actualiza Magisk tan pronto como sea posible.</string>
<string name="unsupport_general_title">Estado anormal</string>
<string name="unsupport_system_app_msg">No se admite la ejecución de esta aplicación como una aplicación del sistema. Revierta la aplicación a una aplicación de usuario.</string>
<string name="unsupport_other_su_msg">Se ha detectado un binario \"su\" que no es de Magisk. Elimine cualquier solución raíz de la competencia y/o reinstale Magisk.</string>
<string name="unsupport_external_storage_msg">Magisk está instalado en el almacenamiento externo. Mueva la aplicación al almacenamiento interno.</string>
<string name="unsupport_nonroot_stub_msg">La aplicación Magisk oculta no puede seguir funcionando porque se perdió la raíz. Restaura el APK original.</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">Conceder permiso de almacenamiento para habilitar esta funcionalidad</string>
<string name="install_unknown_denied">Permitir "instalar aplicaciones desconocidas" para habilitar esta funcionalidad</string>
<string name="add_shortcut_title">Añadir un atajo a la pantalla de inicio</string>
<string name="add_shortcut_msg">Tras esconder la app, su nombre e icono pueden resultar difíciles de reconocer. ¿Quieres añadir un acceso directo más bonito a la pantalla principal?</string>
<string name="app_not_found">No se ha encontrado ninguna app para manejar esta acción</string>
<string name="reboot_apply_change">Reiniciar para aplicar cambios</string>
<string name="restore_app_confirmation">Esto restaurará la aplicación oculta a la aplicación original. ¿Realmente quieres hacer esto?</string>
</resources>

View File

@@ -20,16 +20,16 @@
<string name="home_package">パッケージ ID </string>
<string name="home_app_title">アプリ</string>
<string name="home_notice_content">Magisk は必ず公式 GitHub ページからダウンロードしてください。その他の提供元では悪意あるコードを含んでいる可能性があります!</string>
<string name="home_notice_content">Magisk は必ず公式 GitHub ページからダウンロードしてください。その他の提供元では悪意あるコードを含んでいる可能性があります!</string>
<string name="home_support_title">サポートする</string>
<string name="home_follow_title">フォローする</string>
<string name="home_item_source">ソース</string>
<string name="home_support_content">Magisk はフリーでオープンソースです。寄付を送ることで Magisk の開発を支援できます。</string>
<string name="home_support_content">Magisk はフリーでオープンソースです。寄付を送ることで Magisk の開発を支援することができます。</string>
<string name="home_installed_version">インストール済</string>
<string name="home_latest_version">最新版</string>
<string name="invalid_update_channel">不正な更新チャンネルです</string>
<string name="uninstall_magisk_title">Magisk のアンインストール</string>
<string name="uninstall_magisk_msg">すべてのモジュールが無効化/削除されます。\nアンインストール後は root が無効化されストレージが暗号化されていない場合暗号化される場合があります。</string>
<string name="uninstall_magisk_msg">すべてのモジュールが無効化/削除されます。\nアンインストール後は root が削除されストレージが暗号化されていない場合暗号化される場合があります。</string>
<!--Install-->
<string name="keep_force_encryption">暗号化を維持する</string>
@@ -40,7 +40,7 @@
<string name="install_method_title">方法</string>
<string name="install_next">次へ</string>
<string name="install_start">はじめる</string>
<string name="manager_download_install">タップダウンロードしてインストールします</string>
<string name="manager_download_install">タップしてダウンロードインストールします</string>
<string name="direct_install">直接インストール (推奨)</string>
<string name="install_inactive_slot">別のスロットにインストール (OTA 後)</string>
<string name="install_inactive_slot_msg">お使いのデバイスは再起動後に現在とは別のスロットで強制的に起動されます!\nこのオプションは OTA の完了後にのみ使用してください。\n続行しますか</string>
@@ -52,7 +52,7 @@
<!--Superuser-->
<string name="su_request_title">スーパーユーザー権限の要求</string>
<string name="touch_filtered_warning">スーパーユーザー権限の要求ダイアログが他のアプリで隠れているため、Magisk はあなたの応答を確認できません。</string>
<string name="touch_filtered_warning">他のアプリがスーパーユーザー権限の要求ダイアログを隠しているため、Magisk はあなたの応答を確認できません。</string>
<string name="deny">拒否</string>
<string name="prompt">尋ねる</string>
<string name="grant">許可</string>
@@ -206,7 +206,7 @@
<string name="download">ダウンロード</string>
<string name="reboot">再起動</string>
<string name="release_notes">更新履歴</string>
<string name="flashing">き込み中…</string>
<string name="flashing">中…</string>
<string name="done">完了!</string>
<string name="failure">失敗!</string>
<string name="hide_app_title">Magisk アプリを隠しています…</string>
@@ -218,7 +218,7 @@
<string name="restore_fail">Stock のバックアップがありません!</string>
<string name="setup_fail">セットアップに失敗しました</string>
<string name="env_fix_title">追加のセットアップが必要です</string>
<string name="env_fix_msg">Magisk を正常に動作させるために追加のセットアップが必要です。今すぐ再起動しますか?</string>
<string name="env_fix_msg">Magisk を正常に動作させるために追加のセットアップが必要です。今すぐ再起動しますか?</string>
<string name="setup_msg">追加セットアップを実行中…</string>
<string name="authenticate">認証</string>
<string name="unsupport_magisk_title">対応していない Magisk バージョンです</string>
@@ -227,7 +227,7 @@
<string name="unsupport_system_app_msg">このアプリをシステムアプリとして起動することはサポートされていません。ユーザーアプリに戻してください。</string>
<string name="unsupport_other_su_msg">Magisk 以外の \"su\" バイナリが検出されました。競合する root 権限取得ソフトを削除し、Magisk をインストールし直してください。</string>
<string name="unsupport_external_storage_msg">Magisk が外部ストレージにインストールされています。内部ストレージに移動してください。</string>
<string name="unsupport_nonroot_stub_msg">root 権限が失われたためMagisk の隠しアプリが動作できなくなりました。元の APK を復元してください。</string>
<string name="unsupport_nonroot_stub_msg">root 権限が失われたため、隠し Magisk アプリが動作できなくなりました。元の APK を復元してください。</string>
<string name="unsupport_nonroot_stub_title">@string/settings_restore_app_title</string>
<string name="external_rw_permission_denied">この機能を有効にするにはストレージ権限を許可してください</string>
<string name="install_unknown_denied">この機能を有効化するには、不明なソースからのインストールを許可してください</string>

View File

@@ -119,7 +119,7 @@
<string name="settings_download_path_title">Caminho para Baixar</string>
<string name="settings_download_path_message">Os arquivos serão salvos em %1$s</string>
<string name="settings_hide_app_title">Ocultar o app do Magisk</string>
<string name="settings_hide_app_summary">Instala o app ooulto com ID aleatório e nome personalizado</string>
<string name="settings_hide_app_summary">Instala o app oculto com ID aleatório e nome personalizado</string>
<string name="settings_restore_app_title">Restaurar o App do Magisk</string>
<string name="settings_restore_app_summary">Desoculta o app do Magisk e restaura o APK original</string>
<string name="language">Idioma</string>

View File

@@ -2,7 +2,7 @@
<!--Sections-->
<string name="modules">Модули</string>
<string name="superuser">Суперпользователь</string>
<string name="superuser">Superuser</string>
<string name="logs">Лог</string>
<string name="settings">Настройки</string>
<string name="install">Установка</string>

140
build.py
View File

@@ -37,10 +37,10 @@ def vprint(str):
is_windows = os.name == 'nt'
is_ci = 'CI' in os.environ and os.environ['CI'] == 'true'
EXE_EXT = '.exe' if is_windows else ''
if not is_ci and is_windows:
import colorama
colorama.init()
# Environment checks
@@ -58,16 +58,20 @@ except FileNotFoundError:
cpu_count = multiprocessing.cpu_count()
archs = ['armeabi-v7a', 'x86', 'arm64-v8a', 'x86_64']
triples = ['armv7a-linux-androideabi', 'i686-linux-android', 'aarch64-linux-android', 'x86_64-linux-android']
default_targets = ['magisk', 'magiskinit', 'magiskboot', 'magiskpolicy', 'busybox']
support_targets = default_targets + ['resetprop', 'test']
rust_targets = ['magisk', 'magiskinit', 'magiskboot', 'magiskpolicy']
sdk_path = os.environ['ANDROID_SDK_ROOT']
ndk_root = op.join(sdk_path, 'ndk')
ndk_path = op.join(ndk_root, 'magisk')
ndk_build = op.join(ndk_path, 'ndk-build')
rust_bin = op.join(ndk_path, 'toolchains', 'rust', 'bin')
cargo = op.join(rust_bin, 'cargo' + EXE_EXT)
gradlew = op.join('.', 'gradlew' + ('.bat' if is_windows else ''))
adb_path = op.join(sdk_path, 'platform-tools', 'adb' + ('.exe' if is_windows else ''))
native_gen_path = op.join('native', 'out', 'generated')
adb_path = op.join(sdk_path, 'platform-tools', 'adb' + EXE_EXT)
native_gen_path = op.realpath(op.join('native', 'out', 'generated'))
# Global vars
config = {}
@@ -123,16 +127,17 @@ def mkdir_p(path, mode=0o755):
os.makedirs(path, mode, exist_ok=True)
def execv(cmd):
return subprocess.run(cmd, stdout=STDOUT)
def execv(cmd, env=None):
return subprocess.run(cmd, stdout=STDOUT, env=env)
def system(cmd):
return subprocess.run(cmd, shell=True, stdout=STDOUT)
def cmd_out(cmd):
return subprocess.check_output(cmd).strip().decode('utf-8')
def cmd_out(cmd, env=None):
return subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env) \
.stdout.strip().decode('utf-8')
def xz(data):
@@ -180,15 +185,6 @@ def load_config(args):
STDOUT = None if args.verbose else subprocess.DEVNULL
def collect_binary():
for arch in archs:
mkdir_p(op.join('native', 'out', arch))
for bin in support_targets + ['libpreload.so']:
source = op.join('native', 'libs', arch, bin)
target = op.join('native', 'out', arch, bin)
mv(source, target)
def clean_elf():
if is_windows:
elf_cleaner = op.join('tools', 'elf-cleaner.exe')
@@ -203,48 +199,6 @@ def clean_elf():
execv(args)
def find_build_tools():
global build_tools
if build_tools:
return build_tools
build_tools_root = op.join(os.environ['ANDROID_SDK_ROOT'], 'build-tools')
ls = os.listdir(build_tools_root)
# Use the latest build tools available
ls.sort()
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:
return
msg = '* Signing APK'
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']
if unsigned.endswith('.zip'):
msg = '* Signing zip'
exec_args.extend(['--min-sdk-version', '17',
'--v2-signing-enabled', 'false',
'--v3-signing-enabled', 'false'])
exec_args.append(unsigned)
header(msg)
proc = execv(exec_args)
if proc.returncode != 0:
error('Signing failed!')
def binary_dump(src, var_name):
out_str = f'constexpr unsigned char {var_name}[] = {{'
for i, c in enumerate(xz(src.read())):
@@ -261,7 +215,70 @@ def run_ndk_build(flags):
if proc.returncode != 0:
error('Build binary failed!')
os.chdir('..')
collect_binary()
for arch in archs:
for tgt in support_targets + ['libpreload.so']:
source = op.join('native', 'libs', arch, tgt)
target = op.join('native', 'out', arch, tgt)
mv(source, target)
def run_cargo_build(args):
os.chdir(op.join('native', 'rust'))
targets = set(args.target) & set(rust_targets)
env = os.environ.copy()
env['CARGO_BUILD_RUSTC'] = op.join(rust_bin, 'rustc' + EXE_EXT)
# Install cxxbridge and generate C++ bindings
native_out = op.join('..', '..', 'native', 'out')
local_cargo_root = op.join(native_out, '.cargo')
mkdir_p(local_cargo_root)
cmds = [cargo, 'install', '--root', local_cargo_root, 'cxxbridge-cmd']
if not args.verbose:
cmds.append('-q')
proc = execv(cmds, env)
if proc.returncode != 0:
error('cxxbridge-cmd installation failed!')
cxxbridge = op.join(local_cargo_root, 'bin', 'cxxbridge' + EXE_EXT)
mkdir(native_gen_path)
for p in ['base', 'boot', 'core', 'init', 'sepolicy']:
text = cmd_out([cxxbridge, op.join(p, 'src', 'lib.rs')])
write_if_diff(op.join(native_gen_path, f'{p}-rs.cpp'), text)
text = cmd_out([cxxbridge, '--header', op.join(p, 'src', 'lib.rs')])
write_if_diff(op.join(native_gen_path, f'{p}-rs.hpp'), text)
# Start building the actual build commands
cmds = [cargo, 'build', '-Z', 'build-std=std,panic_abort',
'-Z', 'build-std-features=panic_immediate_abort']
for target in targets:
cmds.append('-p')
cmds.append(target)
rust_out = 'debug'
if args.release:
cmds.append('-r')
rust_out = 'release'
if not args.verbose:
cmds.append('-q')
os_name = platform.system().lower()
llvm_bin = op.join(ndk_path, 'toolchains', 'llvm', 'prebuilt', f'{os_name}-x86_64', 'bin')
env['TARGET_CC'] = op.join(llvm_bin, 'clang' + EXE_EXT)
env['RUSTFLAGS'] = '-Clinker-plugin-lto'
for (arch, triple) in zip(archs, triples):
env['TARGET_CFLAGS'] = f'--target={triple}21'
rust_triple = 'thumbv7neon-linux-androideabi' if triple.startswith('armv7') else triple
proc = execv([*cmds, '--target', rust_triple], env)
if proc.returncode != 0:
error('Build binary failed!')
arch_out = op.join(native_out, arch)
mkdir(arch_out)
for tgt in targets:
source = op.join('target', rust_triple, rust_out, f'lib{tgt}.a')
target = op.join(arch_out, f'lib{tgt}-rs.a')
mv(source, target)
os.chdir(op.join('..', '..'))
def write_if_diff(file_name, text):
@@ -326,6 +343,8 @@ def build_binary(args):
header('* Building binaries: ' + ' '.join(args.target))
run_cargo_build(args)
dump_flag_header()
flag = ''
@@ -402,10 +421,11 @@ def cleanup(args):
rm_rf(op.join('native', 'out'))
rm_rf(op.join('native', 'libs'))
rm_rf(op.join('native', 'obj'))
rm_rf(op.join('native', 'rust', 'target'))
if 'java' in args.target:
header('* Cleaning java')
execv([gradlew, 'clean'])
execv([gradlew, 'app:clean', 'app:shared:clean', 'stub:clean'])
def setup_ndk(args):

View File

@@ -11,7 +11,8 @@ import javax.crypto.spec.SecretKeySpec
import kotlin.random.asKotlinRandom
// Set non-zero value here to fix the random seed for reproducible builds
const val RAND_SEED = 0
// CI builds are always reproducible
val RAND_SEED = if (System.getenv("CI") != null) 42 else 0
private lateinit var RANDOM: Random
private val kRANDOM get() = RANDOM.asKotlinRandom()

View File

@@ -24,6 +24,7 @@ import java.io.PrintStream
import java.security.KeyStore
import java.security.cert.X509Certificate
import java.util.*
import java.util.jar.JarFile
import java.util.zip.*
private fun Project.androidBase(configure: Action<BaseExtension>) =
@@ -90,6 +91,7 @@ private fun addComment(apkPath: File, signConfig: SigningConfig, minSdk: Int, eo
SigningExtension(signingOptions).register(it)
it.eocdComment = eocdComment.toByteArray()
it.get(IncrementalPackager.APP_METADATA_ENTRY_PATH)?.delete()
it.get(JarFile.MANIFEST_NAME)?.delete()
}
}
@@ -133,11 +135,8 @@ private fun Project.setupAppCommon() {
android.applicationVariants.all {
val projectName = project.name.toLowerCase(Locale.ROOT)
val variantCapped = name.capitalize(Locale.ROOT)
val variant = name.toLowerCase(Locale.ROOT)
tasks.getByPath(":$projectName:package$variantCapped").doLast {
val apkDir = if (properties["android.injected.invoked.from.ide"] == "true")
"intermediates" else "outputs"
val apk = File(buildDir, "${apkDir}/apk/${variant}/$projectName-${variant}.apk")
val apk = outputs.files.asFileTree.filter { it.name.endsWith(".apk") }.singleFile
val comment = "version=${Config.version}\nversionCode=${Config.versionCode}"
addComment(apk, signingConfig, android.defaultConfig.minSdk!!, comment)
}
@@ -270,27 +269,20 @@ fun Project.setupStub() {
commandLine(aapt, "optimize", "-o", apkTmp, "--collapse-resource-names", apk)
}
val buffer = ByteArrayOutputStream()
apkTmp.inputStream().use {
object : GZIPOutputStream(buffer) {
init {
def.setLevel(Deflater.BEST_COMPRESSION)
}
}.use { o ->
it.transferTo(o)
val bos = ByteArrayOutputStream()
ZipFile(apkTmp).use { src ->
ZipOutputStream(apk.outputStream()).use {
it.setLevel(Deflater.BEST_COMPRESSION)
it.putNextEntry(ZipEntry("AndroidManifest.xml"))
src.getInputStream(src.getEntry("AndroidManifest.xml")).transferTo(it)
it.closeEntry()
}
}
ZipFile(apkTmp).use { o ->
ZipOutputStream(apk.outputStream()).use { n ->
n.setLevel(Deflater.BEST_COMPRESSION)
n.putNextEntry(ZipEntry("AndroidManifest.xml"))
o.getInputStream(o.getEntry("AndroidManifest.xml")).transferTo(n)
n.closeEntry()
n.finish()
DeflaterOutputStream(bos, Deflater(Deflater.BEST_COMPRESSION)).use {
src.getInputStream(src.getEntry("resources.arsc")).transferTo(it)
}
}
apkTmp.delete()
genEncryptedResources(ByteArrayInputStream(buffer.toByteArray()), outSrcDir)
genEncryptedResources(ByteArrayInputStream(bos.toByteArray()), outSrcDir)
}
}
registerJavaGeneratingTask(genSrcTask, outSrcDir)

View File

@@ -1,5 +1,13 @@
# Magisk Changelog
### v25.2
- [MagiskInit] Fix a potential issue when stub cpio is used
- [MagiskInit] Fix reboot to recovery when stub cpio is used
- [MagiskInit] Fix sepolicy.rules symlink for rootfs devices
- [General] Better data encryption detection
- [General] Move the whole logging infrastructure into Rust
### v25.1
- [MagiskBoot] Fix ramdisk backup being incorrectly skipped

11
docs/releases/25200.md Normal file
View File

@@ -0,0 +1,11 @@
## 2022.7.20 Magisk v25.2
Maintenance release fixing various issues.
- [MagiskInit] Fix a potential issue when stub cpio is used
- [MagiskInit] Fix reboot to recovery when stub cpio is used
- [MagiskInit] Fix sepolicy.rules symlink for rootfs devices
- [General] Better data encryption detection
- [General] Move the whole logging infrastructure into Rust
### Full Changelog: [here](https://topjohnwu.github.io/Magisk/changes.html)

View File

@@ -1,5 +1,6 @@
# Release Notes
- [v25.2](25200.md)
- [v25.1](25100.md)
- [v25.0](25000.md)
- [v24.3](24300.md)

View File

@@ -27,6 +27,6 @@ android.injected.testOnly=false
android.nonTransitiveRClass=true
# Magisk
magisk.stubVersion=32
magisk.versionCode=25100
magisk.ondkVersion=r24.1
magisk.stubVersion=33
magisk.versionCode=25200
magisk.ondkVersion=r24.2

34
native/README.md Normal file
View File

@@ -0,0 +1,34 @@
# Native Development
## Prerequisite
Install the NDK required to build and develop Magisk with `./build.py ndk`. The NDK will be installed to `$ANDROID_SDK_ROOT/ndk/magisk`. You don't need to manually install a Rust toolchain with `rustup`, as the NDK installed already has a Rust toolchain bundled.
## Code Paths
- `jni`: Magisk's code in C++
- `jni/external`: external dependencies, mostly submodules
- `rust`: Magisk's code in Rust
- `src`: irrelevant, only exists to setup a native Android Studio project
## Build Configs
All C/C++ code and its dependencies are built with [`ndk-build`](https://developer.android.com/ndk/guides/ndk-build) and configured with several `*.mk` files scatterred in many places.
The `rust` folder is a proper Cargo workspace, and all Rust code is built with `cargo` just like any other Rust projects.
## Rust + C/C++
To reduce complexity involved in linking, all Rust code is built as `staticlib` and linked to C++ targets to ensure our final product is built with an officially supported NDK build system. Each C++ target can at most link to **one** Rust `staticlib` or else multiple definitions error will occur.
We use the [`cxx`](https://cxx.rs) project for interop between Rust and C++. Although cxx supports interop in both directions, for Magisk, it is strongly advised to avoid calling C++ functions in Rust; if some functionality required in Rust is already implemented in C++, the desired solution is to port the C++ implementation into Rust and export the migrated function back to C++.
## Development / IDE
All C++ code should be recognized and properly indexed by Android Studio out of the box. For Rust:
- Install the [Rust plugin](https://www.jetbrains.com/rust/) in Android Studio
- In Preferences > Languages & Frameworks > Rust, set `$ANDROID_SDK_ROOT/ndk/magisk/toolchains/rust/bin` as the toolchain location
- Open `native/rust/Cargo.toml`, and select "Attach" in the "No Cargo projects found" banner
Note: run `./build.py binary` before developing to make sure generated code is created.

25
native/jni/Android-rs.mk Normal file
View File

@@ -0,0 +1,25 @@
LOCAL_PATH := $(call my-dir)
###########################
# Rust compilation outputs
###########################
include $(CLEAR_VARS)
LOCAL_MODULE := magisk-rs
LOCAL_SRC_FILES := ../out/$(TARGET_ARCH_ABI)/libmagisk-rs.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := boot-rs
LOCAL_SRC_FILES := ../out/$(TARGET_ARCH_ABI)/libmagiskboot-rs.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := init-rs
LOCAL_SRC_FILES := ../out/$(TARGET_ARCH_ABI)/libmagiskinit-rs.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := policy-rs
LOCAL_SRC_FILES := ../out/$(TARGET_ARCH_ABI)/libmagiskpolicy-rs.a
include $(PREBUILT_STATIC_LIBRARY)

View File

@@ -14,7 +14,8 @@ LOCAL_STATIC_LIBRARIES := \
libsystemproperties \
libphmap \
libxhook \
libmincrypt
libmincrypt \
libmagisk-rs
LOCAL_SRC_FILES := \
core/applets.cpp \
@@ -68,7 +69,8 @@ LOCAL_STATIC_LIBRARIES := \
libbase \
libcompat \
libpolicy \
libxz
libxz \
libinit-rs
LOCAL_SRC_FILES := \
init/init.cpp \
@@ -95,7 +97,8 @@ LOCAL_STATIC_LIBRARIES := \
libbz2 \
libfdt \
libz \
libzopfli
libzopfli \
libboot-rs
LOCAL_SRC_FILES := \
boot/main.cpp \
@@ -119,7 +122,8 @@ LOCAL_MODULE := magiskpolicy
LOCAL_STATIC_LIBRARIES := \
libbase \
libbase \
libpolicy
libpolicy \
libpolicy-rs
LOCAL_SRC_FILES := sepolicy/main.cpp
@@ -135,7 +139,8 @@ LOCAL_STATIC_LIBRARIES := \
libbase \
libcompat \
libnanopb \
libsystemproperties
libsystemproperties \
libmagisk-rs
LOCAL_SRC_FILES := \
core/applet_stub.cpp \
@@ -181,6 +186,7 @@ LOCAL_SRC_FILES := \
sepolicy/statement.cpp
include $(BUILD_STATIC_LIBRARY)
include jni/Android-rs.mk
include jni/base/Android.mk
include jni/external/Android.mk

View File

@@ -15,7 +15,8 @@ LOCAL_SRC_FILES := \
selinux.cpp \
logging.cpp \
xwrap.cpp \
stream.cpp
stream.cpp \
../external/cxx-rs/src/cxx.cc
include $(BUILD_STATIC_LIBRARY)
# All static executables should link with libcompat

View File

@@ -6,7 +6,7 @@
#undef _FORTIFY_SOURCE
extern int __vloge(const char* fmt, va_list ap);
extern void __vloge(const char* fmt, va_list ap);
static inline __noreturn __printflike(1, 2) void __fortify_fatal(const char* fmt, ...) {
va_list args;

View File

@@ -5,3 +5,4 @@
#include "../files.hpp"
#include "../misc.hpp"
#include "../logging.hpp"
#include <base-rs.hpp>

View File

@@ -1,62 +1,75 @@
#include <cstdio>
#include <cstdlib>
#include <flags.h>
#include <android/log.h>
#include "logging.hpp"
#include <flags.h>
#include <base.hpp>
// Just need to include it somewhere
#include <base-rs.cpp>
using namespace std;
int nop_log(const char *, va_list) { return 0; }
void nop_ex(int) {}
log_callback log_cb = {
.d = nop_log,
.i = nop_log,
.w = nop_log,
.e = nop_log,
.ex = nop_ex
};
void no_logging() {
log_cb.d = nop_log;
log_cb.i = nop_log;
log_cb.w = nop_log;
log_cb.e = nop_log;
log_cb.ex = nop_ex;
static int fmt_and_log_with_rs(LogLevel level, const char *fmt, va_list ap) {
char buf[4096];
int ret = vsnprintf(buf, sizeof(buf), fmt, ap);
log_with_rs(level, rust::Str(buf, ret));
return ret;
}
static int vprintfe(const char *fmt, va_list ap) {
return vfprintf(stderr, fmt, ap);
int (*cpp_logger)(LogLevel level, const char *fmt, va_list ap) = fmt_and_log_with_rs;
// Used to override external C library logging
extern "C" int magisk_log_print(int prio, const char *tag, const char *fmt, ...) {
LogLevel level;
switch (prio) {
case ANDROID_LOG_DEBUG:
level = LogLevel::Debug;
break;
case ANDROID_LOG_INFO:
level = LogLevel::Info;
break;
case ANDROID_LOG_WARN:
level = LogLevel::Warn;
break;
case ANDROID_LOG_ERROR:
level = LogLevel::Error;
break;
default:
return 0;
}
char fmt_buf[4096];
auto len = strlcpy(fmt_buf, tag, sizeof(fmt_buf));
// Prevent format specifications in the tag
std::replace(fmt_buf, fmt_buf + len, '%', '_');
snprintf(fmt_buf + len, sizeof(fmt_buf) - len, ": %s", fmt);
va_list argv;
va_start(argv, fmt);
int ret = cpp_logger(level, fmt_buf, argv);
va_end(argv);
return ret;
}
void cmdline_logging() {
log_cb.d = vprintfe;
log_cb.i = vprintf;
log_cb.w = vprintfe;
log_cb.e = vprintfe;
log_cb.ex = exit;
}
#define LOG_BODY(prio) { \
#define LOG_BODY(level) { \
va_list argv; \
va_start(argv, fmt); \
log_cb.prio(fmt, argv); \
cpp_logger(LogLevel::level, fmt, argv); \
va_end(argv); \
}
// LTO will optimize out the NOP function
#if MAGISK_DEBUG
void LOGD(const char *fmt, ...) { LOG_BODY(d) }
void LOGD(const char *fmt, ...) { LOG_BODY(Debug) }
#else
void LOGD(const char *fmt, ...) {}
#endif
void LOGI(const char *fmt, ...) { LOG_BODY(i) }
void LOGW(const char *fmt, ...) { LOG_BODY(w) }
void LOGE(const char *fmt, ...) { LOG_BODY(e); log_cb.ex(EXIT_FAILURE); }
void LOGI(const char *fmt, ...) { LOG_BODY(Info) }
void LOGW(const char *fmt, ...) { LOG_BODY(Warn) }
void LOGE(const char *fmt, ...) { LOG_BODY(Error) }
// Export raw symbol to fortify compat
extern "C" int __vloge(const char* fmt, va_list ap) {
return log_cb.e(fmt, ap);
extern "C" void __vloge(const char* fmt, va_list ap) {
cpp_logger(LogLevel::Error, fmt, ap);
}

View File

@@ -3,24 +3,12 @@
#include <cerrno>
#include <cstdarg>
struct log_callback {
int (*d)(const char* fmt, va_list ap);
int (*i)(const char* fmt, va_list ap);
int (*w)(const char* fmt, va_list ap);
int (*e)(const char* fmt, va_list ap);
void (*ex)(int code);
};
#include <base-rs.hpp>
extern log_callback log_cb;
extern int (*cpp_logger)(LogLevel level, const char *fmt, va_list ap);
void LOGD(const char *fmt, ...) __printflike(1, 2);
void LOGI(const char *fmt, ...) __printflike(1, 2);
void LOGW(const char *fmt, ...) __printflike(1, 2);
void LOGE(const char *fmt, ...) __printflike(1, 2);
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s\n", ##args, errno, std::strerror(errno))
int nop_log(const char *, va_list);
void nop_ex(int);
void no_logging();
void cmdline_logging();

View File

@@ -188,7 +188,7 @@ static bool check_data() {
return false;
auto crypto = getprop("ro.crypto.state");
if (!crypto.empty()) {
if (crypto == "unencrypted") {
if (crypto != "encrypted") {
// Unencrypted, we can directly access data
return true;
} else {

View File

@@ -20,7 +20,6 @@ void unlock_blocks();
void reboot();
void start_log_daemon();
void setup_logfile(bool reset);
void magisk_logging();
std::string read_certificate(int fd, int version = -1);
// Module stuffs

View File

@@ -11,6 +11,8 @@
#include <resetprop.hpp>
#include <flags.h>
#include <core-rs.cpp>
#include "core.hpp"
using namespace std;

View File

@@ -35,7 +35,7 @@ void setup_logfile(bool reset) {
}
// Maximum message length for pipes to transfer atomically
#define MAX_MSG_LEN (PIPE_BUF - sizeof(log_meta))
#define MAX_MSG_LEN (int) (PIPE_BUF - sizeof(log_meta))
static void *logfile_writer(void *arg) {
int pipefd = (long) arg;
@@ -124,11 +124,11 @@ static void *logfile_writer(void *arg) {
}
}
int magisk_log(int prio, const char *fmt, va_list ap) {
char buf[MAX_MSG_LEN + 1];
int len = vsnprintf(buf, sizeof(buf), fmt, ap);
void magisk_log_write(int prio, const char *msg, int len) {
if (logd_fd >= 0) {
// Truncate
len = std::min(MAX_MSG_LEN, len);
log_meta meta = {
.prio = prio,
.len = len,
@@ -139,7 +139,7 @@ int magisk_log(int prio, const char *fmt, va_list ap) {
iovec iov[2];
iov[0].iov_base = &meta;
iov[0].iov_len = sizeof(meta);
iov[1].iov_base = buf;
iov[1].iov_base = (void *) msg;
iov[1].iov_len = len;
if (writev(logd_fd, iov, 2) < 0) {
@@ -147,41 +147,6 @@ int magisk_log(int prio, const char *fmt, va_list ap) {
close(logd_fd.exchange(-1));
}
}
__android_log_write(prio, "Magisk", buf);
return len;
}
// Used to override external C library logging
extern "C" int magisk_log_print(int prio, const char *tag, const char *fmt, ...) {
char buf[4096];
auto len = strlcpy(buf, tag, sizeof(buf));
// Prevent format specifications in the tag
std::replace(buf, buf + len, '%', '_');
snprintf(buf + len, sizeof(buf) - len, ": %s", fmt);
va_list argv;
va_start(argv, fmt);
int ret = magisk_log(prio, buf, argv);
va_end(argv);
return ret;
}
#define mlog(prio) [](auto fmt, auto ap){ return magisk_log(ANDROID_LOG_##prio, fmt, ap); }
void magisk_logging() {
log_cb.d = mlog(DEBUG);
log_cb.i = mlog(INFO);
log_cb.w = mlog(WARN);
log_cb.e = mlog(ERROR);
log_cb.ex = nop_ex;
}
#define alog(prio) [](auto fmt, auto ap){ return __android_log_vprint(ANDROID_LOG_##prio, "Magisk", fmt, ap); }
void android_logging() {
log_cb.d = alog(DEBUG);
log_cb.i = alog(INFO);
log_cb.w = alog(WARN);
log_cb.e = alog(ERROR);
log_cb.ex = nop_ex;
}
void start_log_daemon() {

View File

@@ -127,6 +127,7 @@ int magisk_main(int argc, char *argv[]) {
#if 0
/* Entry point for testing stuffs */
else if (argv[1] == "--test"sv) {
rust_test_entry();
return 0;
}
#endif

View File

@@ -103,8 +103,10 @@ int get_manager(int user_id, string *pkg, bool install) {
snprintf(app_path, sizeof(app_path),
"%s/%d/%s/dyn/current.apk", APP_DATA_DIR, u, mgr_pkg->data());
int dyn = open(app_path, O_RDONLY | O_CLOEXEC);
if (dyn < 0)
if (dyn < 0) {
LOGW("pkg: no dyn APK, ignore\n");
return false;
}
bool mismatch = default_cert && read_certificate(dyn, MAGISK_VER_CODE) != *default_cert;
close(dyn);
if (mismatch) {
@@ -270,7 +272,8 @@ int get_manager(int user_id, string *pkg, bool install) {
install_stub();
not_found:
LOGW("pkg: cannot find manager for user=[%d]\n", user_id);
const char *name = mgr_pkg->empty() ? JAVA_PACKAGE_NAME : mgr_pkg->data();
LOGW("pkg: cannot find %s for user=[%d]\n", name, user_id);
if (pkg) pkg->clear();
return -1;
}

1
native/jni/external/cxx-rs vendored Submodule

View File

@@ -8,6 +8,7 @@
#include <functional>
#include <socket.hpp>
#include <core-rs.hpp>
#define AID_ROOT 0
#define AID_SHELL 2000
@@ -80,8 +81,7 @@ void exec_task(std::function<void()> &&task);
// Logging
extern std::atomic<int> logd_fd;
int magisk_log(int prio, const char *fmt, va_list ap);
void android_logging();
extern "C" void magisk_log_write(int prio, const char *msg, int len);
// Daemon handlers
void post_fs_data(int client);

View File

@@ -118,11 +118,18 @@ static bool check_key_combo() {
}
static FILE *kmsg;
static char kmsg_buf[4096];
static int vprintk(const char *fmt, va_list ap) {
vsnprintf(kmsg_buf + 12, sizeof(kmsg_buf) - 12, fmt, ap);
return fprintf(kmsg, "%s", kmsg_buf);
extern "C" void klog_write(const char *msg, int len) {
fprintf(kmsg, "%.*s", len, msg);
}
static int klog_with_rs(LogLevel level, const char *fmt, va_list ap) {
char buf[4096];
strlcpy(buf, "magiskinit: ", sizeof(buf));
int len = vsnprintf(buf + 12, sizeof(buf) - 12, fmt, ap) + 12;
log_with_rs(level, rust::Str(buf, len));
return len;
}
void setup_klog() {
// Shut down first 3 fds
int fd;
@@ -149,9 +156,8 @@ void setup_klog() {
kmsg = fdopen(fd, "w");
setbuf(kmsg, nullptr);
log_cb.d = log_cb.i = log_cb.w = log_cb.e = vprintk;
log_cb.ex = nop_ex;
strcpy(kmsg_buf, "magiskinit: ");
rust::setup_klog();
cpp_logger = klog_with_rs;
// Disable kmsg rate limiting
if (FILE *rate = fopen("/proc/sys/kernel/printk_devkmsg", "w")) {

View File

@@ -22,6 +22,8 @@
#include "init.hpp"
#include <init-rs.cpp>
using namespace std;
bool unxz(int fd, const uint8_t *buf, size_t size) {
@@ -57,6 +59,20 @@ static int dump_bin(const uint8_t *buf, size_t sz, const char *path, mode_t mode
return 0;
}
void restore_ramdisk_init() {
unlink("/init");
const char *orig_init = backup_init();
if (access(orig_init, F_OK) == 0) {
xrename(orig_init, "/init");
} else {
// If the backup init is missing, this means that the boot ramdisk
// was created from scratch, and the real init is in a separate CPIO,
// which is guaranteed to be placed at /system/bin/init.
xsymlink(INIT_PATH, "/init");
}
}
int dump_manager(const char *path, mode_t mode) {
return dump_bin(manager_xz, sizeof(manager_xz), path, mode);
}
@@ -70,7 +86,7 @@ public:
using BaseInit::BaseInit;
void start() override {
LOGD("Ramdisk is recovery, abort\n");
rename(backup_init(), "/init");
restore_ramdisk_init();
rm_rf("/.backup");
exec_init();
}

View File

@@ -1,4 +1,5 @@
#include <base.hpp>
#include <init-rs.hpp>
using kv_pairs = std::vector<std::pair<std::string, std::string>>;
@@ -23,6 +24,7 @@ struct BootConfig {
};
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
#define INIT_PATH "/system/bin/init"
extern std::vector<std::string> mount_list;
@@ -32,6 +34,7 @@ void load_kernel_info(BootConfig *config);
bool check_two_stage();
void setup_klog();
const char *backup_init();
void restore_ramdisk_init();
int dump_manager(const char *path, mode_t mode);
int dump_preload(const char *path, mode_t mode);

View File

@@ -202,13 +202,25 @@ persist:
success:
// Create symlinks so we don't need to go through this logic again
strcpy(p, "/sepolicy.rules");
xsymlink(custom_rules_dir.data(), path);
if (char *rel = strstr(custom_rules_dir.data(), MIRRDIR)) {
// Create symlink with relative path
char s[128];
s[0] = '.';
strlcpy(s + 1, rel + sizeof(MIRRDIR) - 1, sizeof(s) - 1);
xsymlink(s, path);
} else {
xsymlink(custom_rules_dir.data(), path);
}
}
bool LegacySARInit::mount_system_root() {
backup_files();
LOGD("Mounting system_root\n");
// there's no /dev in stub cpio
xmkdir("/dev", 0777);
strcpy(blk_info.block_dev, "/dev/root");
do {
@@ -250,7 +262,6 @@ mount_root:
switch_root("/system_root");
// Make dev writable
xmkdir("/dev", 0755);
xmount("tmpfs", "/dev", "tmpfs", 0, "mode=755");
mount_list.emplace_back("/dev");

View File

@@ -8,7 +8,6 @@
using namespace std;
#define INIT_PATH "/system/bin/init"
#define REDIR_PATH "/data/magiskinit"
void FirstStageInit::prepare() {
@@ -16,16 +15,7 @@ void FirstStageInit::prepare() {
xmount("tmpfs", "/data", "tmpfs", 0, "mode=755");
cp_afc("/init" /* magiskinit */, REDIR_PATH);
unlink("/init");
const char *orig_init = backup_init();
if (access(orig_init, F_OK) == 0) {
xrename(orig_init, "/init");
} else {
// If the backup init is missing, this means that the boot ramdisk
// was created from scratch, and the real init is in a separate CPIO,
// which is guaranteed to be placed at /system/bin/init.
xsymlink(INIT_PATH, "/init");
}
restore_ramdisk_init();
{
auto init = mmap_data("/init", true);
@@ -39,6 +29,7 @@ void FirstStageInit::prepare() {
}
void LegacySARInit::first_stage_prep() {
xmkdir("/data", 0755);
xmount("tmpfs", "/data", "tmpfs", 0, "mode=755");
// Patch init binary

View File

@@ -75,8 +75,6 @@ PB_BIND(PersistentProperties_PersistentPropertyRecord, PersistentProperties_Pers
* End of auto generated code
* ***************************/
bool use_pb = false;
static bool name_decode(pb_istream_t *stream, const pb_field_t *field, void **arg) {
string &name = *static_cast<string *>(*arg);
name.resize(stream->bytes_left);
@@ -154,8 +152,18 @@ static bool file_getprop(const char *name, char *value) {
return value[0] != '\0';
}
static bool check_pb() {
static bool checked = false;
static bool use_pb = false;
if (!checked) {
checked = true;
use_pb = access(PERSISTENT_PROPERTY_DIR "/persistent_properties", R_OK) == 0;
}
return use_pb;
}
void persist_getprops(prop_cb *prop_cb) {
if (use_pb) {
if (check_pb()) {
pb_getprop(prop_cb);
} else {
auto dir = open_dir(PERSISTENT_PROPERTY_DIR);
@@ -180,7 +188,7 @@ private:
};
string persist_getprop(const char *name) {
if (use_pb) {
if (check_pb()) {
auto prop = match_prop_name(name);
pb_getprop(&prop);
if (prop.value[0]) {
@@ -199,7 +207,7 @@ string persist_getprop(const char *name) {
}
bool persist_deleteprop(const char *name) {
if (use_pb) {
if (check_pb()) {
prop_list list;
prop_collector collector(list);
persist_getprops(&collector);

View File

@@ -16,8 +16,6 @@ struct prop_cb {
}
};
extern bool use_pb;
using prop_list = std::map<std::string, std::string>;
struct prop_collector : prop_cb {

View File

@@ -13,8 +13,6 @@
using namespace std;
static bool verbose = false;
#ifdef APPLET_STUB_MAIN
#define system_property_set __system_property_set
#define system_property_find __system_property_find
@@ -240,7 +238,6 @@ struct resetprop : public sysprop {
static sysprop_stub *get_impl() {
static sysprop_stub *impl = nullptr;
if (impl == nullptr) {
use_pb = access(PERSISTENT_PROPERTY_DIR "/persistent_properties", R_OK) == 0;
#ifdef APPLET_STUB_MAIN
if (__system_properties_init()) {
LOGE("resetprop: __system_properties_init error\n");
@@ -297,10 +294,9 @@ void load_prop_file(const char *filename, bool prop_svc) {
}
int resetprop_main(int argc, char *argv[]) {
log_cb.d = [](auto fmt, auto ap) -> int { return verbose ? vfprintf(stderr, fmt, ap) : 0; };
bool prop_svc = true;
bool persist = false;
bool verbose = false;
char *argv0 = argv[0];
--argc;
@@ -340,6 +336,8 @@ int resetprop_main(int argc, char *argv[]) {
++argv;
}
set_log_level_state(LogLevel::Debug, verbose);
switch (argc) {
case 0:
print_props(persist);

View File

@@ -6,8 +6,7 @@ using namespace std;
void sepolicy::magisk_rules() {
// Temp suppress warnings
auto bak = log_cb.w;
log_cb.w = nop_log;
set_log_level_state(LogLevel::Warn, false);
// This indicates API 26+
bool new_rules = exists("untrusted_app_25");
@@ -196,5 +195,5 @@ void sepolicy::magisk_rules() {
impl->strip_dontaudit();
#endif
log_cb.w = bak;
set_log_level_state(LogLevel::Warn, true);
}

View File

@@ -311,7 +311,7 @@ void su_daemon_handler(int client, const sock_cred *cred) {
LOGD("su: fork handler\n");
// Abort upon any error occurred
log_cb.ex = exit;
exit_on_error(true);
// ack
write_int(client, 0);

View File

@@ -17,17 +17,6 @@ using namespace std;
void *self_handle = nullptr;
static int zygisk_log(int prio, const char *fmt, va_list ap);
#define zlog(prio) [](auto fmt, auto ap){ return zygisk_log(ANDROID_LOG_##prio, fmt, ap); }
static void zygisk_logging() {
log_cb.d = zlog(DEBUG);
log_cb.i = zlog(INFO);
log_cb.w = zlog(WARN);
log_cb.e = zlog(ERROR);
log_cb.ex = nop_ex;
}
// Make sure /proc/self/environ is sanitized
// Filter env and reset MM_ENV_END
static void sanitize_environ() {
@@ -114,7 +103,7 @@ static void zygisk_init() {
// The following code runs in zygote/app process
static int zygisk_log(int prio, const char *fmt, va_list ap) {
extern "C" void zygisk_log_write(int prio, const char *msg, int len) {
// If we don't have log pipe set, ask magiskd for it
// This could happen multiple times in zygote because it was closed to prevent crashing
if (logd_fd < 0) {
@@ -139,13 +128,12 @@ static int zygisk_log(int prio, const char *fmt, va_list ap) {
sigaddset(&mask, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &mask, &orig_mask);
}
int ret = magisk_log(prio, fmt, ap);
magisk_log_write(prio, msg, len);
if (sig) {
timespec ts{};
sigtimedwait(&mask, nullptr, &ts);
pthread_sigmask(SIG_SETMASK, &orig_mask, nullptr);
}
return ret;
}
static inline bool should_load_modules(uint32_t flags) {

1
native/rust/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
target/

103
native/rust/Cargo.lock generated Normal file
View File

@@ -0,0 +1,103 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "base"
version = "0.1.0"
dependencies = [
"cxx",
]
[[package]]
name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cxx"
version = "1.0.69"
dependencies = [
"cc",
"cxxbridge-flags",
"cxxbridge-macro",
]
[[package]]
name = "cxxbridge-flags"
version = "1.0.69"
[[package]]
name = "cxxbridge-macro"
version = "1.0.69"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "magisk"
version = "0.1.0"
dependencies = [
"base",
"cxx",
]
[[package]]
name = "magiskboot"
version = "0.1.0"
dependencies = [
"base",
]
[[package]]
name = "magiskinit"
version = "0.1.0"
dependencies = [
"base",
"cxx",
]
[[package]]
name = "magiskpolicy"
version = "0.1.0"
dependencies = [
"base",
]
[[package]]
name = "proc-macro2"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"

26
native/rust/Cargo.toml Normal file
View File

@@ -0,0 +1,26 @@
[workspace]
members = [
"base",
"boot",
"core",
"init",
"sepolicy",
]
[profile.dev]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = true
[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = true
[patch.crates-io]
cxx = { path = "../jni/external/cxx-rs" }

View File

@@ -0,0 +1,7 @@
[package]
name = "base"
version = "0.1.0"
edition = "2021"
[dependencies]
cxx = "1.0.69"

View File

@@ -0,0 +1,25 @@
#![feature(format_args_nl)]
pub use logging::*;
pub use misc::*;
mod logging;
mod misc;
#[cxx::bridge]
pub mod ffi {
#[derive(Copy, Clone)]
pub enum LogLevel {
Error,
Warn,
Info,
Debug,
}
extern "Rust" {
fn log_with_rs(level: LogLevel, msg: &str);
fn exit_on_error(b: bool);
fn set_log_level_state(level: LogLevel, enabled: bool);
fn cmdline_logging();
}
}

View File

@@ -0,0 +1,139 @@
use std::fmt::Arguments;
use std::io::{stderr, stdout, Write};
use std::process::exit;
use crate::ffi::LogLevel;
// Ugly hack to avoid using enum
#[allow(non_snake_case, non_upper_case_globals)]
mod LogFlag {
pub const DisableError: u32 = 0x1;
pub const DisableWarn: u32 = 0x2;
pub const DisableInfo: u32 = 0x4;
pub const DisableDebug: u32 = 0x8;
pub const ExitOnError: u32 = 0x10;
}
// We don't need to care about thread safety, because all
// logger changes will only happen on the main thread.
pub static mut LOGGER: Logger = Logger {
fmt: |_, _| {},
write: |_, _| {},
flags: 0,
};
#[derive(Copy, Clone)]
pub struct Logger {
pub fmt: fn(level: LogLevel, args: Arguments),
pub write: fn(level: LogLevel, msg: &[u8]),
pub flags: u32,
}
pub fn exit_on_error(b: bool) {
unsafe {
if b {
LOGGER.flags |= LogFlag::ExitOnError;
} else {
LOGGER.flags &= !LogFlag::ExitOnError;
}
}
}
impl LogLevel {
fn to_disable_flag(&self) -> u32 {
match *self {
LogLevel::Error => LogFlag::DisableError,
LogLevel::Warn => LogFlag::DisableWarn,
LogLevel::Info => LogFlag::DisableInfo,
LogLevel::Debug => LogFlag::DisableDebug,
_ => 0
}
}
}
pub fn set_log_level_state(level: LogLevel, enabled: bool) {
let flag = level.to_disable_flag();
unsafe {
if enabled {
LOGGER.flags &= !flag
} else {
LOGGER.flags |= flag
}
}
}
pub fn log_with_rs(level: LogLevel, msg: &str) {
let logger = unsafe { LOGGER };
if (logger.flags & level.to_disable_flag()) != 0 {
return;
}
(logger.write)(level, msg.as_bytes());
if level == LogLevel::Error && (logger.flags & LogFlag::ExitOnError) != 0 {
exit(1);
}
}
pub fn log_impl(level: LogLevel, args: Arguments) {
let logger = unsafe { LOGGER };
if (logger.flags & level.to_disable_flag()) != 0 {
return;
}
(logger.fmt)(level, args);
if level == LogLevel::Error && (logger.flags & LogFlag::ExitOnError) != 0 {
exit(1);
}
}
pub fn cmdline_logging() {
fn print(level: LogLevel, args: Arguments) {
if level == LogLevel::Info {
print!("{}", args);
} else {
eprint!("{}", args);
}
}
fn write(level: LogLevel, msg: &[u8]) {
if level == LogLevel::Info {
stdout().write_all(msg).ok();
} else {
stderr().write_all(msg).ok();
}
}
let logger = Logger {
fmt: print,
write,
flags: LogFlag::ExitOnError,
};
unsafe {
LOGGER = logger;
}
}
#[macro_export]
macro_rules! error {
($($arg:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Error, format_args_nl!($($arg)+)))
}
#[macro_export]
macro_rules! warn {
($($arg:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Warn, format_args_nl!($($arg)+)))
}
#[macro_export]
macro_rules! info {
($($arg:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Info, format_args_nl!($($arg)+)))
}
#[cfg(debug_assertions)]
#[macro_export]
macro_rules! debug {
($($arg:tt)+) => ($crate::log_impl($crate::ffi::LogLevel::Debug, format_args_nl!($($arg)+)))
}
#[cfg(not(debug_assertions))]
#[macro_export]
macro_rules! debug {
($($arg:tt)+) => ()
}

View File

@@ -0,0 +1,41 @@
use std::cmp::min;
use std::fmt;
use std::fmt::Arguments;
struct BufFmtWriter<'a> {
buf: &'a mut [u8],
used: usize,
}
impl<'a> BufFmtWriter<'a> {
fn new(buf: &'a mut [u8]) -> Self {
BufFmtWriter { buf, used: 0 }
}
}
impl<'a> fmt::Write for BufFmtWriter<'a> {
// The buffer should always be null terminated
fn write_str(&mut self, s: &str) -> fmt::Result {
if self.used >= self.buf.len() - 1 {
// Silent truncate
return Ok(());
}
let remain = &mut self.buf[self.used..];
let s_bytes = s.as_bytes();
let copied = min(s_bytes.len(), remain.len() - 1);
remain[..copied].copy_from_slice(&s_bytes[..copied]);
self.used += copied;
self.buf[self.used] = b'\0';
// Silent truncate
Ok(())
}
}
pub fn fmt_to_buf(buf: &mut [u8], args: Arguments) -> usize {
let mut w = BufFmtWriter::new(buf);
if let Ok(()) = fmt::write(&mut w, args) {
w.used
} else {
0
}
}

View File

@@ -0,0 +1,10 @@
[package]
name = "magiskboot"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["staticlib"]
[dependencies]
base = { path = "../base" }

View File

@@ -0,0 +1 @@
pub use base;

View File

@@ -0,0 +1,11 @@
[package]
name = "magisk"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["staticlib"]
[dependencies]
base = { path = "../base" }
cxx = "1.0.69"

View File

@@ -0,0 +1,16 @@
pub use base;
pub use logging::*;
mod logging;
#[cxx::bridge]
pub mod ffi {
extern "Rust" {
fn rust_test_entry();
fn android_logging();
fn magisk_logging();
fn zygisk_logging();
}
}
fn rust_test_entry() {}

View File

@@ -0,0 +1,112 @@
use std::fmt::Arguments;
use base::*;
use base::ffi::LogLevel;
#[allow(dead_code, non_camel_case_types)]
#[repr(i32)]
enum ALogPriority {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT,
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT,
}
extern "C" {
fn __android_log_write(prio: i32, tag: *const u8, msg: *const u8);
fn magisk_log_write(prio: i32, msg: *const u8, len: i32);
fn zygisk_log_write(prio: i32, msg: *const u8, len: i32);
}
fn level_to_prio(level: LogLevel) -> i32 {
match level {
LogLevel::Error => ALogPriority::ANDROID_LOG_ERROR as i32,
LogLevel::Warn => ALogPriority::ANDROID_LOG_WARN as i32,
LogLevel::Info => ALogPriority::ANDROID_LOG_INFO as i32,
LogLevel::Debug => ALogPriority::ANDROID_LOG_DEBUG as i32,
_ => 0
}
}
pub fn android_logging() {
fn android_log_fmt(level: LogLevel, args: Arguments) {
let mut buf: [u8; 4096] = [0; 4096];
fmt_to_buf(&mut buf, args);
unsafe {
__android_log_write(level_to_prio(level), b"Magisk\0".as_ptr(), buf.as_ptr());
}
}
fn android_log_write(level: LogLevel, msg: &[u8]) {
unsafe {
__android_log_write(level_to_prio(level), b"Magisk\0".as_ptr(), msg.as_ptr());
}
}
let logger = Logger {
fmt: android_log_fmt,
write: android_log_write,
flags: 0,
};
exit_on_error(false);
unsafe {
LOGGER = logger;
}
}
pub fn magisk_logging() {
fn magisk_fmt(level: LogLevel, args: Arguments) {
let mut buf: [u8; 4096] = [0; 4096];
let len = fmt_to_buf(&mut buf, args);
unsafe {
__android_log_write(level_to_prio(level), b"Magisk\0".as_ptr(), buf.as_ptr());
magisk_log_write(level_to_prio(level), buf.as_ptr(), len as i32);
}
}
fn magisk_write(level: LogLevel, msg: &[u8]) {
unsafe {
__android_log_write(level_to_prio(level), b"Magisk\0".as_ptr(), msg.as_ptr());
magisk_log_write(level_to_prio(level), msg.as_ptr(), msg.len() as i32);
}
}
let logger = Logger {
fmt: magisk_fmt,
write: magisk_write,
flags: 0,
};
exit_on_error(false);
unsafe {
LOGGER = logger;
}
}
pub fn zygisk_logging() {
fn zygisk_fmt(level: LogLevel, args: Arguments) {
let mut buf: [u8; 4096] = [0; 4096];
let len = fmt_to_buf(&mut buf, args);
unsafe {
__android_log_write(level_to_prio(level), b"Magisk\0".as_ptr(), buf.as_ptr());
zygisk_log_write(level_to_prio(level), buf.as_ptr(), len as i32);
}
}
fn zygisk_write(level: LogLevel, msg: &[u8]) {
unsafe {
__android_log_write(level_to_prio(level), b"Magisk\0".as_ptr(), msg.as_ptr());
zygisk_log_write(level_to_prio(level), msg.as_ptr(), msg.len() as i32);
}
}
let logger = Logger {
fmt: zygisk_fmt,
write: zygisk_write,
flags: 0,
};
exit_on_error(false);
unsafe {
LOGGER = logger;
}
}

View File

@@ -0,0 +1,11 @@
[package]
name = "magiskinit"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["staticlib"]
[dependencies]
base = { path = "../base" }
cxx = "1.0.69"

View File

@@ -0,0 +1,11 @@
pub use base;
pub use logging::*;
mod logging;
#[cxx::bridge(namespace = "rust")]
pub mod ffi2 {
extern "Rust" {
fn setup_klog();
}
}

View File

@@ -0,0 +1,37 @@
use std::fmt::Arguments;
use base::*;
use base::ffi::LogLevel;
extern "C" {
fn klog_write(msg: *const u8, len: i32);
}
pub fn setup_klog() {
const PREFIX: &[u8; 12] = b"magiskinit: ";
const PFX_LEN: usize = PREFIX.len();
fn klog_fmt(_: LogLevel, args: Arguments) {
let mut buf: [u8; 4096] = [0; 4096];
buf[..PFX_LEN].copy_from_slice(PREFIX);
let len = fmt_to_buf(&mut buf[PFX_LEN..], args) + PFX_LEN;
unsafe {
klog_write(buf.as_ptr(), len as i32);
}
}
fn klog_write_impl(_: LogLevel, msg: &[u8]) {
unsafe {
klog_write(msg.as_ptr(), msg.len() as i32);
}
}
let logger = Logger {
fmt: klog_fmt,
write: klog_write_impl,
flags: 0,
};
exit_on_error(false);
unsafe {
LOGGER = logger;
}
}

View File

@@ -0,0 +1,10 @@
[package]
name = "magiskpolicy"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["staticlib", "rlib"]
[dependencies]
base = { path = "../base" }

View File

@@ -0,0 +1 @@
pub use base;

View File

@@ -185,8 +185,8 @@ rm -f ramdisk.cpio.orig config magisk*.xz
for dt in dtb kernel_dtb extra; do
if [ -f $dt ]; then
if ! ./magiskboot dtb $dt test; then
ui_print "! Unsupported boot image $dt"
abort "! Please restore back to stock boot image"
ui_print "! Boot image $dt was patched by old (unsupported) Magisk"
abort "! Please try again with *unpatched* boot image"
fi
if ./magiskboot dtb $dt patch; then
ui_print "- Patch fstab in boot image $dt"

View File

@@ -34,7 +34,10 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
@@ -76,7 +79,9 @@ public class DownloadActivity extends Activity {
// Inject resources
try {
loadResources();
} catch (Exception ignored) {}
} catch (Exception e) {
error(e);
}
ProviderInstaller.install(this);
@@ -103,7 +108,7 @@ public class DownloadActivity extends Activity {
}
private void error(Throwable e) {
Log.e(getClass().getSimpleName(), "", e);
Log.e(getClass().getSimpleName(), Log.getStackTraceString(e));
finish();
}
@@ -157,14 +162,26 @@ public class DownloadActivity extends Activity {
}
private void decryptResources(OutputStream out) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey key = new SecretKeySpec(Bytes.key(), "AES");
IvParameterSpec iv = new IvParameterSpec(Bytes.iv());
cipher.init(Cipher.DECRYPT_MODE, key, iv);
var is = new GZIPInputStream(new CipherInputStream(
new ByteArrayInputStream(Bytes.res()), cipher));
try (is; out) {
APKInstall.transfer(is, out);
try (var zip = new ZipOutputStream(out)) {
zip.putNextEntry(new ZipEntry("resources.arsc"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey key = new SecretKeySpec(Bytes.key(), "AES");
IvParameterSpec iv = new IvParameterSpec(Bytes.iv());
cipher.init(Cipher.DECRYPT_MODE, key, iv);
var is = new InflaterInputStream(new CipherInputStream(
new ByteArrayInputStream(Bytes.res()), cipher));
try (is) {
APKInstall.transfer(is, zip);
}
zip.closeEntry();
zip.putNextEntry(new ZipEntry("AndroidManifest.xml"));
var apk = new ZipFile(getPackageResourcePath());
var xml = apk.getInputStream(apk.getEntry("AndroidManifest.xml"));
try (apk; xml) {
APKInstall.transfer(xml, zip);
}
zip.closeEntry();
}
}