1
mirror of https://github.com/topjohnwu/Magisk synced 2025-10-27 04:02:14 +01:00

Compare commits

..

154 Commits
v11.1 ... v13.0

Author SHA1 Message Date
topjohnwu
0b4baad78b Add mount namespace mode 2017-06-08 22:56:21 +08:00
topjohnwu
201e32d4c4 Fix daemon crashes in encrypted /data 2017-06-08 19:15:51 +08:00
topjohnwu
0980cb6eb5 Proper handle version string 2017-06-08 05:21:51 +08:00
topjohnwu
f75d23363b Update Magisk Manager 2017-06-08 05:21:27 +08:00
topjohnwu
6c0ba66f17 Add excessive logging for debug mode 2017-06-08 03:25:15 +08:00
topjohnwu
f32ce7392e Update sepolicy rules 2017-06-08 03:02:01 +08:00
topjohnwu
8bf382adad Apparently, not every device uses emmc 2017-06-07 11:32:35 +08:00
topjohnwu
541ba357bb Fix prop issues 2017-06-07 11:26:58 +08:00
topjohnwu
b6578b52e3 Update README.MD 2017-06-04 02:55:12 +08:00
topjohnwu
fb01c43ece Add Linux compatibility 2017-06-04 01:39:52 +08:00
topjohnwu
b9a012c6e3 Fix execution in Magisk binary for uninstallation 2017-06-04 00:35:45 +08:00
topjohnwu
17684ed8a8 Fix uninstaller and build with 'all' 2017-06-04 00:04:58 +08:00
topjohnwu
1b6b3b2cd5 Build in debug mode by default 2017-06-03 22:04:22 +08:00
topjohnwu
acd8567586 Adjust for Windows builds 2017-06-03 22:00:22 +08:00
topjohnwu
e780c76c93 Massive build script refactor 2017-06-03 20:31:02 +08:00
topjohnwu
532c6caddf Fix typo in cpio check 2017-06-03 18:52:02 +08:00
topjohnwu
ef8d9be633 More improvements and fixes 2017-06-03 05:52:49 +08:00
topjohnwu
2cdbcc5666 Add more checks for other patches 2017-06-03 05:08:52 +08:00
topjohnwu
c282a8f328 Loop for every for logging 2017-06-03 04:31:01 +08:00
topjohnwu
b9eab39541 Add ext4 img helper commands 2017-06-03 03:58:26 +08:00
topjohnwu
20903784a4 Support file based encryption and several small updates 2017-06-03 02:28:51 +08:00
topjohnwu
3ec9ff7467 Update MagiskSU 2017-06-01 03:20:51 +08:00
topjohnwu
17d3a87b1f Prevent resetprop function signature duplicate with libc 2017-05-30 23:34:39 +08:00
topjohnwu
14c5c60863 Improve excessive rapid root access performance 2017-05-29 18:56:00 +08:00
topjohnwu
70a80090c4 Improve multiuser su support 2017-05-28 01:33:58 +08:00
topjohnwu
b6cb5d09cb Add multiuser support 2017-05-27 02:43:55 +08:00
topjohnwu
69cfde4516 Add new function for vector (future proof) 2017-05-26 23:03:54 +08:00
topjohnwu
bdc83da098 Fix bug in magic mount 2017-05-26 23:03:54 +08:00
topjohnwu
f872a122a9 Preserve at least 32M free size 2017-05-26 23:03:45 +08:00
topjohnwu
aa92e4cbd0 Fix stupid bug in MagiskHide 2017-05-12 15:28:15 +08:00
topjohnwu
e603877a17 Install Magisk Manager APK with pm (Android O Compat.) 2017-05-09 01:16:58 +08:00
topjohnwu
bb96477779 Improve Magic Mount with proper precedence 2017-05-09 01:09:32 +08:00
topjohnwu
543ee79720 Prevent su logging tons of errors 2017-05-08 11:50:52 +08:00
topjohnwu
ea8cd98361 Cleanup file descriptors 2017-05-08 03:11:14 +08:00
topjohnwu
58849f28a8 Add daemon response code 2017-05-05 16:13:26 +08:00
topjohnwu
d66c284bed Fix several small issues 2017-05-05 04:39:09 +08:00
topjohnwu
693848280b Add systemless hosts support 2017-05-04 03:05:37 +08:00
topjohnwu
396afaa181 Improve magiskhide stability 2017-05-04 02:58:37 +08:00
topjohnwu
05ed29133b Finish post-fs simple mount 2017-05-04 02:39:53 +08:00
topjohnwu
a31c1e8084 post-fs-data mode done 2017-05-04 01:22:56 +08:00
topjohnwu
21891230f2 Typo fix 2017-05-02 05:00:01 +08:00
topjohnwu
47da76c5a5 Stupid bug, critical fix 2017-05-02 04:57:14 +08:00
topjohnwu
6017ff2318 Close files, cleanup resourses 2017-05-02 04:55:55 +08:00
topjohnwu
e16d604d0d Implement Magic Mount 2017-05-01 01:58:52 +08:00
topjohnwu
d3d5703f3f Reduce duplicate code for MagiskBoot 2017-04-28 21:53:44 +08:00
topjohnwu
62fe92d922 Update credits 2017-04-28 03:36:16 +08:00
topjohnwu
512e7be74f Add version info 2017-04-28 03:26:48 +08:00
topjohnwu
727abbea8f Cleanup magiskboot 2017-04-28 03:24:30 +08:00
topjohnwu
76f81ece62 Fix verbose output 2017-04-28 01:45:57 +08:00
topjohnwu
495654f9ff Small tweaks 2017-04-24 21:43:30 +08:00
topjohnwu
95fec2100e Use GPL v3 license and update copyright messages 2017-04-22 17:12:54 +08:00
topjohnwu
623a879797 Update scripts 2017-04-22 17:12:54 +08:00
topjohnwu
4c96d23f48 Some minor updates 2017-04-22 17:12:54 +08:00
topjohnwu
9bc8f6e9d7 Add common script support 2017-04-22 17:12:54 +08:00
topjohnwu
e00e6509ee Add error code for magiskhide 2017-04-22 17:12:54 +08:00
topjohnwu
be5739508b Isolate root daemon from requests 2017-04-22 17:12:54 +08:00
topjohnwu
38c867ea94 Some fixes 2017-04-22 17:12:54 +08:00
topjohnwu
2a985ce6c0 Add magiskhide list management 2017-04-22 17:12:54 +08:00
topjohnwu
e4f3fb36f3 Update build scripts 2017-04-22 17:12:54 +08:00
topjohnwu
b2f8792873 Add more Android O selinux stuff 2017-04-22 17:12:54 +08:00
topjohnwu
2065133e2d Update policy rules for Android O 2017-04-22 17:12:54 +08:00
topjohnwu
86da87f254 Update build script and tools 2017-04-22 17:12:54 +08:00
topjohnwu
102a7f8723 Change flags 2017-04-22 17:12:54 +08:00
topjohnwu
e9afc15719 Fix magiskhide daemon enable/disable 2017-04-22 17:12:54 +08:00
topjohnwu
08527dde9b Auto start magiskhide 2017-04-22 17:12:54 +08:00
topjohnwu
d9c3a3c9a9 Remove su_device auto transit 2017-04-22 17:12:54 +08:00
topjohnwu
fe89f9e55e Update to newer functions in resetprop 2017-04-22 17:12:54 +08:00
topjohnwu
73802aabac Fix compile issue when using NDK Unified Headers 2017-04-22 17:12:54 +08:00
topjohnwu
bc66733289 Add Android O sepolicy patches 2017-04-22 17:12:54 +08:00
topjohnwu
f4c93b2251 Update resetprop for Android O support
Updated to upstream https://android.googlesource.com/platform/bionic.git
2017-04-22 17:12:54 +08:00
topjohnwu
c079c598f2 Update scripts, MagiskSU now works fine 2017-04-22 17:12:54 +08:00
topjohnwu
8a2f0063d4 Improve magiskhide process/thread management 2017-04-22 17:12:54 +08:00
topjohnwu
dfe4b33f2f Integrate sepolicy patching with MagiskSU fixed 2017-04-22 17:12:54 +08:00
topjohnwu
2f7cfa7ab2 Link binaries when daemon started 2017-04-22 17:12:54 +08:00
topjohnwu
bdcb813ee6 Add block rw support 2017-04-22 17:12:54 +08:00
topjohnwu
f0751007f3 Update main function 2017-04-22 17:12:54 +08:00
topjohnwu
6ad993704c Integrate MagiskSU into Magisk daemon 2017-04-22 17:12:54 +08:00
topjohnwu
796c3009c7 Refactor resetprop 2017-04-22 17:12:54 +08:00
topjohnwu
144ff5e716 Integrate MagiskHide into Magisk Daemon 2017-04-22 17:12:54 +08:00
topjohnwu
054a1e5ea4 Add magisk daemon 2017-04-22 17:12:54 +08:00
topjohnwu
a223f6056e Add zygote namespace detection 2017-04-22 17:12:54 +08:00
topjohnwu
a1fd7704e0 Fix vector bug 2017-04-22 17:12:54 +08:00
topjohnwu
b94227efc9 Add process searching 2017-04-22 17:12:54 +08:00
topjohnwu
3a7e782c07 Remove separate binary support for tools rely on daemon 2017-04-22 17:12:54 +08:00
topjohnwu
8f6b33d790 Rewrite magiskhide 2017-04-22 17:12:54 +08:00
topjohnwu
f476daa041 Change parts of library to shared
libsqlite and libselinux are shipped with Android systems
We build them here for the compiler to link against it,
we actually use the one in /system/lib(64)
2017-04-22 17:12:54 +08:00
topjohnwu
acfde9458d Merge magiskpolicy, magiskhide, resetprop, magisksu 2017-04-22 17:12:54 +08:00
topjohnwu
82e969627a Start unifying with log monitor 2017-04-22 17:12:54 +08:00
topjohnwu
40766b3375 Do not use psuedo permissive, hide instead 2017-04-03 23:28:18 +08:00
topjohnwu
d274e45587 Fix SuperSU installation 2017-03-31 06:25:22 +08:00
topjohnwu
0a0eb3f710 Update policy rules 2017-03-31 02:54:39 +08:00
topjohnwu
81d054a525 Adjust scripts 2017-03-31 02:54:39 +08:00
topjohnwu
2e185f4ec9 Add core props support 2017-03-30 02:47:40 +08:00
topjohnwu
67f347f880 Live patch policy in service mode 2017-03-30 02:29:10 +08:00
topjohnwu
81542fc6a8 Fix MTK header support 2017-03-29 04:35:35 +08:00
topjohnwu
5aced279d6 Add legacy lz4 mode support 2017-03-29 04:35:35 +08:00
topjohnwu
3f016f785f Handle selinux for Samsung in binary 2017-03-29 02:23:10 +08:00
topjohnwu
a6427d081e Fix typo 2017-03-29 02:22:33 +08:00
topjohnwu
8c7fbe20f9 Daemons cannot run in /data on Samsung, move to magisk.img 2017-03-27 07:23:53 +08:00
Deiki-kun
469aba8ed0 Magisk Hide enable/disable scripts fix 2017-03-27 05:51:23 +08:00
topjohnwu
6e8e4ad5da Fix compile warnings 2017-03-26 23:40:34 +08:00
Jan Christian Grünhage
2f33d654e4 Fix Markdown headings 2017-03-26 21:49:24 +08:00
Jasmin Hassan
760b6385f1 list_monitor: use IN_CLOSE_WRITE instead of IN_MODIFY 2017-03-26 21:49:11 +08:00
Jasmin Hassan
91527500f9 proc_monitor: Support newer kernels am_proc_start format 2017-03-26 21:49:11 +08:00
Jasmin Hassan
e87d989ca3 Fix proccess monitor for lsskernel 6.0.1 (3.8UX) 2017-03-26 21:49:11 +08:00
topjohnwu
64d61bae08 Start MagiskHide even if disabled (MagiskSU only mode) 2017-03-26 21:47:54 +08:00
topjohnwu
9862265465 Add Samsung RKP hexpatch back 2017-03-26 21:44:44 +08:00
topjohnwu
624b7616d0 Another freakin stupid typo 2017-03-21 05:15:13 +08:00
topjohnwu
d53f33bed8 I shall test Samsung before release... 2017-03-21 04:25:49 +08:00
topjohnwu
02e039d792 Small fixes 2017-03-20 05:03:52 +08:00
topjohnwu
9f9333315e Update build script and remove redundant file 2017-03-19 05:02:20 +08:00
topjohnwu
0d10b812fe Handle MagiskSU and MagiskHide differently 2017-03-19 05:00:12 +08:00
topjohnwu
b4fe4f3d10 Rename sepolicy-inject 2017-03-18 17:26:30 +08:00
topjohnwu
ba93fcbda0 Prevent multirom crashes 2017-03-18 16:57:29 +08:00
topjohnwu
88d19a4ca4 Several fixes 2017-03-18 16:57:04 +08:00
topjohnwu
af7b9ea898 Update to MagiskSU 8 2017-03-16 06:58:43 +08:00
topjohnwu
09cd0468cf Stop after reading TRAILER!!! 2017-03-16 06:46:32 +08:00
topjohnwu
529aa754f5 Update scripts 2017-03-15 19:32:25 +08:00
topjohnwu
3c7e865555 The long awaited vendor mount fix 2017-03-15 03:43:28 +08:00
topjohnwu
7877ac0c3b Well, /dev/zero cannot be used like that... 2017-03-13 05:05:51 +08:00
topjohnwu
1442e29d0e Update size in MTK headers 2017-03-13 04:27:56 +08:00
topjohnwu
9a7e9b736e Typo 2017-03-13 04:17:39 +08:00
topjohnwu
c421e45fa0 Small improvements and bug fixes 2017-03-12 19:22:15 +08:00
topjohnwu
8833d21ac3 Update scripts for MagiskBoot 2017-03-12 18:21:50 +08:00
topjohnwu
1a3c522c94 Various improvements for Magisk installation 2017-03-12 18:12:16 +08:00
topjohnwu
c55aa92d4f Update build script 2017-03-12 01:24:30 +08:00
topjohnwu
212a303347 Add auto cpio backup and restore 2017-03-10 07:52:59 +08:00
topjohnwu
3f3568d8af More cpio features 2017-03-10 04:15:37 +08:00
topjohnwu
1e3bcfc8cd Add basic cpio features 2017-03-08 00:54:23 +08:00
topjohnwu
a4ce9f6f05 Add compress, decompress, cleanup command 2017-03-05 01:51:13 +08:00
topjohnwu
65dc99744e Use our own zlib for static link and ZLIB_CONST flag 2017-03-04 21:18:24 +08:00
topjohnwu
c6d4740b0c Separate utility functions 2017-03-04 21:16:59 +08:00
topjohnwu
9f91c8b59d Improvements 2017-03-04 00:04:15 +08:00
topjohnwu
2b3b087c29 Add bzip2 support 2017-03-02 05:23:31 +08:00
topjohnwu
e08d46aa76 Add lz4 support 2017-03-02 04:12:47 +08:00
topjohnwu
feccc97a14 Fix typo 2017-03-01 00:50:56 +08:00
topjohnwu
77eec3d21d Support legacy lzma 2017-03-01 00:47:59 +08:00
topjohnwu
ecaafd1b70 Fix header when repack from ELF 2017-03-01 00:15:38 +08:00
topjohnwu
0d51997e46 Add xz support 2017-02-28 21:56:13 +08:00
topjohnwu
463cbceb07 Cleanup Android.mk 2017-02-28 17:53:04 +08:00
topjohnwu
1437c5c63f Add ndk-compression with liblzma 2017-02-28 17:24:27 +08:00
topjohnwu
52f1d50902 Project restructure 2017-02-28 16:59:21 +08:00
topjohnwu
a839cb787e Rename bootimgtool to magiskboot 2017-02-28 05:43:49 +08:00
topjohnwu
f621fb2060 Add gzip native support 2017-02-28 05:40:27 +08:00
topjohnwu
2ccd8b8838 Cleanup hexpatch 2017-02-25 03:50:26 +08:00
topjohnwu
7ef0746c52 Add ELF support 2017-02-25 03:29:12 +08:00
topjohnwu
6f609f0dd7 Several improvements 2017-02-24 15:53:17 +08:00
topjohnwu
ee2a30470a Boot IMG tools complete re-write
Fix #27, Fix #35, Fix #68, Fix #70, Fix #71, Fix #72, Fix #75, Fix #87
2017-02-24 07:45:48 +08:00
topjohnwu
e11fb2c09e Fix compile errors 2017-02-20 11:55:32 +08:00
topjohnwu
c6e9270590 Add busybox to uninstaller and bug fixes 2017-02-14 07:13:36 +08:00
topjohnwu
3e2e171407 Update su 2017-02-14 06:41:52 +08:00
topjohnwu
332f531a10 Move binaries to seperate folder 2017-02-14 06:39:10 +08:00
Drgravy
bae2c9bc63 fix LG bump support for uninstaller 2017-02-14 03:39:53 +08:00
Drgravy
5ac68f8df8 fix up bump support for LG g2/g3 devices 2017-02-14 03:39:53 +08:00
109 changed files with 229895 additions and 2369 deletions

3
.gitattributes vendored
View File

@@ -10,8 +10,7 @@
*.cmd text eol=crlf
# Denote all files that are truly binary and should not be modified.
busybox binary
futility binary
chromeos/** binary
*.jar binary
*.exe binary
*.apk binary

22
.gitignore vendored
View File

@@ -1,25 +1,7 @@
obj/
libs/
*.zip
*.jks
# Generated binaries
zip_static/arm/*
zip_static/arm64/*
zip_static/x86/*
zip_static/x64/*
uninstaller/arm/*
uninstaller/arm64/*
uninstaller/x86/*
uninstaller/x64/*
# Copied binaries
ziptools/zipadjust
# Generated scripts
uninstaller/common/
zip_static/common/magic_mask.sh
zip_static/common/magisksu.sh
zip_static/common/init.magisk.rc
zip_static/common/custom_ramdisk_patch.sh
zip_static/META-INF/com/google/android/update-binary
# Leave all busybox!
!busybox

17
.gitmodules vendored
View File

@@ -1,12 +1,15 @@
[submodule "jni/sepolicy-inject"]
path = jni/sepolicy-inject
url = https://github.com/topjohnwu/sepolicy-inject
[submodule "jni/resetprop"]
path = jni/resetprop
url = https://github.com/topjohnwu/resetprop.git
[submodule "jni/selinux"]
path = jni/selinux
url = https://github.com/topjohnwu/selinux.git
[submodule "jni/su"]
path = jni/su
url = https://github.com/topjohnwu/Superuser.git
url = https://github.com/topjohnwu/MagiskSU.git
[submodule "jni/ndk-compression"]
path = jni/ndk-compression
url = https://github.com/topjohnwu/ndk-compression.git
[submodule "jni/magiskpolicy"]
path = jni/magiskpolicy
url = https://github.com/topjohnwu/magiskpolicy.git
[submodule "MagiskManager"]
path = MagiskManager
url = https://github.com/topjohnwu/MagiskManager.git

674
LICENSE Normal file

File diff suppressed because it is too large Load Diff

1
MagiskManager Submodule

Submodule MagiskManager added at d3ff482c9b

View File

@@ -1,11 +1,78 @@
# Magisk
###Static binaries included:
* Busybox: http://forum.xda-developers.com/android/software-hacking/tool-busybox-flashable-archs-t3348543
###How to build Magisk
1. Download and install NDK
2. Add the NDK directory into PATH
To check if the PATH is set correctly, try calling `which ndk-build` (`where ndk-build` on Windows) and see if it shows the NDK directory
3. Unix-like users (e.g. Linux & MacOS) please execute `build.sh` through shell
Windows users please execute `build.cmd` through cmd
4. The scripts will show you further details
## How to build Magisk
#### Building has been tested on 3 major platforms:
***macOS 10.12.5***
***Ubuntu 17.04 x64***
***Windows 10 Creators Update x64***
#### Environment Requirements
1. Python 3 **(>= 3.5)**: `python3` (or in some cases `python`) should be accessible
2. Java runtime: `java` should be accessible
3. (Unix only) C compiler: `gcc` should be accessible
4. Android SDK: `ANDROID_HOME` environment variable should point to the Android SDK folder
5. NDK: Install NDK using `sdkmanager`, or through Android SDK Manager
6. Android build-tools: Should have build-tools version matching `MagiskManager/app/build.gradle` installed
#### Instructions and Notes
1. The python build script uses ANSI color codes to change the color of the terminal output. For Windows, this **only** works on Windows 10, as previous Windows console do not support them. If you insist to use an older Windows version, a quick Google search should provide many workarounds
2. After installing the latest Python 3 on Windows (allow the installer to add Python to PATH, or you'll have to manually set the environment), instead of calling `python3` like most Unix environment, you should call `python` in shell (cmd or Powershell both OK). You can double check the version by `python --version`
3. The build script will do several checks, it will refuse to run if the environment doesn't meet the requirements
4. For further instructions, please check the built in help message by `python3 build.py -h`
(Unix users can simply `./build.py -h`, Windows users, as mentioned, call `python` instead)
5. Each action has its own help message, access them by commands like `python3 build.py all -h`
6. To build Magisk for release (enabled through the `--release` flag, the script builds in debug mode by default), you will need to provide a Java keystore file, and place it in `release_signature.jks` to sign Magisk Manager APK for release builds. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually)
7. To properly setup the Android SDK environment, the easiest way is to use Android Studio and open Magisk Manager. If gradle sync passed, your build-tools etc. should be set properly. You can also access SDK Manager GUI within Android Studio to download NDK. Don't forget to add Android Studio's SDK path into environment variable ANDROID_HOME.
## License
Magisk, including all subprojects (git submodule) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
## Credits
**MagiskManager** (`MagiskManager`)
* Copyright 2016-2017, John Wu (@topjohnwu)
* All contributors and translators
**MagiskSU** (`jni/su`)
* Copyright 2016-2017, John Wu (@topjohnwu)
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
* Copyright 2013, Koushik Dutta (@koush)
* Copyright 2010, Adam Shanks (@ChainsDD)
* Copyright 2008, Zinx Verituse (@zinxv)
**MagiskPolicy** (`jni/magiskpolicy`)
* Copyright 2016-2017, John Wu (@topjohnwu)
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
* Copyright 2015, Joshua Brindle (@joshua_brindle)
**MagiskHide** (`jni/magiskhide`)
* Copyright 2016-2017, John Wu (@topjohnwu)
* Copyright 2016, Pierre-Hugues Husson (phh@phh.me) (original hidesu)
**resetprop** (`jni/resetprop`)
* Copyright 2016-2017 John Wu (@topjohnwu)
* Copyright 2016 nkk71 (nkk71x@gmail.com)
**SELinux** (`jni/selinux`)
* Makefile for NDK: Copyright 2016-2017, John Wu (@topjohnwu)
* It is maintained by many developers in SELinux project, copyright belongs to them
**ndk-compression** (`jni/ndk-compression`)
* Makefile for NDK: Copyright 2017, John Wu (@topjohnwu)
* Each library has its own copyright message in each directories
**Others Not Mentioned**
* Copyright 2016-2017, John Wu (@topjohnwu)

167
build.cmd
View File

@@ -1,167 +0,0 @@
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
SET me=%~nx0
SET parent=%~dp0
SET tab=
SET OK=
CD %parent%
call :%~1 "%~2"
IF NOT DEFINED OK CALL :usage
EXIT /B %ERRORLEVEL%
:usage
ECHO %me% all ^<version name^>
ECHO %tab%Build binaries, zip, and sign Magisk
ECHO %tab%This is equlivant to first ^<build^>, then ^<zip^>
ECHO %me% clean
ECHO %tab%Cleanup compiled / generated files
ECHO %me% build
ECHO %tab%Build the binaries with ndk
ECHO %me% zip ^<version name^>
ECHO %tab%Zip and sign Magisk
ECHO %me% uninstaller
ECHO %tab%Zip and sign the uninstaller
EXIT /B 1
:all
SET OK=y
IF [%~1] == [] (
CALL :error "Missing version number"
CALL :usage
EXIT /B %ERRORLEVEL%
)
CALL :build
CALL :zip "%~1"
EXIT /B %ERRORLEVEL%
:build
SET OK=y
ECHO ************************
ECHO * Building binaries
ECHO ************************
FOR /F "tokens=* USEBACKQ" %%F IN (`where ndk-build`) DO (
IF [%%F] == [] (
CALL :error "Please add ndk-build to PATH!"
EXIT /B 1
)
)
CALL ndk-build -j4 || CALL :error "Magisk binary tools build failed...."
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
ECHO ************************
ECHO * Copying binaries
ECHO ************************
COPY /Y libs\armeabi-v7a\* zip_static\arm
COPY /Y libs\arm64-v8a\* zip_static\arm64
COPY /Y libs\x86\* zip_static\x86
COPY /Y libs\x86_64\* zip_static\x64
CALL :mkcp libs\armeabi-v7a\bootimgtools uninstaller\arm
CALL :mkcp libs\arm64-v8a\bootimgtools uninstaller\arm64
CALL :mkcp libs\x86\bootimgtools uninstaller\x86
CALL :mkcp libs\x86_64\bootimgtools uninstaller\x64
EXIT /B %ERRORLEVEL%
:clean
SET OK=y
ECHO ************************
ECHO * Cleaning up
ECHO ************************
CALL ndk-build clean
forfiles /P zip_static\arm /C "cmd /C IF NOT @file == \"busybox\" DEL @file"
forfiles /P zip_static\arm64 /C "cmd /C IF NOT @file == \"busybox\" DEL @file"
forfiles /P zip_static\x86 /C "cmd /C IF NOT @file == \"busybox\" DEL @file"
forfiles /P zip_static\x64 /C "cmd /C IF NOT @file == \"busybox\" DEL @file"
2>NUL DEL zip_static\META-INF\com\google\android\update-binary
2>NUL DEL zip_static\common\custom_ramdisk_patch.sh
2>NUL DEL zip_static\common\magisksu.sh
2>NUL DEL zip_static\common\init.magisk.rc
2>NUL DEL zip_static\common\magic_mask.sh
2>NUL RMDIR /S /Q uninstaller\common
2>NUL RMDIR /S /Q uninstaller\arm
2>NUL RMDIR /S /Q uninstaller\arm64
2>NUL RMDIR /S /Q uninstaller\x86
2>NUL RMDIR /S /Q uninstaller\x64
EXIT /B 0
:zip
SET OK=y
IF [%~1] == [] (
CALL :error "Missing version number"
CALL :usage
EXIT /B %ERRORLEVEL%
)
IF NOT EXIST "zip_static\arm\bootimgtools" CALL :error "Missing binaries! Please run '%me% build' before zipping!"
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
ECHO ************************
ECHO * Adding version info
ECHO ************************
powershell.exe -nologo -noprofile -command "(gc -Raw scripts\flash_script.sh) -replace 'MAGISK_VERSION_STUB', 'Magisk v%~1 Boot Image Patcher' | sc zip_static\META-INF\com\google\android\update-binary"
powershell.exe -nologo -noprofile -command "(gc -Raw scripts\magic_mask.sh) -replace 'MAGISK_VERSION_STUB', 'setprop magisk.version \"%~1\"' | sc zip_static\common\magic_mask.sh"
ECHO ************************
ECHO * Zipping Magisk v%~1
ECHO ************************
COPY /Y scripts\custom_ramdisk_patch.sh zip_static\common\custom_ramdisk_patch.sh
COPY /Y scripts\magisksu.sh zip_static\common\magisksu.sh
COPY /Y scripts\init.magisk.rc zip_static\common\init.magisk.rc
CD zip_static
2>NUL DEL "..\Magisk-v%~1.zip"
..\ziptools\win_bin\zip "..\Magisk-v%~1.zip" -r .
CD ..\
CALL :sign_zip "Magisk-v%~1.zip"
EXIT /B %ERRORLEVEL%
:uninstaller
SET OK=y
IF NOT EXIST "uninstaller\arm\bootimgtools" CALL :error "Missing binaries! Please run '%me% build' before zipping!"
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
ECHO ************************
ECHO * Zipping uninstaller
ECHO ************************
CALL :mkcp scripts\magisk_uninstaller.sh uninstaller\common
FOR /F "tokens=* USEBACKQ" %%F IN (`ziptools\win_bin\date "+%%Y%%m%%d"`) DO (set timestamp=%%F)
CD uninstaller
2>NUL DEL "../Magisk-uninstaller-%timestamp%.zip"
..\ziptools\win_bin\zip "../Magisk-uninstaller-%timestamp%.zip" -r .
CD ..\
CALL :sign_zip "Magisk-uninstaller-%timestamp%.zip"
EXIT /B %ERRORLEVEL%
:sign_zip
IF NOT EXIST "ziptools\win_bin\zipadjust.exe" (
ECHO ************************
ECHO * Compiling ZipAdjust
ECHO ************************
gcc -o ziptools\win_bin\zipadjust ziptools\src\*.c -lz || CALL :error "ZipAdjust Build failed...."
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
)
SET basename="%~1"
SET basename="%basename:.zip=%"
ECHO ************************
ECHO * First sign %~1
ECHO ************************
java -jar "ziptools\signapk.jar" "ziptools\test.certificate.x509.pem" "ziptools\test.key.pk8" "%~1" "%basename:"=%-firstsign.zip"
ECHO ************************
ECHO * Adjusting %~1
ECHO ************************
ziptools\win_bin\zipadjust "%basename:"=%-firstsign.zip" "%basename:"=%-adjusted.zip"
ECHO ************************
ECHO * Final sign %~1
ECHO ************************
java -jar "ziptools\minsignapk.jar" "ziptools\test.certificate.x509.pem" "ziptools\test.key.pk8" "%basename:"=%-adjusted.zip" "%basename:"=%-signed.zip"
MOVE /Y "%basename:"=%-signed.zip" "%~1"
DEL "%basename:"=%-adjusted.zip" "%basename:"=%-firstsign.zip"
EXIT /B %ERRORLEVEL%
:mkcp
2>NUL MKDIR "%~2"
2>NUL COPY /Y "%~1" "%~2"
EXIT /B 0
:error
ECHO.
ECHO ! %~1
ECHO.
EXIT /B 1

270
build.py Executable file

File diff suppressed because it is too large Load Diff

156
build.sh
View File

@@ -1,156 +0,0 @@
#!/bin/bash
usage() {
echo "$0 all <version name>"
echo -e "\tBuild binaries, zip, and sign Magisk"
echo -e "\tThis is equlivant to first <build>, then <zip>"
echo "$0 clean"
echo -e "\tCleanup compiled / generated files"
echo "$0 build"
echo -e "\tBuild the binaries with ndk"
echo "$0 zip <version name>"
echo -e "\tZip and sign Magisk"
echo "$0 uninstaller"
echo -e "\tZip and sign the uninstaller"
exit 1
}
cleanup() {
echo "************************"
echo "* Cleaning up"
echo "************************"
ndk-build clean 2>/dev/null
ls zip_static/arm/* | grep -v "busybox" | xargs rm -rfv
ls zip_static/arm64/* | grep -v "busybox" | xargs rm -rfv
ls zip_static/x86/* | grep -v "busybox" | xargs rm -rfv
ls zip_static/x64/* | grep -v "busybox" | xargs rm -rfv
rm -rfv zip_static/META-INF/com/google/android/update-binary
rm -rfv zip_static/common/custom_ramdisk_patch.sh
rm -rfv zip_static/common/magisksu.sh
rm -rfv zip_static/common/init.magisk.rc
rm -rfv zip_static/common/magic_mask.sh
rm -rfv uninstaller/common
rm -rfv uninstaller/arm
rm -rfv uninstaller/arm64
rm -rfv uninstaller/x86
rm -rfv uninstaller/x64
}
mkcp() {
[ ! -d "$2" ] && mkdir -p "$2"
cp -afv $1 $2
}
error() {
echo -e "\n! $1\n"
exit 1
}
build_bin() {
echo "************************"
echo "* Building binaries"
echo "************************"
[ -z `which ndk-build` ] && error "Please add ndk-build to PATH!"
ndk-build -j4 || error "Magisk binary tools build failed...."
echo "************************"
echo "* Copying binaries"
echo "************************"
mkcp "libs/armeabi-v7a/*" zip_static/arm
mkcp libs/armeabi-v7a/bootimgtools uninstaller/arm
mkcp "libs/arm64-v8a/*" zip_static/arm64
mkcp libs/arm64-v8a/bootimgtools uninstaller/arm64
mkcp "libs/x86/*" zip_static/x86
mkcp libs/x86/bootimgtools uninstaller/x86
mkcp "libs/x86_64/*" zip_static/x64
mkcp libs/x86_64/bootimgtools uninstaller/x64
}
zip_package() {
[ ! -f "zip_static/arm/bootimgtools" ] && error "Missing binaries!! Please run '$0 build' before zipping"
echo "************************"
echo "* Adding version info"
echo "************************"
sed "s/MAGISK_VERSION_STUB/Magisk v$1 Boot Image Patcher/g" scripts/flash_script.sh > zip_static/META-INF/com/google/android/update-binary
sed "s/MAGISK_VERSION_STUB/setprop magisk.version \"$1\"/g" scripts/magic_mask.sh > zip_static/common/magic_mask.sh
echo "************************"
echo "* Zipping Magisk v$1"
echo "************************"
cp -afv scripts/custom_ramdisk_patch.sh zip_static/common/custom_ramdisk_patch.sh
cp -afv scripts/magisksu.sh zip_static/common/magisksu.sh
cp -afv scripts/init.magisk.rc zip_static/common/init.magisk.rc
cd zip_static
find . -type f -exec chmod 644 {} \;
find . -type d -exec chmod 755 {} \;
rm -rf "../Magisk-v$1.zip"
zip "../Magisk-v$1.zip" -r .
cd ../
sign_zip "Magisk-v$1.zip"
}
zip_uninstaller() {
[ ! -f "uninstaller/arm/bootimgtools" ] && error "Missing binaries!! Please run '$0 build' before zipping"
echo "************************"
echo "* Zipping uninstaller"
echo "************************"
mkcp scripts/magisk_uninstaller.sh uninstaller/common
cd uninstaller
find . -type f -exec chmod 644 {} \;
find . -type d -exec chmod 755 {} \;
TIMESTAMP=`date "+%Y%m%d"`
rm -rf "../Magisk-uninstaller-$TIMESTAMP.zip"
zip "../Magisk-uninstaller-$TIMESTAMP.zip" -r .
cd ../
sign_zip "Magisk-uninstaller-$TIMESTAMP.zip"
}
sign_zip() {
if [ ! -f "ziptools/zipadjust" ]; then
echo "************************"
echo "* Compiling ZipAdjust"
echo "************************"
gcc -o ziptools/zipadjust ziptools/src/*.c -lz || error "ZipAdjust Build failed...."
chmod 755 ziptools/zipadjust
fi
echo "************************"
echo "* First sign $1"
echo "************************"
java -jar "ziptools/signapk.jar" "ziptools/test.certificate.x509.pem" "ziptools/test.key.pk8" "$1" "${1%.*}-firstsign.zip"
echo "************************"
echo "* Adjusting $1"
echo "************************"
ziptools/zipadjust "${1%.*}-firstsign.zip" "${1%.*}-adjusted.zip"
echo "************************"
echo "* Final sign $1"
echo "************************"
java -jar "ziptools/minsignapk.jar" "ziptools/test.certificate.x509.pem" "ziptools/test.key.pk8" "${1%.*}-adjusted.zip" "${1%.*}-signed.zip"
mv "${1%.*}-signed.zip" "$1"
rm "${1%.*}-adjusted.zip" "${1%.*}-firstsign.zip"
}
DIR="$(cd "$(dirname "$0")"; pwd)"
cd "$DIR"
case $1 in
"all" )
[ -z "$2" ] && echo -e "! Missing version number\n" && usage
build_bin
zip_package $2
;;
"clean" )
cleanup
;;
"build" )
build_bin
;;
"zip" )
[ -z "$2" ] && echo -e "! Missing version number\n" && usage
zip_package $2
;;
"uninstaller" )
zip_uninstaller
;;
* )
usage
;;
esac

View File

@@ -1,10 +1,65 @@
LOCAL_PATH := $(call my-dir)
include jni/bootimgtools/Android.mk
include jni/magiskhide/Android.mk
include jni/resetprop/Android.mk
include jni/sepolicy-inject/Android.mk
include jni/su/Android.mk
include $(CLEAR_VARS)
LOCAL_MODULE := magisk
LOCAL_STATIC_LIBRARIES := libsepol
LOCAL_SHARED_LIBRARIES := libsqlite libselinux
include jni/selinux/libsepol/Android.mk
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/utils \
$(LOCAL_PATH)/daemon \
$(LOCAL_PATH)/resetprop \
$(LOCAL_PATH)/magiskpolicy \
$(LOCAL_PATH)/selinux/libselinux/include \
$(LOCAL_PATH)/selinux/libsepol/include \
$(LOCAL_PATH)/sqlite3
LOCAL_SRC_FILES := \
main.c \
utils/misc.c \
utils/vector.c \
utils/xwrap.c \
utils/list.c \
daemon/daemon.c \
daemon/socket_trans.c \
daemon/log_monitor.c \
daemon/bootstages.c \
magiskhide/magiskhide.c \
magiskhide/hide_daemon.c \
magiskhide/proc_monitor.c \
magiskhide/pre_process.c \
magiskhide/list_manager.c \
magiskpolicy/magiskpolicy.c \
magiskpolicy/rules.c \
magiskpolicy/sepolicy.c \
magiskpolicy/api.c \
resetprop/resetprop.cpp \
resetprop/system_properties.cpp \
su/su.c \
su/activity.c \
su/db.c \
su/misc.c \
su/pts.c \
su/su_daemon.c \
su/su_socket.c
LOCAL_CFLAGS := -Wno-implicit-exception-spec-mismatch
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
# Libraries
include jni/selinux/libselinux/Android.mk
include jni/selinux/libsepol/Android.mk
include jni/sqlite3/Android.mk
#####################################################################
# In order to build separate binaries, please comment out everything
# starting from line 3 (including the 3 lines for libraries)
# Then, uncomment the line you want below
#####################################################################
# include jni/resetprop/Android.mk
# include jni/magiskpolicy/Android.mk
# Build magiskboot
include jni/magiskboot/Android.mk

View File

@@ -1,4 +1,4 @@
APP_ABI := x86 x86_64 armeabi-v7a arm64-v8a
APP_PIE = true
APP_PLATFORM := android-21
APP_UNIFIED_HEADERS := true
APP_CPPFLAGS += -std=c++11

View File

@@ -1,8 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := bootimgtools
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := main.c extract.c repack.c hexpatch.c
LOCAL_CFLAGS += -std=gnu11
include $(BUILD_EXECUTABLE)

View File

@@ -1,149 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include "bootimg.h"
void dump(uint8_t *ptr, size_t size, char* filename) {
unlink(filename);
int ofd = open(filename, O_WRONLY|O_CREAT, 0644);
assert(ofd >= 0);
int ret = write(ofd, ptr, size);
assert(ret == size);
close(ofd);
}
//TODO: Search for other header types
void dump_ramdisk(uint8_t *ptr, size_t size) {
//GZip header
if(memcmp(ptr, "\x1f\x8b\x08\x00", 4) == 0) {
dump(ptr, size, "ramdisk.gz");
//MTK header
} else if(memcmp(ptr, "\x88\x16\x88\x58", 4) == 0) {
if(memcmp(ptr+8, "RECOVERY", 8)==0) {
dump(ptr, 0, "ramdisk-mtk-recovery");
} else if(memcmp(ptr+8, "ROOTFS\0\0", 8)==0) {
dump(ptr, 0, "ramdisk-mtk-boot");
} else {
exit(1);
}
dump(ptr, 0, "ramdisk-mtk"); //Create an mtk flag
dump_ramdisk(ptr+512, size-512);
} else {
//Since our first aim is to extract/repack ramdisk
//Stop if we can't find it
//Still dump it for debug purposes
dump(ptr, size, "ramdisk");
fprintf(stderr, "Unknown ramdisk type\n");
abort();
}
}
void search_security_hdr(uint8_t *buf, size_t size) {
if(memcmp(buf, "CHROMEOS", 8) == 0) {
dump(buf, 0, "chromeos");
return;
}
}
int search_security(uint8_t *buf, size_t size, int pos) {
//Rockchip signature
if(memcmp(buf+1024, "SIGN", 4) == 0) {
//Rockchip signature AT LEAST means the bootloader will check the crc
dump(buf, 0, "rkcrc"); //Create an flag to tell it
//And it's possible there is a security too
return 1;
}
//If we didn't parse the whole file, it is highly likely there is a boot signature
if(pos < size) {
return 1;
}
return 0;
}
/*
* TODO:
* - At the moment we dump kernel + ramdisk + second + DT, it's likely we only want ramdisk
* - Error-handling via assert() is perhaps not the best
*/
int extract(char *image) {
int fd = open(image, O_RDONLY);
off_t size = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
uint8_t *orig = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
uint8_t *base = orig;
assert(base);
search_security_hdr(base, size);
//We're searching for the header in the whole file, we could stop earlier.
//At least HTC and nVidia have a signature header
while(base<(orig+size)) {
if(memcmp(base, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0)
break;
//We're searching every 256bytes, is it ok?
base += 256;
}
assert(base < (orig+size));
struct boot_img_hdr *hdr = (struct boot_img_hdr*) base;
assert(
hdr->page_size == 2048 ||
hdr->page_size == 4096 ||
hdr->page_size == 16384
);
long pos = hdr->page_size;
dump(base+pos, hdr->kernel_size, "kernel");
pos += hdr->kernel_size + hdr->page_size-1;
pos &= ~(hdr->page_size-1L);
dump_ramdisk(base+pos, hdr->ramdisk_size);
pos += hdr->ramdisk_size + hdr->page_size-1;
pos &= ~(hdr->page_size-1L);
if(hdr->second_size) {
assert( (pos+hdr->second_size) <= size);
dump(base+pos, hdr->second_size, "second");
pos += hdr->second_size + hdr->page_size-1;
pos &= ~(hdr->page_size-1L);
}
//This is non-standard, so we triple check
if( hdr->unused[0] &&
pos < size &&
(pos+hdr->unused[0]) <= size) {
if(memcmp(base+pos, "QCDT", 4) == 0 ||
memcmp(base+pos, "SPRD", 4) == 0 ||
memcmp(base+pos, "DTBH", 4) == 0 ||
memcmp(base+pos, "\xD0\x0D\xFE\xED", 4) == 0
) {
dump(base+pos, hdr->unused[0], "dt");
pos += hdr->unused[0] + hdr->page_size-1;
pos &= ~(hdr->page_size-1L);
}
}
//If we think we find some security-related infos in the boot.img
//create a "secure" flag to warn the user it is dangerous
if(search_security(base, size, pos)) {
dump(base, 0, "secure");
}
munmap(orig, size);
close(fd);
return 0;
}

View File

@@ -1,66 +0,0 @@
#include <getopt.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include "bootimg.h"
int hex2int(char c) {
int first = c / 16 - 3;
int second = c % 16;
int result = first * 10 + second;
if(result > 9) result--;
return result;
}
int hex2ascii(char c, char d) {
int high = hex2int(c) * 16;
int low = hex2int(d);
return high+low;
}
void hexstr2str(char *hex, char *str) {
char buf = 0;
for(int i = 0, length = strlen(hex); i < length; ++i){
if(i % 2){
str[i / 2] = hex2ascii(buf, hex[i]);
} else{
buf = hex[i];
}
}
}
int hexpatch(char * image, char *from, char *to) {
int fd = open(image, O_RDWR), patternsize = strlen(from) / 2, patchsize = strlen(to) / 2;
off_t filesize = lseek(fd, 0, SEEK_END);
char *file, *pattern, *patch, *start;
file = malloc(sizeof (char) * filesize);
pattern = malloc(sizeof (char) * patternsize);
patch = malloc(sizeof (char) * patchsize);
lseek(fd, 0, SEEK_SET);
read(fd, file, filesize);
hexstr2str(from, pattern);
hexstr2str(to, patch);
for (off_t i = 0; i < filesize;) {
int j;
for (j = 0; j < patternsize; ++j) {
if(file[i + j] != pattern[j]) break;
}
if (j == patternsize) {
fprintf(stderr, "Pattern %s found!\nPatching to %s\n", from, to);
lseek(fd, i, SEEK_SET);
write(fd, patch, patchsize);
}
if(j == 0) j = 1;
i += j;
}
free(file);
free(pattern);
free(patch);
close(fd);
return 0;
}

View File

@@ -1,45 +0,0 @@
#include <getopt.h>
#include <stdio.h>
#include "bootimg.h"
/********************
Patch Boot Image
*********************/
int usage(char *arg0) {
fprintf(stderr, "Boot Image Unpack/Repack Tool\n");
fprintf(stderr, "%s --extract <bootimage>\n", arg0);
fprintf(stderr, " Unpack <bootimage> into current directory\n\n");
fprintf(stderr, "%s --repack <bootimage>\n", arg0);
fprintf(stderr, " Repack kernel, dt, ramdisk... from current directory to new-image.img\n <bootimage> is the image you've just unpacked\n\n");
fprintf(stderr, "%s --hexpatch <bootimage> <hexpattern1> <hexpattern2>\n", arg0);
fprintf(stderr, " Search <hexpattern1> in <bootimage>, and replace with <hexpattern2>\n\n");
return 1;
}
int main(int argc, char *argv[])
{
char ch;
struct option long_options[] = {
{"extract", required_argument, NULL, 'e'},
{"repack", required_argument, NULL, 'r'},
{"hexpatch", required_argument, NULL, 'p'},
{NULL, 0, NULL, 0}
};
while ((ch = getopt_long(argc, argv, "e:r:p:", long_options, NULL)) != -1) {
switch (ch) {
case 'e':
return extract(optarg);
case 'r':
return repack(optarg);
case 'p':
if (argc < 5) return usage(argv[0]);
optind += 2;
return hexpatch(argv[optind - 3], argv[optind - 2], argv[optind - 1]);
default:
return usage(argv[0]);
}
}
return 0;
}

View File

@@ -1,144 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include "bootimg.h"
off_t file_size(char *filename) {
struct stat st;
if(stat(filename, &st))
exit(1);
return st.st_size;
}
int append_file(int ofd, char *filename, off_t pos) {
lseek(ofd, pos, SEEK_SET);
int fd = open(filename, O_RDONLY);
int size = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
sendfile(ofd, fd, NULL, size);
close(fd);
return size;
}
int append_ramdisk(int ofd, off_t pos) {
if(access("ramdisk-mtk", R_OK) == 0) {
char buf[512];
off_t size = file_size("ramdisk.gz");
memcpy(buf, "\x88\x16\x88\x58", 4);
uint32_t v = size;
memcpy(buf+4, &v, sizeof(v)); //Should convert to LE
//TODO: RECOVERY OR ROOTFS?
char str[32];
memset(str, 0, sizeof(str));
if(access("ramdisk-mtk-boot", R_OK)==0) {
strcpy(str, "ROOTFS");
} else if(access("ramdisk-mtk-recovery", R_OK)==0) {
strcpy(str, "RECOVERY");
} else {
exit(1);
}
memcpy(buf+8, str, sizeof(str));
memset(buf+8+sizeof(str), 0xff, 512-8-sizeof(str));
pwrite(ofd, buf, sizeof(buf), pos);
return append_file(ofd, "ramdisk.gz", pos + 512) + 512;
} else if(access("ramdisk.gz", R_OK) == 0) {
return append_file(ofd, "ramdisk.gz", pos);
} else {
return append_file(ofd, "ramdisk", pos);
}
}
void post_process(struct boot_img_hdr *hdr, int ofd, int pos) {
if(access("rkcrc", R_OK) == 0) {
fprintf(stderr, "Rockchip CRCs not supported yet\n");
exit(1);
}
//Round up the file size
ftruncate(ofd, pos);
}
int repack(char *image) {
//TODO: Merge with extract.c?
//{
int ifd = open(image, O_RDONLY);
off_t isize = lseek(ifd, 0, SEEK_END);
lseek(ifd, 0, SEEK_SET);
uint8_t *iorig = mmap(NULL, isize, PROT_READ, MAP_SHARED, ifd, 0);
uint8_t *ibase = iorig;
assert(ibase);
while(ibase<(iorig+isize)) {
if(memcmp(ibase, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0)
break;
ibase += 256;
}
assert(ibase < (iorig+isize));
//}
//
struct boot_img_hdr *ihdr = (struct boot_img_hdr*) ibase;
assert(
ihdr->page_size == 2048 ||
ihdr->page_size == 4096 ||
ihdr->page_size == 16384
);
unlink("new-boot.img");
int ofd = open("new-boot.img", O_RDWR|O_CREAT, 0644);
ftruncate(ofd, ihdr->page_size);
//Write back original header, we'll change it later
write(ofd, ihdr, sizeof(*ihdr));
struct boot_img_hdr *hdr = mmap(NULL, sizeof(*ihdr), PROT_READ|PROT_WRITE, MAP_SHARED, ofd, 0);
//First set everything to zero, so we know where we are at.
hdr->kernel_size = 0;
hdr->ramdisk_size = 0;
hdr->second_size = 0;
hdr->unused[0] = 0;
memset(hdr->id, 0, sizeof(hdr->id)); //Setting id to 0 might be wrong?
int pos = hdr->page_size;
int size = 0;
size = append_file(ofd, "kernel", pos);
pos += size + hdr->page_size - 1;
pos &= ~(hdr->page_size-1);
hdr->kernel_size = size;
size = append_ramdisk(ofd, pos);
pos += size + hdr->page_size - 1;
pos &= ~(hdr->page_size-1);
hdr->ramdisk_size = size;
if(access("second", R_OK) == 0) {
size = append_file(ofd, "second", pos);
pos += size + hdr->page_size - 1;
pos &= ~(hdr->page_size-1);
hdr->second_size = size;
}
if(access("dt", R_OK) == 0) {
size = append_file(ofd, "dt", pos);
pos += size + hdr->page_size - 1;
pos &= ~(hdr->page_size-1);
hdr->unused[0] = size;
}
post_process(hdr, ofd, pos);
munmap(hdr, sizeof(*ihdr));
close(ofd);
return 0;
}

773
jni/daemon/bootstages.c Normal file

File diff suppressed because it is too large Load Diff

208
jni/daemon/daemon.c Normal file
View File

@@ -0,0 +1,208 @@
/* daemon.c - Magisk Daemon
*
* Start the daemon and wait for requests
* Connect the daemon and send requests through sockets
*/
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <selinux/selinux.h>
#include "magisk.h"
#include "utils.h"
#include "daemon.h"
#include "magiskpolicy.h"
pthread_t sepol_patch;
int null_fd;
static void *request_handler(void *args) {
// Setup the default error handler for threads
err_handler = exit_thread;
int client = *((int *) args);
free(args);
client_request req = read_int(client);
struct ucred credentials;
get_client_cred(client, &credentials);
switch (req) {
case LAUNCH_MAGISKHIDE:
case STOP_MAGISKHIDE:
case ADD_HIDELIST:
case RM_HIDELIST:
case POST_FS:
case POST_FS_DATA:
case LATE_START:
if (credentials.uid != 0) {
write_int(client, ROOT_REQUIRED);
close(client);
return NULL;
}
default:
break;
}
switch (req) {
case LAUNCH_MAGISKHIDE:
launch_magiskhide(client);
break;
case STOP_MAGISKHIDE:
stop_magiskhide(client);
break;
case ADD_HIDELIST:
add_hide_list(client);
break;
case RM_HIDELIST:
rm_hide_list(client);
break;
case SUPERUSER:
su_daemon_receiver(client);
break;
case CHECK_VERSION:
write_string(client, MAGISK_VER_STR);
close(client);
break;
case CHECK_VERSION_CODE:
write_int(client, MAGISK_VER_CODE);
close(client);
break;
case POST_FS:
post_fs(client);
break;
case POST_FS_DATA:
post_fs_data(client);
break;
case LATE_START:
late_start(client);
break;
default:
break;
}
// Just in case
close(client);
return NULL;
}
/* Setup the address and return socket fd */
static int setup_socket(struct sockaddr_un *sun) {
int fd = xsocket(AF_LOCAL, SOCK_STREAM, 0);
if (fcntl(fd, F_SETFD, FD_CLOEXEC))
PLOGE("fcntl FD_CLOEXEC");
memset(sun, 0, sizeof(*sun));
sun->sun_family = AF_LOCAL;
memcpy(sun->sun_path, REQUESTOR_DAEMON_PATH, REQUESTOR_DAEMON_PATH_LEN);
return fd;
}
static void *large_sepol_patch(void *args) {
LOGD("sepol: Starting large patch thread\n");
// Patch su to everything
sepol_allow("su", ALL, ALL, ALL);
dump_policydb(SELINUX_LOAD);
LOGD("sepol: Large patch done\n");
destroy_policydb();
return NULL;
}
void start_daemon(int client) {
// Launch the daemon, create new session, set proper context
if (getuid() != UID_ROOT || getgid() != UID_ROOT) {
fprintf(stderr, "Starting daemon requires root: %s\n", strerror(errno));
PLOGE("start daemon");
}
switch (fork()) {
case -1:
PLOGE("fork");
case 0:
break;
default:
return;
}
// First close the client, it's useless for us
close(client);
xsetsid();
setcon("u:r:su:s0");
umask(022);
null_fd = xopen("/dev/null", O_RDWR | O_CLOEXEC);
xdup2(null_fd, STDIN_FILENO);
xdup2(null_fd, STDOUT_FILENO);
xdup2(null_fd, STDERR_FILENO);
// Patch selinux with medium patch before we do anything
load_policydb(SELINUX_POLICY);
sepol_med_rules();
dump_policydb(SELINUX_LOAD);
// Continue the larger patch in another thread, we will join later
pthread_create(&sepol_patch, NULL, large_sepol_patch, NULL);
struct sockaddr_un sun;
int fd = setup_socket(&sun);
xbind(fd, (struct sockaddr*) &sun, sizeof(sun));
xlisten(fd, 10);
// Change process name
strcpy(argv0, "magisk_daemon");
// The root daemon should not do anything if an error occurs
// It should stay intact under any circumstances
err_handler = do_nothing;
LOGI("Magisk v" xstr(MAGISK_VERSION) " daemon started\n");
// Unlock all blocks for rw
unlock_blocks();
// Setup links under /sbin
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
create_links(NULL, "/sbin");
xchmod("/sbin", 0755);
mkdir("/magisk", 0755);
xchmod("/magisk", 0755);
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
// Loop forever to listen for requests
while(1) {
int *client = xmalloc(sizeof(int));
*client = xaccept(fd, NULL, NULL);
// Just in case, set to close on exec
fcntl(*client, F_SETFD, FD_CLOEXEC);
pthread_t thread;
xpthread_create(&thread, NULL, request_handler, client);
// Detach the thread, we will never join it
pthread_detach(thread);
}
}
/* Connect the daemon, and return a socketfd */
int connect_daemon() {
struct sockaddr_un sun;
int fd = setup_socket(&sun);
// LOGD("client: trying to connect socket\n");
if (connect(fd, (struct sockaddr*) &sun, sizeof(sun))) {
/* If we cannot access the daemon, we start the daemon
* since there is no clear entry point when the daemon should be started
*/
LOGD("client: connect fail, try launching new daemon process\n");
start_daemon(fd);
do {
// Wait for 10ms
usleep(10);
} while (connect(fd, (struct sockaddr*) &sun, sizeof(sun)));
}
return fd;
}

79
jni/daemon/daemon.h Normal file
View File

@@ -0,0 +1,79 @@
/* daemon.h - Utility functions for daemon-client communication
*/
#ifndef _DAEMON_H_
#define _DAEMON_H_
#include <pthread.h>
extern pthread_t sepol_patch;
// Commands require connecting to daemon
typedef enum {
DO_NOTHING = 0,
LAUNCH_MAGISKHIDE,
STOP_MAGISKHIDE,
ADD_HIDELIST,
RM_HIDELIST,
SUPERUSER,
CHECK_VERSION,
CHECK_VERSION_CODE,
POST_FS,
POST_FS_DATA,
LATE_START,
TEST
} client_request;
// Return codes for daemon
typedef enum {
DAEMON_ERROR = -1,
DAEMON_SUCCESS = 0,
ROOT_REQUIRED,
HIDE_IS_ENABLED,
HIDE_NOT_ENABLED,
HIDE_ITEM_EXIST,
HIDE_ITEM_NOT_EXIST,
} daemon_response;
// daemon.c
void start_daemon(int client);
int connect_daemon();
// socket_trans.c
int recv_fd(int sockfd);
void send_fd(int sockfd, int fd);
int read_int(int fd);
void write_int(int fd, int val);
char* read_string(int fd);
void write_string(int fd, const char* val);
// log_monitor.c
void monitor_logs();
/***************
* Boot Stages *
***************/
void post_fs(int client);
void post_fs_data(int client);
void late_start(int client);
/**************
* MagiskHide *
**************/
void launch_magiskhide(int client);
void stop_magiskhide(int client);
void add_hide_list(int client);
void rm_hide_list(int client);
/*************
* Superuser *
*************/
void su_daemon_receiver(int client);
#endif

46
jni/daemon/log_monitor.c Normal file
View File

@@ -0,0 +1,46 @@
/* log_monitor.c - New thread to monitor logcat
*
* Open a new thread to call logcat and get logs with tag "Magisk"
* Also, write the logs to a log file for debugging purpose
*
*/
#include <stdio.h>
#include <limits.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/wait.h>
#include "magisk.h"
#include "utils.h"
#include "daemon.h"
static void *logger_thread(void *args) {
// Setup error handler
err_handler = exit_thread;
rename(LOGFILE, LASTLOG);
int log_fd, log_pid;
log_fd = xopen(LOGFILE, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0644);
while (1) {
// Start logcat
char *const command[] = { "logcat", "-s", "Magisk", "-v", "thread", NULL };
log_pid = run_command(0, &log_fd, "/system/bin/logcat", command);
waitpid(log_pid, NULL, 0);
// For some reason it went here, clear buffer and restart
system("logcat -c");
}
// Should never be here, but well...
close(log_fd);
return NULL;
}
/* Start a new thread to monitor logcat and dump to logfile */
void monitor_logs() {
pthread_t thread;
xpthread_create(&thread, NULL, logger_thread, NULL);
pthread_detach(thread);
}

148
jni/daemon/socket_trans.c Normal file
View File

@@ -0,0 +1,148 @@
/* socket_trans.c - Functions to transfer data through socket
*/
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "magisk.h"
#include "utils.h"
#include "daemon.h"
/*
* Receive a file descriptor from a Unix socket.
* Contributed by @mkasick
*
* Returns the file descriptor on success, or -1 if a file
* descriptor was not actually included in the message
*
* On error the function terminates by calling exit(-1)
*/
int recv_fd(int sockfd) {
// Need to receive data from the message, otherwise don't care about it.
char iovbuf;
struct iovec iov = {
.iov_base = &iovbuf,
.iov_len = 1,
};
char cmsgbuf[CMSG_SPACE(sizeof(int))];
struct msghdr msg = {
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = cmsgbuf,
.msg_controllen = sizeof(cmsgbuf),
};
xrecvmsg(sockfd, &msg, MSG_WAITALL);
// Was a control message actually sent?
switch (msg.msg_controllen) {
case 0:
// No, so the file descriptor was closed and won't be used.
return -1;
case sizeof(cmsgbuf):
// Yes, grab the file descriptor from it.
break;
default:
goto error;
}
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
if (cmsg == NULL ||
cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
cmsg->cmsg_level != SOL_SOCKET ||
cmsg->cmsg_type != SCM_RIGHTS) {
error:
LOGE("unable to read fd");
exit(-1);
}
return *(int *)CMSG_DATA(cmsg);
}
/*
* Send a file descriptor through a Unix socket.
* Contributed by @mkasick
*
* On error the function terminates by calling exit(-1)
*
* fd may be -1, in which case the dummy data is sent,
* but no control message with the FD is sent.
*/
void send_fd(int sockfd, int fd) {
// Need to send some data in the message, this will do.
struct iovec iov = {
.iov_base = "",
.iov_len = 1,
};
struct msghdr msg = {
.msg_iov = &iov,
.msg_iovlen = 1,
};
char cmsgbuf[CMSG_SPACE(sizeof(int))];
if (fd != -1) {
// Is the file descriptor actually open?
if (fcntl(fd, F_GETFD) == -1) {
if (errno != EBADF) {
PLOGE("unable to send fd");
}
// It's closed, don't send a control message or sendmsg will EBADF.
} else {
// It's open, send the file descriptor in a control message.
msg.msg_control = cmsgbuf;
msg.msg_controllen = sizeof(cmsgbuf);
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
*(int *)CMSG_DATA(cmsg) = fd;
}
}
xsendmsg(sockfd, &msg, 0);
}
int read_int(int fd) {
int val;
xxread(fd, &val, sizeof(int));
return val;
}
void write_int(int fd, int val) {
if (fd < 0) return;
xwrite(fd, &val, sizeof(int));
}
char* read_string(int fd) {
int len = read_int(fd);
if (len > PATH_MAX || len < 0) {
LOGE("invalid string length %d", len);
exit(1);
}
char* val = xmalloc(sizeof(char) * (len + 1));
xxread(fd, val, len);
val[len] = '\0';
return val;
}
void write_string(int fd, const char* val) {
if (fd < 0) return;
int len = strlen(val);
write_int(fd, len);
xwrite(fd, val, len);
}

93
jni/magisk.h Normal file
View File

@@ -0,0 +1,93 @@
/* magisk.h - Top header
*/
#ifndef _MAGISK_H_
#define _MAGISK_H_
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <android/log.h>
#define MAGISK_VER_STR xstr(MAGISK_VERSION) ":MAGISK"
#define str(a) #a
#define xstr(a) str(a)
#define REQUESTOR_DAEMON_PATH "\0MAGISK"
#define REQUESTOR_DAEMON_PATH_LEN 7
#define LOG_TAG "Magisk"
#ifndef ARG_MAX
#define ARG_MAX 4096
#endif
#define LOGFILE "/cache/magisk.log"
#define LASTLOG "/cache/last_magisk.log"
#define DEBUG_LOG "/data/magisk_debug.log"
#define UNBLOCKFILE "/dev/.magisk.unblock"
#define DISABLEFILE "/cache/.disable_magisk"
#define UNINSTALLER "/cache/magisk_uninstaller.sh"
#define MOUNTPOINT "/magisk"
#define COREDIR MOUNTPOINT "/.core"
#define HOSTSFILE COREDIR "/hosts"
#define HIDELIST COREDIR "/hidelist"
#define MAINIMG "/data/magisk.img"
#define DATABIN "/data/magisk"
#define MANAGERAPK DATABIN "/magisk.apk"
#define MAGISKTMP "/dev/magisk"
#define MIRRDIR MAGISKTMP "/mirror"
#define DUMMDIR MAGISKTMP "/dummy"
#define CACHEMOUNT "/cache/magisk_mount"
#define SELINUX_PATH "/sys/fs/selinux/"
#define SELINUX_ENFORCE SELINUX_PATH "enforce"
#define SELINUX_POLICY SELINUX_PATH "policy"
#define SELINUX_LOAD SELINUX_PATH "load"
#define MAGISKHIDE_PROP "persist.magisk.hide"
// Global handler for PLOGE
extern __thread void (*err_handler)(void);
// Common error handlers
static inline void exit_proc() { exit(1); }
static inline void exit_thread() { pthread_exit(NULL); }
static inline void do_nothing() {}
// Dummy function to depress debug message
static inline void stub(const char *fmt, ...) {}
#ifdef DEBUG
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#else
#define LOGD(...) stub(__VA_ARGS__)
#endif
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define PLOGE(fmt, args...) { LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)); err_handler(); }
extern char *argv0; /* For changing process name */
extern char *applet[];
extern int (*applet_main[]) (int, char *[]);
extern int null_fd;
// Multi-call entrypoints
int magiskhide_main(int argc, char *argv[]);
int magiskpolicy_main(int argc, char *argv[]);
int su_client_main(int argc, char *argv[]);
#ifdef __cplusplus
extern "C" {
#endif
int resetprop_main(int argc, char *argv[]);
#ifdef __cplusplus
}
#endif
#endif

31
jni/magiskboot/Android.mk Normal file
View File

@@ -0,0 +1,31 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := magiskboot
LOCAL_STATIC_LIBRARIES := libz liblzma liblz4 libbz2
LOCAL_C_INCLUDES := \
jni/utils \
jni/ndk-compression/zlib/ \
jni/ndk-compression/xz/src/liblzma/api/ \
jni/ndk-compression/lz4/lib/ \
jni/ndk-compression/bzip2/
LOCAL_SRC_FILES := \
main.c \
unpack.c \
repack.c \
hexpatch.c \
parseimg.c \
compress.c \
utils.c \
cpio.c \
sha1.c \
../utils/xwrap.c \
../utils/vector.c
LOCAL_CFLAGS += -DZLIB_CONST
include $(BUILD_EXECUTABLE)
include jni/ndk-compression/zlib/Android.mk
include jni/ndk-compression/xz/src/liblzma/Android.mk
include jni/ndk-compression/lz4/lib/Android.mk
include jni/ndk-compression/bzip2/Android.mk

View File

@@ -43,7 +43,14 @@ struct boot_img_hdr
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t page_size; /* flash page size we assume */
uint32_t unused[2]; /* future expansion: should be 0 */
uint32_t dt_size; /* device tree in bytes */
/* operating system version and security patch level; for
* version "A.B.C" and patch level "Y-M-D":
* ver = A << 14 | B << 7 | C (7 bits for each of A, B, C)
* lvl = ((Y - 2000) & 127) << 4 | M (7 bits for Y, 4 bits for M)
* os_version = ver << 11 | lvl */
uint32_t os_version;
uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */
@@ -66,10 +73,13 @@ struct boot_img_hdr
** +-----------------+
** | second stage | o pages
** +-----------------+
** | device tree | p pages
** +-----------------+
**
** n = (kernel_size + page_size - 1) / page_size
** m = (ramdisk_size + page_size - 1) / page_size
** o = (second_size + page_size - 1) / page_size
** p = (dt_size + page_size - 1) / page_size
**
** 0. all entities are page_size aligned in flash
** 1. kernel and ramdisk are required (size != 0)
@@ -83,8 +93,10 @@ struct boot_img_hdr
** else: jump to kernel_addr
*/
int extract(char *image);
int repack(char *image);
int hexpatch(char *image, char *from, char *to);
typedef struct mtk_hdr {
uint8_t magic[4]; /* MTK magic */
uint32_t size; /* Size of the content */
uint8_t name[32]; /* The type of the header */
} mtk_hdr;
#endif

569
jni/magiskboot/compress.c Normal file

File diff suppressed because it is too large Load Diff

480
jni/magiskboot/cpio.c Normal file

File diff suppressed because it is too large Load Diff

42
jni/magiskboot/cpio.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef _CPIO_H_
#define _CPIO_H_
#include <stdint.h>
typedef struct cpio_file {
// uint32_t ino;
uint32_t mode;
uint32_t uid;
uint32_t gid;
// uint32_t nlink;
// uint32_t mtime;
uint32_t filesize;
// uint32_t devmajor;
// uint32_t devminor;
// uint32_t rdevmajor;
// uint32_t rdevminor;
uint32_t namesize;
// uint32_t check;
char *filename;
char *data;
int remove;
} cpio_file;
typedef struct cpio_newc_header {
char magic[6];
char ino[8];
char mode[8];
char uid[8];
char gid[8];
char nlink[8];
char mtime[8];
char filesize[8];
char devmajor[8];
char devminor[8];
char rdevmajor[8];
char rdevminor[8];
char namesize[8];
char check[8];
} cpio_newc_header;
#endif

32
jni/magiskboot/hexpatch.c Normal file
View File

@@ -0,0 +1,32 @@
#include "magiskboot.h"
static void hex2byte(const char *hex, unsigned char *str) {
char high, low;
for (int i = 0, length = strlen(hex); i < length; i += 2) {
high = toupper(hex[i]) - '0';
low = toupper(hex[i + 1]) - '0';
str[i / 2] = ((high > 9 ? high - 7 : high) << 4) + (low > 9 ? low - 7 : low);
}
}
void hexpatch(const char *image, const char *from, const char *to) {
int patternsize = strlen(from) / 2, patchsize = strlen(to) / 2;
size_t filesize;
unsigned char *file, *pattern, *patch;
mmap_rw(image, &file, &filesize);
pattern = xmalloc(patternsize);
patch = xmalloc(patchsize);
hex2byte(from, pattern);
hex2byte(to, patch);
for (size_t i = 0; i < filesize - patternsize; ++i) {
if (memcmp(file + i, pattern, patternsize) == 0) {
printf("Pattern %s found!\nPatching to %s\n", from, to);
memset(file + i, 0, patternsize);
memcpy(file + i, patch, patchsize);
i += patternsize - 1;
}
}
munmap(file, filesize);
free(pattern);
free(patch);
}

10
jni/magiskboot/magisk.h Normal file
View File

@@ -0,0 +1,10 @@
/* magisk.h - Let MagiskBoot use the same error handling API as main magisk program
*/
#ifndef _MAGISK_H_
#define _MAGISK_H_
#define LOGE(err, ...) { fprintf(stderr, __VA_ARGS__); exit(err); }
#define PLOGE(fmt, args...) { fprintf(stderr, fmt " failed with %d: %s\n\n", ##args, errno, strerror(errno)); exit(1); }
#endif

Some files were not shown because too many files have changed in this diff Show More