├── .gitattributes
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── config.yml
├── ccache.sh
└── workflows
│ ├── build.yml
│ └── issues.yml
├── .gitignore
├── .gitmodules
├── LICENSE
├── README.MD
├── app
├── .gitignore
├── build.gradle.kts
├── proguard-rules.pro
├── shared
│ ├── .gitignore
│ ├── build.gradle.kts
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── topjohnwu
│ │ └── magisk
│ │ ├── DynAPK.java
│ │ ├── FileProvider.java
│ │ ├── ProviderInstaller.java
│ │ └── utils
│ │ ├── APKInstall.java
│ │ ├── CompoundEnumeration.java
│ │ └── DynamicClassLoader.java
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── topjohnwu
│ │ └── magisk
│ │ ├── arch
│ │ ├── BaseUIActivity.kt
│ │ ├── BaseUIComponent.kt
│ │ ├── BaseUIFragment.kt
│ │ ├── BaseViewModel.kt
│ │ ├── Queryable.kt
│ │ └── ViewEvent.kt
│ │ ├── core
│ │ ├── App.kt
│ │ ├── Config.kt
│ │ ├── Const.kt
│ │ ├── Hacks.kt
│ │ ├── Info.kt
│ │ ├── Provider.kt
│ │ ├── Receiver.kt
│ │ ├── SplashActivity.kt
│ │ ├── UpdateCheckService.kt
│ │ ├── base
│ │ │ ├── BaseActivity.kt
│ │ │ ├── BaseReceiver.kt
│ │ │ ├── BaseService.kt
│ │ │ ├── BaseWorkerWrapper.kt
│ │ │ └── PermissionRequestBuilder.kt
│ │ ├── download
│ │ │ ├── BaseDownloader.kt
│ │ │ ├── DownloadService.kt
│ │ │ ├── ManagerHandler.kt
│ │ │ ├── ModuleProcessor.kt
│ │ │ └── Subject.kt
│ │ ├── magiskdb
│ │ │ ├── BaseDao.kt
│ │ │ ├── PolicyDao.kt
│ │ │ ├── Query.kt
│ │ │ ├── SettingsDao.kt
│ │ │ └── StringDao.kt
│ │ ├── model
│ │ │ ├── UpdateInfo.kt
│ │ │ ├── module
│ │ │ │ ├── LocalModule.kt
│ │ │ │ ├── Module.kt
│ │ │ │ └── OnlineModule.kt
│ │ │ └── su
│ │ │ │ ├── SuLog.kt
│ │ │ │ └── SuPolicy.kt
│ │ ├── su
│ │ │ ├── SuCallbackHandler.kt
│ │ │ └── SuRequestHandler.kt
│ │ ├── tasks
│ │ │ ├── FlashZip.kt
│ │ │ ├── HideAPK.kt
│ │ │ ├── MagiskInstaller.kt
│ │ │ └── RepoUpdater.kt
│ │ └── utils
│ │ │ ├── AXML.kt
│ │ │ ├── BiometricHelper.kt
│ │ │ ├── IODispatcherExecutor.kt
│ │ │ ├── Keygen.kt
│ │ │ ├── Locales.kt
│ │ │ ├── MediaStoreUtils.kt
│ │ │ ├── ProgressInputStream.kt
│ │ │ ├── ShellInit.kt
│ │ │ ├── ZipUtils.kt
│ │ │ └── net
│ │ │ ├── LollipopNetworkObserver.kt
│ │ │ ├── MarshmallowNetworkObserver.kt
│ │ │ └── NetworkObserver.kt
│ │ ├── data
│ │ ├── database
│ │ │ ├── RepoDao.kt
│ │ │ └── SuLogDao.kt
│ │ ├── network
│ │ │ └── NetworkServices.kt
│ │ ├── preference
│ │ │ ├── BooleanProperty.kt
│ │ │ ├── FloatProperty.kt
│ │ │ ├── IntProperty.kt
│ │ │ ├── LongProperty.kt
│ │ │ ├── PreferenceModel.kt
│ │ │ ├── Property.kt
│ │ │ ├── StringProperty.kt
│ │ │ └── StringSetProperty.kt
│ │ └── repository
│ │ │ ├── DBConfig.kt
│ │ │ ├── LogRepository.kt
│ │ │ └── NetworkService.kt
│ │ ├── databinding
│ │ ├── AdaptersRecycler.kt
│ │ ├── BindingBoundAdapter.kt
│ │ ├── DataBindingAdapters.kt
│ │ ├── DiffObservableList.kt
│ │ ├── FilterableDiffObservableList.kt
│ │ ├── Helpers.kt
│ │ ├── ObservableHost.kt
│ │ ├── RecyclerViewItems.kt
│ │ └── RvBindingAdapter.kt
│ │ ├── di
│ │ ├── Networking.kt
│ │ └── ServiceLocator.kt
│ │ ├── events
│ │ ├── OpenInappLinkEvent.kt
│ │ ├── RebootEvent.kt
│ │ ├── SnackbarEvent.kt
│ │ ├── ViewEvents.kt
│ │ └── dialog
│ │ │ ├── BiometricEvent.kt
│ │ │ ├── DarkThemeDialog.kt
│ │ │ ├── DialogEvent.kt
│ │ │ ├── EnvFixDialog.kt
│ │ │ ├── ManagerInstallDialog.kt
│ │ │ ├── MarkDownDialog.kt
│ │ │ ├── ModuleInstallDialog.kt
│ │ │ ├── SecondSlotWarningDialog.kt
│ │ │ ├── SuperuserRevokeDialog.kt
│ │ │ └── UninstallDialog.kt
│ │ ├── ktx
│ │ ├── Dimens.kt
│ │ ├── RecyclerView.kt
│ │ ├── XAndroid.kt
│ │ ├── XBinding.kt
│ │ ├── XJava.kt
│ │ ├── XSU.kt
│ │ └── XString.kt
│ │ ├── signing
│ │ ├── ApkSignerV2.java
│ │ ├── ByteArrayStream.java
│ │ ├── CryptoUtils.java
│ │ ├── JarMap.java
│ │ ├── SignApk.java
│ │ ├── SignBoot.java
│ │ └── ZipUtils.java
│ │ ├── ui
│ │ ├── MainActivity.kt
│ │ ├── flash
│ │ │ ├── ConsoleItem.kt
│ │ │ ├── FlashFragment.kt
│ │ │ └── FlashViewModel.kt
│ │ ├── hide
│ │ │ ├── HideFragment.kt
│ │ │ ├── HideInfo.kt
│ │ │ ├── HideRvItems.kt
│ │ │ └── HideViewModel.kt
│ │ ├── home
│ │ │ ├── DeveloperItem.kt
│ │ │ ├── HomeFragment.kt
│ │ │ └── HomeViewModel.kt
│ │ ├── inflater
│ │ │ ├── LayoutInflaterFactory.kt
│ │ │ └── WindowInsetsHelper.kt
│ │ ├── install
│ │ │ ├── InstallFragment.kt
│ │ │ └── InstallViewModel.kt
│ │ ├── log
│ │ │ ├── LogFragment.kt
│ │ │ ├── LogRvItem.kt
│ │ │ └── LogViewModel.kt
│ │ ├── module
│ │ │ ├── ModuleFragment.kt
│ │ │ ├── ModuleRvItem.kt
│ │ │ └── ModuleViewModel.kt
│ │ ├── safetynet
│ │ │ ├── CheckSafetyNetEvent.kt
│ │ │ ├── SafetyNetHelper.kt
│ │ │ ├── SafetynetFragment.kt
│ │ │ └── SafetynetViewModel.kt
│ │ ├── settings
│ │ │ ├── BaseSettingsItem.kt
│ │ │ ├── SettingsFragment.kt
│ │ │ ├── SettingsItems.kt
│ │ │ └── SettingsViewModel.kt
│ │ ├── superuser
│ │ │ ├── PolicyRvItem.kt
│ │ │ ├── SuperuserFragment.kt
│ │ │ └── SuperuserViewModel.kt
│ │ ├── surequest
│ │ │ ├── SuRequestActivity.kt
│ │ │ └── SuRequestViewModel.kt
│ │ └── theme
│ │ │ ├── Theme.kt
│ │ │ ├── ThemeFragment.kt
│ │ │ └── ThemeViewModel.kt
│ │ ├── utils
│ │ ├── CachedValue.kt
│ │ ├── EndlessRecyclerScrollListener.kt
│ │ ├── HideableBehavior.kt
│ │ ├── KItemDecoration.kt
│ │ ├── MarkwonImagePlugin.kt
│ │ ├── MotionRevealHelper.kt
│ │ ├── TextHolder.kt
│ │ └── Utils.kt
│ │ └── view
│ │ ├── MagiskDialog.kt
│ │ ├── Notifications.kt
│ │ ├── Shortcuts.kt
│ │ ├── TappableHeadlineItem.kt
│ │ └── TextItem.kt
│ └── res
│ ├── anim
│ ├── fragment_enter.xml
│ ├── fragment_enter_pop.xml
│ ├── fragment_exit.xml
│ └── fragment_exit_pop.xml
│ ├── color
│ ├── color_error_transient.xml
│ ├── color_menu_tint.xml
│ ├── color_on_primary_transient.xml
│ ├── color_primary_error_transient.xml
│ ├── color_primary_transient.xml
│ ├── color_secondary_transient.xml
│ ├── color_state_primary_transient.xml
│ └── color_text_transient.xml
│ ├── drawable-nodpi
│ └── logo.png
│ ├── drawable-v23
│ └── ic_splash_activity.xml
│ ├── drawable-v26
│ ├── ic_launcher.xml
│ ├── sc_extension.xml
│ ├── sc_magiskhide.xml
│ └── sc_superuser.xml
│ ├── drawable
│ ├── avd_bug_from_filled.xml
│ ├── avd_bug_to_filled.xml
│ ├── avd_circle_check_from_filled.xml
│ ├── avd_circle_check_to_filled.xml
│ ├── avd_delete_magisk.xml
│ ├── avd_home_from_filled.xml
│ ├── avd_home_to_filled.xml
│ ├── avd_magisk_delete.xml
│ ├── avd_module_from_filled.xml
│ ├── avd_module_to_filled.xml
│ ├── avd_settings_from_filled.xml
│ ├── avd_settings_to_filled.xml
│ ├── avd_superuser_from_filled.xml
│ ├── avd_superuser_to_filled.xml
│ ├── bg_checkbox.xml
│ ├── bg_divider_rounded_on_primary.xml
│ ├── bg_line_bottom_rounded.xml
│ ├── bg_line_top_rounded.xml
│ ├── bg_selection_circle_green.xml
│ ├── bg_shadow.xml
│ ├── divider_l1.xml
│ ├── divider_l_50.xml
│ ├── ic_back_md2.xml
│ ├── ic_bug_filled_md2.xml
│ ├── ic_bug_md2.xml
│ ├── ic_bug_outlined_md2.xml
│ ├── ic_check_circle_checked_md2.xml
│ ├── ic_check_circle_md2.xml
│ ├── ic_check_circle_unchecked_md2.xml
│ ├── ic_check_md2.xml
│ ├── ic_checkbox.xml
│ ├── ic_close_md2.xml
│ ├── ic_compound_checkbox.xml
│ ├── ic_day.xml
│ ├── ic_day_night.xml
│ ├── ic_delete_md2.xml
│ ├── ic_device.xml
│ ├── ic_download_md2.xml
│ ├── ic_extension.xml
│ ├── ic_fingerprint.xml
│ ├── ic_folder_list.xml
│ ├── ic_forth_md2.xml
│ ├── ic_github.xml
│ ├── ic_hide_md2.xml
│ ├── ic_hide_select_md2.xml
│ ├── ic_home_filled_md2.xml
│ ├── ic_home_md2.xml
│ ├── ic_home_outlined_md2.xml
│ ├── ic_info.xml
│ ├── ic_install.xml
│ ├── ic_logo.xml
│ ├── ic_magisk.xml
│ ├── ic_magisk_delete.xml
│ ├── ic_magisk_outline.xml
│ ├── ic_magisk_padded.xml
│ ├── ic_magiskhide.xml
│ ├── ic_manager.xml
│ ├── ic_module_filled_md2.xml
│ ├── ic_module_md2.xml
│ ├── ic_module_outlined_md2.xml
│ ├── ic_module_storage_md2.xml
│ ├── ic_more.xml
│ ├── ic_night.xml
│ ├── ic_notifications_md2.xml
│ ├── ic_order_date.xml
│ ├── ic_order_name.xml
│ ├── ic_paint.xml
│ ├── ic_patreon.xml
│ ├── ic_paypal.xml
│ ├── ic_refresh_data_md2.xml
│ ├── ic_refresh_safetynet_md2.xml
│ ├── ic_restart.xml
│ ├── ic_safetynet_md2.xml
│ ├── ic_save_md2.xml
│ ├── ic_search_md2.xml
│ ├── ic_settings_filled_md2.xml
│ ├── ic_settings_md2.xml
│ ├── ic_settings_outlined_md2.xml
│ ├── ic_show_md2.xml
│ ├── ic_splash_activity.xml
│ ├── ic_superuser.xml
│ ├── ic_superuser_filled_md2.xml
│ ├── ic_superuser_md2.xml
│ ├── ic_superuser_outlined_md2.xml
│ ├── ic_twitter.xml
│ ├── ic_up_md2.xml
│ ├── ic_update_md2.xml
│ ├── sc_extension.xml
│ ├── sc_magiskhide.xml
│ └── sc_superuser.xml
│ ├── layout
│ ├── activity_main_md2.xml
│ ├── activity_request.xml
│ ├── dialog_magisk_base.xml
│ ├── dialog_settings_app_name.xml
│ ├── dialog_settings_download_path.xml
│ ├── dialog_settings_update_channel.xml
│ ├── fragment_flash_md2.xml
│ ├── fragment_hide_md2.xml
│ ├── fragment_home_md2.xml
│ ├── fragment_install_md2.xml
│ ├── fragment_log_md2.xml
│ ├── fragment_module_md2.xml
│ ├── fragment_safetynet_md2.xml
│ ├── fragment_settings_md2.xml
│ ├── fragment_superuser_md2.xml
│ ├── fragment_theme_md2.xml
│ ├── include_hide_filter.xml
│ ├── include_home_magisk.xml
│ ├── include_home_manager.xml
│ ├── include_log_magisk.xml
│ ├── include_log_superuser.xml
│ ├── include_module_filter.xml
│ ├── item_console_md2.xml
│ ├── item_developer.xml
│ ├── item_hide_md2.xml
│ ├── item_hide_process_md2.xml
│ ├── item_icon_link.xml
│ ├── item_list_single_line.xml
│ ├── item_log_access_md2.xml
│ ├── item_log_track_md2.xml
│ ├── item_module_download.xml
│ ├── item_module_md2.xml
│ ├── item_policy_md2.xml
│ ├── item_repo_md2.xml
│ ├── item_section_md2.xml
│ ├── item_settings.xml
│ ├── item_settings_section.xml
│ ├── item_spinner.xml
│ ├── item_tappable_headline.xml
│ ├── item_text.xml
│ ├── item_theme.xml
│ ├── item_theme_container.xml
│ └── markdown_window_md2.xml
│ ├── menu
│ ├── menu_bottom_nav.xml
│ ├── menu_flash.xml
│ ├── menu_hide_md2.xml
│ ├── menu_home_md2.xml
│ ├── menu_log_md2.xml
│ ├── menu_module_md2.xml
│ └── menu_reboot.xml
│ ├── navigation
│ └── main.xml
│ ├── raw
│ ├── changelog.md
│ └── manager.sh
│ ├── values-ar
│ └── strings.xml
│ ├── values-az
│ └── strings.xml
│ ├── values-be
│ └── strings.xml
│ ├── values-bg
│ └── strings.xml
│ ├── values-ca
│ └── strings.xml
│ ├── values-cs
│ └── strings.xml
│ ├── values-de
│ └── strings.xml
│ ├── values-el
│ └── strings.xml
│ ├── values-es
│ └── strings.xml
│ ├── values-et
│ └── strings.xml
│ ├── values-fa
│ └── strings.xml
│ ├── values-fr
│ └── strings.xml
│ ├── values-hi
│ └── strings.xml
│ ├── values-hr
│ └── strings.xml
│ ├── values-in
│ └── strings.xml
│ ├── values-it
│ └── strings.xml
│ ├── values-iw
│ └── strings.xml
│ ├── values-ja
│ └── strings.xml
│ ├── values-ka
│ └── strings.xml
│ ├── values-ko
│ └── strings.xml
│ ├── values-lt
│ └── strings.xml
│ ├── values-mk
│ └── strings.xml
│ ├── values-nb
│ └── strings.xml
│ ├── values-night
│ ├── colors.xml
│ ├── styles_md2.xml
│ └── themes_md2.xml
│ ├── values-nl
│ └── strings.xml
│ ├── values-pa
│ └── strings.xml
│ ├── values-pl
│ └── strings.xml
│ ├── values-pt-rBR
│ └── strings.xml
│ ├── values-pt-rPT
│ └── strings.xml
│ ├── values-ro
│ └── strings.xml
│ ├── values-ru
│ └── strings.xml
│ ├── values-sk
│ └── strings.xml
│ ├── values-sq
│ └── strings.xml
│ ├── values-sr
│ └── strings.xml
│ ├── values-sv
│ └── strings.xml
│ ├── values-ta
│ └── strings.xml
│ ├── values-th
│ └── strings.xml
│ ├── values-tr
│ └── strings.xml
│ ├── values-uk
│ └── strings.xml
│ ├── values-v23
│ └── themes.xml
│ ├── values-v27
│ └── themes.xml
│ ├── values-vi
│ └── strings.xml
│ ├── values-zh-rCN
│ └── strings.xml
│ ├── values-zh-rTW
│ └── strings.xml
│ └── values
│ ├── arrays.xml
│ ├── attrs.xml
│ ├── colors.xml
│ ├── default_color.xml
│ ├── dimens.xml
│ ├── drawable.xml
│ ├── ids.xml
│ ├── resources.xml
│ ├── strings.xml
│ ├── styles_md2.xml
│ ├── styles_md2_appearance.xml
│ ├── styles_md2_impl.xml
│ ├── styles_view_md2.xml
│ ├── themes.xml
│ └── themes_md2.xml
├── build.gradle.kts
├── build.py
├── buildSrc
├── .gitignore
├── build.gradle.kts
└── src
│ └── main
│ └── java
│ ├── Codegen.kt
│ ├── Plugin.kt
│ └── Setup.kt
├── config.prop.sample
├── docs
├── README.md
├── app_changes.md
├── boot.md
├── changes.md
├── deploy.md
├── details.md
├── faq.md
├── guides.md
├── images
│ ├── device_info.png
│ ├── disable_auto_ota.png
│ ├── install_inactive_slot.png
│ ├── logo.png
│ ├── manager_reboot.png
│ ├── ota_done.png
│ └── restore_img.png
├── install.md
├── ota.md
├── procedures.html
├── releases
│ ├── 18000.md
│ ├── 18100.md
│ ├── 19000.md
│ ├── 19100.md
│ ├── 19200.md
│ ├── 19300.md
│ ├── 19400.md
│ ├── 20000.md
│ ├── 20100.md
│ ├── 20200.md
│ ├── 20300.md
│ ├── 20400.md
│ ├── 21000.md
│ ├── 21100.md
│ ├── 21200.md
│ ├── 21400.md
│ ├── 22000.md
│ ├── 22100.md
│ ├── 23000.md
│ └── index.md
└── tools.md
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── native
├── .gitignore
├── build.gradle.kts
├── jni
│ ├── .gitignore
│ ├── Android.mk
│ ├── Application.mk
│ ├── core
│ │ ├── applet_stub.cpp
│ │ ├── applets.cpp
│ │ ├── bootstages.cpp
│ │ ├── core.hpp
│ │ ├── daemon.cpp
│ │ ├── db.cpp
│ │ ├── logging.cpp
│ │ ├── magisk.cpp
│ │ ├── module.cpp
│ │ ├── restorecon.cpp
│ │ ├── scripting.cpp
│ │ ├── socket.cpp
│ │ └── thread.cpp
│ ├── external
│ │ ├── Android.mk
│ │ ├── systemproperties
│ │ │ ├── Android.mk
│ │ │ ├── context_node.cpp
│ │ │ ├── contexts_serialized.cpp
│ │ │ ├── contexts_split.cpp
│ │ │ ├── include
│ │ │ │ ├── _system_properties.h
│ │ │ │ ├── async_safe
│ │ │ │ │ └── log.h
│ │ │ │ ├── private
│ │ │ │ │ ├── ErrnoRestorer.h
│ │ │ │ │ ├── bionic_defs.h
│ │ │ │ │ ├── bionic_futex.h
│ │ │ │ │ ├── bionic_lock.h
│ │ │ │ │ ├── bionic_macros.h
│ │ │ │ │ └── hacks.h
│ │ │ │ ├── property_info_parser
│ │ │ │ │ └── property_info_parser.h
│ │ │ │ ├── system_properties.h
│ │ │ │ └── system_properties
│ │ │ │ │ ├── context_node.h
│ │ │ │ │ ├── contexts.h
│ │ │ │ │ ├── contexts_pre_split.h
│ │ │ │ │ ├── contexts_serialized.h
│ │ │ │ │ ├── contexts_split.h
│ │ │ │ │ ├── prop_area.h
│ │ │ │ │ ├── prop_info.h
│ │ │ │ │ └── system_properties.h
│ │ │ ├── prop_area.cpp
│ │ │ ├── prop_info.cpp
│ │ │ ├── property_info_parser.cpp
│ │ │ ├── system_properties.cpp
│ │ │ ├── system_property_api.cpp
│ │ │ └── system_property_set.cpp
│ │ ├── xz-embedded
│ │ │ ├── xz.h
│ │ │ ├── xz_config.h
│ │ │ ├── xz_crc32.c
│ │ │ ├── xz_dec_lzma2.c
│ │ │ ├── xz_dec_stream.c
│ │ │ ├── xz_lzma2.h
│ │ │ ├── xz_private.h
│ │ │ └── xz_stream.h
│ │ └── xz_config
│ │ │ └── config.h
│ ├── include
│ │ ├── daemon.hpp
│ │ ├── db.hpp
│ │ ├── magisk.hpp
│ │ ├── magiskpolicy.hpp
│ │ ├── resetprop.hpp
│ │ └── socket.hpp
│ ├── init
│ │ ├── getinfo.cpp
│ │ ├── init.cpp
│ │ ├── init.hpp
│ │ ├── magiskrc.inc
│ │ ├── mount.cpp
│ │ ├── raw_data.cpp
│ │ ├── raw_data.hpp
│ │ ├── rootdir.cpp
│ │ └── twostage.cpp
│ ├── magiskboot
│ │ ├── bootimg.cpp
│ │ ├── bootimg.hpp
│ │ ├── compress.cpp
│ │ ├── compress.hpp
│ │ ├── cpio.cpp
│ │ ├── cpio.hpp
│ │ ├── dtb.cpp
│ │ ├── dtb.hpp
│ │ ├── format.cpp
│ │ ├── format.hpp
│ │ ├── hexpatch.cpp
│ │ ├── magiskboot.hpp
│ │ ├── main.cpp
│ │ ├── pattern.cpp
│ │ └── ramdisk.cpp
│ ├── magiskhide
│ │ ├── hide_policy.cpp
│ │ ├── hide_utils.cpp
│ │ ├── magiskhide.cpp
│ │ ├── magiskhide.hpp
│ │ └── proc_monitor.cpp
│ ├── magiskpolicy
│ │ ├── magiskpolicy.cpp
│ │ ├── policydb.cpp
│ │ ├── rules.cpp
│ │ ├── sepolicy.cpp
│ │ ├── sepolicy.hpp
│ │ └── statement.cpp
│ ├── resetprop
│ │ ├── _resetprop.hpp
│ │ ├── persist_properties.cpp
│ │ └── resetprop.cpp
│ ├── su
│ │ ├── connect.cpp
│ │ ├── pts.cpp
│ │ ├── pts.hpp
│ │ ├── su.cpp
│ │ ├── su.hpp
│ │ └── su_daemon.cpp
│ ├── utils
│ │ ├── Android.mk
│ │ ├── files.cpp
│ │ ├── files.hpp
│ │ ├── include
│ │ │ ├── selinux.hpp
│ │ │ ├── stream.hpp
│ │ │ └── utils.hpp
│ │ ├── logging.cpp
│ │ ├── logging.hpp
│ │ ├── misc.cpp
│ │ ├── misc.hpp
│ │ ├── missing.cpp
│ │ ├── missing.hpp
│ │ ├── new.cpp
│ │ ├── selinux.cpp
│ │ ├── stream.cpp
│ │ ├── xwrap.cpp
│ │ └── xwrap.hpp
│ └── zygisk
│ │ ├── api.hpp
│ │ ├── entry.cpp
│ │ ├── gen_jni_hooks.py
│ │ ├── hook.cpp
│ │ ├── inject.hpp
│ │ ├── jni_hooks.hpp
│ │ ├── memory.cpp
│ │ ├── memory.hpp
│ │ ├── ptrace.cpp
│ │ ├── ptrace.hpp
│ │ └── utils.cpp
└── src
│ └── main
│ └── AndroidManifest.xml
├── scripts
├── addon.d.sh
├── boot_patch.sh
├── emulator.sh
├── flash_script.sh
├── module_installer.sh
├── uninstaller.sh
├── update_binary.sh
└── util_functions.sh
├── settings.gradle.kts
├── stub
├── .gitignore
├── build.gradle.kts
├── proguard-rules.pro
├── res
│ ├── values-ar
│ │ └── strings.xml
│ ├── values-az
│ │ └── strings.xml
│ ├── values-be
│ │ └── strings.xml
│ ├── values-bg
│ │ └── strings.xml
│ ├── values-ca
│ │ └── strings.xml
│ ├── values-cs
│ │ └── strings.xml
│ ├── values-de
│ │ └── strings.xml
│ ├── values-el
│ │ └── strings.xml
│ ├── values-es
│ │ └── strings.xml
│ ├── values-et
│ │ └── strings.xml
│ ├── values-fa
│ │ └── strings.xml
│ ├── values-fr
│ │ └── strings.xml
│ ├── values-hi
│ │ └── strings.xml
│ ├── values-hr
│ │ └── strings.xml
│ ├── values-in
│ │ └── strings.xml
│ ├── values-it
│ │ └── strings.xml
│ ├── values-iw
│ │ └── strings.xml
│ ├── values-ja
│ │ └── strings.xml
│ ├── values-ka
│ │ └── strings.xml
│ ├── values-ko
│ │ └── strings.xml
│ ├── values-lt
│ │ └── strings.xml
│ ├── values-mk
│ │ └── strings.xml
│ ├── values-nb
│ │ └── strings.xml
│ ├── values-nl
│ │ └── strings.xml
│ ├── values-pa
│ │ └── strings.xml
│ ├── values-pl
│ │ └── strings.xml
│ ├── values-pt-rBR
│ │ └── strings.xml
│ ├── values-pt-rPT
│ │ └── strings.xml
│ ├── values-ro
│ │ └── strings.xml
│ ├── values-ru
│ │ └── strings.xml
│ ├── values-sk
│ │ └── strings.xml
│ ├── values-sr
│ │ └── strings.xml
│ ├── values-sv
│ │ └── strings.xml
│ ├── values-ta
│ │ └── strings.xml
│ ├── values-th
│ │ └── strings.xml
│ ├── values-tr
│ │ └── strings.xml
│ ├── values-uk
│ │ └── strings.xml
│ ├── values-vi
│ │ └── strings.xml
│ ├── values-zh-rCN
│ │ └── strings.xml
│ ├── values-zh-rTW
│ │ └── strings.xml
│ └── values
│ │ └── strings.xml
├── src
│ └── main
│ │ └── java
│ │ └── com
│ │ └── topjohnwu
│ │ └── magisk
│ │ ├── ClassLoaders.java
│ │ ├── DelegateApplication.java
│ │ ├── DelegateComponentFactory.java
│ │ ├── DownloadActivity.java
│ │ ├── InjectAPK.java
│ │ ├── dummy
│ │ ├── DummyProvider.java
│ │ └── DummyReceiver.java
│ │ └── net
│ │ ├── BadRequest.java
│ │ ├── ErrorHandler.java
│ │ ├── Networking.java
│ │ ├── Request.java
│ │ └── ResponseListener.java
└── template
│ ├── AndroidManifest.xml
│ └── Mapping.java
└── tools
├── elf-cleaner.exe
├── futility
├── keys
├── kernel.keyblock
├── kernel_data_key.vbprivk
├── testkey.pk8
├── testkey.x509.pem
├── verity.pk8
└── verity.x509.pem
└── ndk-bins
├── 16
├── arm
│ ├── crtbegin_dynamic.o
│ ├── crtbegin_so.o
│ ├── crtbegin_static.o
│ ├── crtend_android.o
│ ├── crtend_so.o
│ ├── libc.a
│ ├── libm.a
│ └── libstdc++.a
└── i686
│ ├── crtbegin_dynamic.o
│ ├── crtbegin_so.o
│ ├── crtbegin_static.o
│ ├── crtend_android.o
│ ├── crtend_so.o
│ ├── libc.a
│ ├── libm.a
│ ├── libstdc++.a
│ └── libz.a
├── 21
├── aarch64
│ ├── crtbegin_dynamic.o
│ ├── crtbegin_so.o
│ ├── crtbegin_static.o
│ ├── crtend_android.o
│ ├── crtend_so.o
│ ├── libc.a
│ ├── libm.a
│ ├── libstdc++.a
│ └── libz.a
├── arm
│ ├── crtbegin_dynamic.o
│ ├── crtbegin_so.o
│ ├── crtbegin_static.o
│ ├── crtend_android.o
│ ├── crtend_so.o
│ ├── libc.a
│ ├── libm.a
│ ├── libstdc++.a
│ └── libz.a
├── i686
│ ├── crtbegin_dynamic.o
│ ├── crtbegin_so.o
│ ├── crtbegin_static.o
│ ├── crtend_android.o
│ ├── crtend_so.o
│ ├── libc.a
│ ├── libm.a
│ ├── libstdc++.a
│ └── libz.a
└── x86_64
│ ├── crtbegin_dynamic.o
│ ├── crtbegin_so.o
│ ├── crtbegin_static.o
│ ├── crtend_android.o
│ ├── crtend_so.o
│ ├── libc.a
│ ├── libm.a
│ ├── libstdc++.a
│ └── libz.a
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set the default behavior, in case people don't have core.autocrlf set.
2 | * text eol=lf
3 |
4 | # Explicitly declare text files you want to always be normalized and converted
5 | # to native line endings on checkout.
6 | # *.c text
7 | # *.h text
8 |
9 | # Declare files that will always have CRLF line endings on checkout.
10 | *.cmd text eol=crlf
11 | *.bat text eol=crlf
12 |
13 | # Denote all files that are truly binary and should not be modified.
14 | tools/** binary
15 | *.jar binary
16 | *.exe binary
17 | *.apk binary
18 | *.png binary
19 | *.jpg binary
20 | *.ttf binary
21 |
22 | # Help GitHub detect languages
23 | native/jni/external/** linguist-vendored
24 | native/jni/systemproperties/** linguist-language=C++
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: XDA Community Support
4 | url: https://forum.xda-developers.com/f/magisk.5903/
5 | about: Please ask and answer questions here.
6 |
7 |
--------------------------------------------------------------------------------
/.github/ccache.sh:
--------------------------------------------------------------------------------
1 | OS=$(uname)
2 | CCACHE_VER=4.4
3 |
4 | case $OS in
5 | Darwin )
6 | brew install ccache
7 | ln -s $(which ccache) ./ccache
8 | ;;
9 | Linux )
10 | sudo apt-get install -y ccache
11 | ln -s $(which ccache) ./ccache
12 | ;;
13 | * )
14 | curl -OL https://github.com/ccache/ccache/releases/download/v${CCACHE_VER}/ccache-${CCACHE_VER}-windows-64.zip
15 | unzip -j ccache-*-windows-64.zip '*/ccache.exe'
16 | ;;
17 | esac
18 | mkdir ./.ccache
19 | ./ccache -o compiler_check='%compiler% -dumpmachine; %compiler% -dumpversion'
20 |
--------------------------------------------------------------------------------
/.github/workflows/issues.yml:
--------------------------------------------------------------------------------
1 | name: Check Issues
2 |
3 | on:
4 | issues:
5 | types: [opened]
6 | jobs:
7 | check:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - name: Check out
11 | uses: actions/checkout@v2
12 | - name: Read latest version code
13 | run: |
14 | ver=$(sed -n 's/^magisk.versionCode=//p' gradle.properties)
15 | echo MAGISK_VERSION_CODE=$ver >> $GITHUB_ENV
16 | - if: contains(github.event.issue.body, format('Magisk version code{0} ', ':')) != true
17 | id: close
18 | name: Close Issue(template)
19 | uses: peter-evans/close-issue@v1
20 | with:
21 | comment: This issue is being automatically closed because it does not follow the issue template.
22 | - if: steps.close.conclusion == 'skipped' && contains(github.event.issue.body, format('Magisk version code{0} {1}', ':', env.MAGISK_VERSION_CODE)) != true
23 | name: Close Issue(latest canary)
24 | uses: peter-evans/close-issue@v1
25 | with:
26 | comment: This issue is being automatically closed because latest canary Magisk version code is ${{ env.MAGISK_VERSION_CODE }}.
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | *.zip
3 | *.jks
4 | *.apk
5 | /config.prop
6 | /update.sh
7 | /dict.txt
8 |
9 | # Built binaries
10 | native/out
11 |
12 | # Android Studio / Gradle
13 | *.iml
14 | .gradle
15 | /local.properties
16 | /.idea
17 | /build
18 | /captures
19 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | .idea/
5 | /build
6 | app/release
7 | *.hprof
8 | .externalNativeBuild/
9 | *.apk
10 | src/main/assets
11 | src/main/jniLibs
12 | src/main/resources
13 |
--------------------------------------------------------------------------------
/app/shared/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/shared/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.library")
3 | }
4 |
5 | setupCommon()
6 |
7 | android {
8 | defaultConfig {
9 | consumerProguardFiles("proguard-rules.pro")
10 | }
11 | }
12 |
13 | dependencies {
14 | api("io.michaelrocks:paranoid-core:0.3.5")
15 | }
16 |
--------------------------------------------------------------------------------
/app/shared/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/shared/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
15 |
18 |
19 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/shared/src/main/java/com/topjohnwu/magisk/ProviderInstaller.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk;
2 |
3 | import android.content.Context;
4 |
5 | import io.michaelrocks.paranoid.Obfuscate;
6 |
7 | @Obfuscate
8 | public class ProviderInstaller {
9 |
10 | public static boolean install(Context context) {
11 | try {
12 | // Try installing new SSL provider from Google Play Service
13 | Context gms = context.createPackageContext("com.google.android.gms",
14 | Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
15 | gms.getClassLoader()
16 | .loadClass("com.google.android.gms.common.security.ProviderInstallerImpl")
17 | .getMethod("insertProvider", Context.class)
18 | .invoke(null, gms);
19 | } catch (Exception e) {
20 | return false;
21 | }
22 | return true;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/shared/src/main/java/com/topjohnwu/magisk/utils/CompoundEnumeration.java:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.utils;
2 |
3 | import java.util.Enumeration;
4 | import java.util.NoSuchElementException;
5 |
6 | public class CompoundEnumeration implements Enumeration {
7 | private Enumeration[] enums;
8 | private int index = 0;
9 |
10 | @SafeVarargs
11 | public CompoundEnumeration(Enumeration ...enums) {
12 | this.enums = enums;
13 | }
14 |
15 | private boolean next() {
16 | while (index < enums.length) {
17 | if (enums[index] != null && enums[index].hasMoreElements()) {
18 | return true;
19 | }
20 | index++;
21 | }
22 | return false;
23 | }
24 |
25 | public boolean hasMoreElements() {
26 | return next();
27 | }
28 |
29 | public E nextElement() {
30 | if (!next()) {
31 | throw new NoSuchElementException();
32 | }
33 | return enums[index].nextElement();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/arch/BaseUIComponent.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.arch
2 |
3 | import android.view.View
4 | import androidx.lifecycle.LifecycleOwner
5 |
6 | interface BaseUIComponent : LifecycleOwner {
7 |
8 | val viewRoot: View
9 | val viewModel: VM
10 |
11 | fun startObserveEvents() {
12 | viewModel.viewEvents.observe(this) {
13 | onEventDispatched(it)
14 | }
15 | }
16 |
17 | /**
18 | * Called for all [ViewEvent]s published by associated viewModel.
19 | */
20 | fun onEventDispatched(event: ViewEvent) {}
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/arch/Queryable.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.arch
2 |
3 | import android.os.Handler
4 | import androidx.core.os.postDelayed
5 | import com.topjohnwu.superuser.internal.UiThreadHandler
6 |
7 | interface Queryable {
8 |
9 | val queryDelay: Long
10 | val queryHandler: Handler get() = UiThreadHandler.handler
11 |
12 | fun submitQuery() {
13 | queryHandler.postDelayed(queryDelay) { query() }
14 | }
15 |
16 | fun query()
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/arch/ViewEvent.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.arch
2 |
3 | import android.content.Context
4 | import kotlinx.coroutines.CoroutineScope
5 |
6 | /**
7 | * Class for passing events from ViewModels to Activities/Fragments
8 | * (see https://medium.com/google-developers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150)
9 | */
10 | abstract class ViewEvent
11 |
12 | abstract class ViewEventWithScope: ViewEvent() {
13 | lateinit var scope: CoroutineScope
14 | }
15 |
16 | interface ContextExecutor {
17 | operator fun invoke(context: Context)
18 | }
19 |
20 | interface ActivityExecutor {
21 | operator fun invoke(activity: BaseUIActivity<*, *>)
22 | }
23 |
24 | interface FragmentExecutor {
25 | operator fun invoke(fragment: BaseUIFragment<*, *>)
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/core/base/BaseReceiver.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.base
2 |
3 | import android.content.BroadcastReceiver
4 | import android.content.Context
5 | import android.content.ContextWrapper
6 | import android.content.Intent
7 | import com.topjohnwu.magisk.core.wrap
8 |
9 | abstract class BaseReceiver : BroadcastReceiver() {
10 |
11 | final override fun onReceive(context: Context, intent: Intent?) {
12 | onReceive(context.wrap() as ContextWrapper, intent)
13 | }
14 |
15 | abstract fun onReceive(context: ContextWrapper, intent: Intent?)
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/core/base/BaseService.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.base
2 |
3 | import android.app.Service
4 | import android.content.Context
5 | import com.topjohnwu.magisk.core.wrap
6 |
7 | abstract class BaseService : Service() {
8 | override fun attachBaseContext(base: Context) {
9 | super.attachBaseContext(base.wrap())
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/core/base/PermissionRequestBuilder.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.base
2 |
3 | typealias SimpleCallback = () -> Unit
4 | typealias PermissionRationaleCallback = (List) -> Unit
5 |
6 | class PermissionRequestBuilder {
7 |
8 | private var onSuccessCallback: SimpleCallback = {}
9 | private var onFailureCallback: SimpleCallback = {}
10 | private var onShowRationaleCallback: PermissionRationaleCallback = {}
11 |
12 | fun onSuccess(callback: SimpleCallback) {
13 | onSuccessCallback = callback
14 | }
15 |
16 | fun onFailure(callback: SimpleCallback) {
17 | onFailureCallback = callback
18 | }
19 |
20 | fun onShowRationale(callback: PermissionRationaleCallback) {
21 | onShowRationaleCallback = callback
22 | }
23 |
24 | fun build(): PermissionRequest {
25 | return PermissionRequest(onSuccessCallback, onFailureCallback, onShowRationaleCallback)
26 | }
27 |
28 | }
29 |
30 | class PermissionRequest(
31 | private val onSuccessCallback: SimpleCallback,
32 | private val onFailureCallback: SimpleCallback,
33 | private val onShowRationaleCallback: PermissionRationaleCallback
34 | ) {
35 |
36 | fun onSuccess() = onSuccessCallback()
37 | fun onFailure() = onFailureCallback()
38 | fun onShowRationale(permissions: List) = onShowRationaleCallback(permissions)
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/core/magiskdb/BaseDao.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.magiskdb
2 |
3 | import androidx.annotation.StringDef
4 |
5 | abstract class BaseDao {
6 |
7 | object Table {
8 | const val POLICY = "policies"
9 | const val LOG = "logs"
10 | const val SETTINGS = "settings"
11 | const val STRINGS = "strings"
12 | }
13 |
14 | @StringDef(Table.POLICY, Table.LOG, Table.SETTINGS, Table.STRINGS)
15 | @Retention(AnnotationRetention.SOURCE)
16 | annotation class TableStrict
17 |
18 | @TableStrict
19 | abstract val table: String
20 |
21 | inline fun buildQuery(builder: Builder.() -> Unit = {}) =
22 | Builder::class.java.newInstance()
23 | .apply { table = this@BaseDao.table }
24 | .apply(builder)
25 | .toString()
26 | .let { Query(it) }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/topjohnwu/magisk/core/magiskdb/SettingsDao.kt:
--------------------------------------------------------------------------------
1 | package com.topjohnwu.magisk.core.magiskdb
2 |
3 | class SettingsDao : BaseDao() {
4 |
5 | override val table = Table.SETTINGS
6 |
7 | suspend fun delete(key: String) = buildQuery {
8 | condition { equals("key", key) }
9 | }.commit()
10 |
11 | suspend fun put(key: String, value: Int) = buildQuery {
12 | values("key" to key, "value" to value)
13 | }.commit()
14 |
15 | suspend fun fetch(key: String, default: Int = -1) = buildQuery