mirror of
https://github.com/topjohnwu/Magisk
synced 2025-10-27 04:02:14 +01:00
Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d53f33bed8 | ||
|
|
02e039d792 | ||
|
|
9f9333315e | ||
|
|
0d10b812fe | ||
|
|
b4fe4f3d10 | ||
|
|
ba93fcbda0 | ||
|
|
88d19a4ca4 | ||
|
|
af7b9ea898 | ||
|
|
09cd0468cf | ||
|
|
529aa754f5 | ||
|
|
3c7e865555 | ||
|
|
7877ac0c3b | ||
|
|
1442e29d0e | ||
|
|
9a7e9b736e | ||
|
|
c421e45fa0 | ||
|
|
8833d21ac3 | ||
|
|
1a3c522c94 | ||
|
|
c55aa92d4f | ||
|
|
212a303347 | ||
|
|
3f3568d8af | ||
|
|
1e3bcfc8cd | ||
|
|
a4ce9f6f05 | ||
|
|
65dc99744e | ||
|
|
c6d4740b0c | ||
|
|
9f91c8b59d | ||
|
|
2b3b087c29 | ||
|
|
e08d46aa76 | ||
|
|
feccc97a14 | ||
|
|
77eec3d21d | ||
|
|
ecaafd1b70 | ||
|
|
0d51997e46 | ||
|
|
463cbceb07 | ||
|
|
1437c5c63f | ||
|
|
52f1d50902 | ||
|
|
a839cb787e | ||
|
|
f621fb2060 | ||
|
|
2ccd8b8838 | ||
|
|
7ef0746c52 | ||
|
|
6f609f0dd7 | ||
|
|
ee2a30470a | ||
|
|
e11fb2c09e | ||
|
|
c6e9270590 | ||
|
|
3e2e171407 | ||
|
|
332f531a10 | ||
|
|
bae2c9bc63 | ||
|
|
5ac68f8df8 | ||
|
|
06d3b94804 | ||
|
|
e7c314fefc | ||
|
|
faab79b41a | ||
|
|
14204c9bfc | ||
|
|
45dbd4464b | ||
|
|
472255924a | ||
|
|
6d3ac2aa55 | ||
|
|
9ad03994d1 | ||
|
|
35228f80b8 | ||
|
|
69ded881c6 | ||
|
|
d9bce45db4 | ||
|
|
5e92b4faa9 | ||
|
|
db501822ef | ||
|
|
ef9948a967 | ||
|
|
298f09402f | ||
|
|
d4149d4b7a | ||
|
|
3315228a90 | ||
|
|
f72205c401 | ||
|
|
11862bbaee |
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -10,8 +10,7 @@
|
||||
*.cmd text eol=crlf
|
||||
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
busybox binary
|
||||
futility binary
|
||||
binaries/** binary
|
||||
*.jar binary
|
||||
*.exe binary
|
||||
*.apk binary
|
||||
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -2,20 +2,21 @@ obj/
|
||||
libs/
|
||||
*.zip
|
||||
|
||||
# Generated binaries
|
||||
# Copied binaries
|
||||
zip_static/arm/*
|
||||
zip_static/arm64/*
|
||||
zip_static/x86/*
|
||||
zip_static/x64/*
|
||||
zip_static/chromeos/*
|
||||
uninstaller/arm/*
|
||||
uninstaller/arm64/*
|
||||
uninstaller/x86/*
|
||||
uninstaller/x64/*
|
||||
uninstaller/chromeos/*
|
||||
ziptools/zipadjust
|
||||
|
||||
# Generated scripts
|
||||
zip_static/common/magic_mask.sh
|
||||
uninstaller/common/
|
||||
zip_static/common/*.sh
|
||||
zip_static/common/*.rc
|
||||
zip_static/META-INF/com/google/android/update-binary
|
||||
|
||||
# Leave all busybox!
|
||||
!busybox
|
||||
|
||||
14
.gitmodules
vendored
14
.gitmodules
vendored
@@ -1,12 +1,12 @@
|
||||
[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
|
||||
|
||||
BIN
binaries/busybox-arm
Normal file
BIN
binaries/busybox-arm
Normal file
Binary file not shown.
BIN
binaries/busybox-arm64
Normal file
BIN
binaries/busybox-arm64
Normal file
Binary file not shown.
BIN
binaries/busybox-x64
Normal file
BIN
binaries/busybox-x64
Normal file
Binary file not shown.
BIN
binaries/busybox-x86
Normal file
BIN
binaries/busybox-x86
Normal file
Binary file not shown.
53
build.cmd
53
build.cmd
@@ -53,14 +53,14 @@ EXIT /B %ERRORLEVEL%
|
||||
ECHO ************************
|
||||
ECHO * Copying binaries
|
||||
ECHO ************************
|
||||
COPY /Y libs\armeabi\* 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\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
|
||||
CALL :mkcp libs\armeabi-v7a\* zip_static\arm
|
||||
CALL :mkcp libs\arm64-v8a\* zip_static\arm64
|
||||
CALL :mkcp libs\x86\* zip_static\x86
|
||||
CALL :mkcp libs\x86_64\* zip_static\x64
|
||||
CALL :mkcp libs\armeabi-v7a\magiskboot uninstaller\arm
|
||||
CALL :mkcp libs\arm64-v8a\magiskboot uninstaller\arm64
|
||||
CALL :mkcp libs\x86\magiskboot uninstaller\x86
|
||||
CALL :mkcp libs\x86_64\magiskboot uninstaller\x64
|
||||
EXIT /B %ERRORLEVEL%
|
||||
|
||||
:clean
|
||||
@@ -69,16 +69,20 @@ EXIT /B %ERRORLEVEL%
|
||||
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 RMDIR /S /Q zip_static\arm
|
||||
2>NUL RMDIR /S /Q zip_static\arm64
|
||||
2>NUL RMDIR /S /Q zip_static\x86
|
||||
2>NUL RMDIR /S /Q zip_static\x64
|
||||
2>NUL RMDIR /S /Q zip_static\chromeos
|
||||
2>NUL DEL zip_static\META-INF\com\google\android\update-binary
|
||||
2>NUL DEL zip_static\common\magic_mask.sh
|
||||
2>NUL DEL zip_static\common\*.sh
|
||||
2>NUL DEL zip_static\common\*.rc
|
||||
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
|
||||
2>NUL RMDIR /S /Q uninstaller\chromeos
|
||||
EXIT /B 0
|
||||
|
||||
:zip
|
||||
@@ -88,7 +92,7 @@ EXIT /B %ERRORLEVEL%
|
||||
CALL :usage
|
||||
EXIT /B %ERRORLEVEL%
|
||||
)
|
||||
IF NOT EXIST "zip_static\arm\bootimgtools" CALL :error "Missing binaries! Please run '%me% build' before zipping!"
|
||||
IF NOT EXIST "zip_static\arm\magiskboot" CALL :error "Missing binaries! Please run '%me% build' before zipping!"
|
||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||
ECHO ************************
|
||||
ECHO * Adding version info
|
||||
@@ -96,6 +100,16 @@ EXIT /B %ERRORLEVEL%
|
||||
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 * Copying Files
|
||||
ECHO ************************
|
||||
COPY /Y scripts\ramdisk_patch.sh zip_static\common\ramdisk_patch.sh
|
||||
COPY /Y scripts\init.magisk.rc zip_static\common\init.magisk.rc
|
||||
COPY /Y binaries\busybox-arm zip_static\arm\busybox
|
||||
COPY /Y binaries\busybox-arm64 zip_static\arm64\busybox
|
||||
COPY /Y binaries\busybox-x86 zip_static\x86\busybox
|
||||
COPY /Y binaries\busybox-x64 zip_static\x64\busybox
|
||||
CALL :mkcp binaries\chromeos zip_static\chromeos
|
||||
ECHO ************************
|
||||
ECHO * Zipping Magisk v%~1
|
||||
ECHO ************************
|
||||
CD zip_static
|
||||
@@ -107,9 +121,18 @@ EXIT /B %ERRORLEVEL%
|
||||
|
||||
:uninstaller
|
||||
SET OK=y
|
||||
IF NOT EXIST "uninstaller\arm\bootimgtools" CALL :error "Missing binaries! Please run '%me% build' before zipping!"
|
||||
IF NOT EXIST "uninstaller\arm\magiskboot" CALL :error "Missing binaries! Please run '%me% build' before zipping!"
|
||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||
ECHO ************************
|
||||
ECHO * Copying Files
|
||||
ECHO ************************
|
||||
CALL :mkcp scripts\magisk_uninstaller.sh uninstaller\common
|
||||
COPY /Y binaries\busybox-arm uninstaller\arm\busybox
|
||||
COPY /Y binaries\busybox-arm64 uninstaller\arm64\busybox
|
||||
COPY /Y binaries\busybox-x86 uninstaller\x86\busybox
|
||||
COPY /Y binaries\busybox-x64 uninstaller\x64\busybox
|
||||
CALL :mkcp binaries\chromeos uninstaller\chromeos
|
||||
ECHO ************************
|
||||
ECHO * Zipping uninstaller
|
||||
ECHO ************************
|
||||
FOR /F "tokens=* USEBACKQ" %%F IN (`ziptools\win_bin\date "+%%Y%%m%%d"`) DO (set timestamp=%%F)
|
||||
|
||||
50
build.sh
50
build.sh
@@ -20,16 +20,20 @@ cleanup() {
|
||||
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/magic_mask.sh
|
||||
rm -rfv zip_static/arm
|
||||
rm -rfv zip_static/arm64
|
||||
rm -rfv zip_static/x86
|
||||
rm -rfv zip_static/x64
|
||||
rm -rfv zip_static/chromeos
|
||||
rm -rfv zip_static/META-INF/com/google/android/update-binary
|
||||
rm -rfv zip_static/common/*.sh
|
||||
rm -rfv zip_static/common/*.rc
|
||||
rm -rfv uninstaller/common
|
||||
rm -rfv uninstaller/arm
|
||||
rm -rfv uninstaller/arm64
|
||||
rm -rfv uninstaller/x86
|
||||
rm -rfv uninstaller/x64
|
||||
rm -rfv uninstaller/chromeos
|
||||
}
|
||||
|
||||
mkcp() {
|
||||
@@ -51,24 +55,34 @@ build_bin() {
|
||||
echo "************************"
|
||||
echo "* Copying binaries"
|
||||
echo "************************"
|
||||
mkcp "libs/armeabi/*" zip_static/arm
|
||||
mkcp libs/armeabi/bootimgtools uninstaller/arm
|
||||
mkcp "libs/armeabi-v7a/*" zip_static/arm
|
||||
mkcp libs/armeabi-v7a/magiskboot uninstaller/arm
|
||||
mkcp "libs/arm64-v8a/*" zip_static/arm64
|
||||
mkcp libs/arm64-v8a/bootimgtools uninstaller/arm64
|
||||
mkcp libs/arm64-v8a/magiskboot uninstaller/arm64
|
||||
mkcp "libs/x86/*" zip_static/x86
|
||||
mkcp libs/x86/bootimgtools uninstaller/x86
|
||||
mkcp libs/x86/magiskboot uninstaller/x86
|
||||
mkcp "libs/x86_64/*" zip_static/x64
|
||||
mkcp libs/x86_64/bootimgtools uninstaller/x64
|
||||
mkcp libs/x86_64/magiskboot uninstaller/x64
|
||||
}
|
||||
|
||||
zip_package() {
|
||||
[ ! -f "zip_static/arm/bootimgtools" ] && error "Missing binaries!! Please run '$0 build' before zipping"
|
||||
[ ! -f "zip_static/arm/magiskboot" ] && 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 "* Copying files"
|
||||
echo "************************"
|
||||
cp -afv scripts/ramdisk_patch.sh zip_static/common/ramdisk_patch.sh
|
||||
cp -afv scripts/init.magisk.rc zip_static/common/init.magisk.rc
|
||||
cp -afv binaries/busybox-arm zip_static/arm/busybox
|
||||
cp -afv binaries/busybox-arm64 zip_static/arm64/busybox
|
||||
cp -afv binaries/busybox-x86 zip_static/x86/busybox
|
||||
cp -afv binaries/busybox-x64 zip_static/x64/busybox
|
||||
cp -afv binaries/chromeos/. zip_static/chromeos
|
||||
echo "************************"
|
||||
echo "* Zipping Magisk v$1"
|
||||
echo "************************"
|
||||
cd zip_static
|
||||
@@ -81,10 +95,20 @@ zip_package() {
|
||||
}
|
||||
|
||||
zip_uninstaller() {
|
||||
[ ! -f "uninstaller/arm/bootimgtools" ] && error "Missing binaries!! Please run '$0 build' before zipping"
|
||||
[ ! -f "uninstaller/arm/magiskboot" ] && error "Missing binaries!! Please run '$0 build' before zipping"
|
||||
echo "************************"
|
||||
echo "* Copying files"
|
||||
echo "************************"
|
||||
mkcp scripts/magisk_uninstaller.sh uninstaller/common
|
||||
cp -afv binaries/busybox-arm uninstaller/arm/busybox
|
||||
cp -afv binaries/busybox-arm64 uninstaller/arm64/busybox
|
||||
cp -afv binaries/busybox-x86 uninstaller/x86/busybox
|
||||
cp -afv binaries/busybox-x64 uninstaller/x64/busybox
|
||||
cp -afv binaries/chromeos/. zip_static/chromeos
|
||||
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 {} \;
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include jni/bootimgtools/Android.mk
|
||||
include jni/magiskboot/Android.mk
|
||||
include jni/magiskhide/Android.mk
|
||||
include jni/resetprop/Android.mk
|
||||
include jni/sepolicy-inject/Android.mk
|
||||
include jni/magiskpolicy/Android.mk
|
||||
include jni/su/Android.mk
|
||||
|
||||
include jni/selinux/libsepol/Android.mk
|
||||
include jni/selinux/libselinux/Android.mk
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
APP_ABI := x86 x86_64 armeabi arm64-v8a
|
||||
APP_PIE = true
|
||||
APP_ABI := x86 x86_64 armeabi-v7a arm64-v8a
|
||||
APP_PLATFORM := android-21
|
||||
APP_CPPFLAGS += -std=c++11
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
19
jni/magiskboot/Android.mk
Normal file
19
jni/magiskboot/Android.mk
Normal file
@@ -0,0 +1,19 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := magiskboot
|
||||
LOCAL_STATIC_LIBRARIES := libz liblzma liblz4 libbz2
|
||||
LOCAL_C_INCLUDES := \
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
479
jni/magiskboot/compress.c
Normal file
479
jni/magiskboot/compress.c
Normal file
File diff suppressed because it is too large
Load Diff
480
jni/magiskboot/cpio.c
Normal file
480
jni/magiskboot/cpio.c
Normal file
File diff suppressed because it is too large
Load Diff
42
jni/magiskboot/cpio.h
Normal file
42
jni/magiskboot/cpio.h
Normal 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
|
||||
151
jni/magiskboot/elf.h
Normal file
151
jni/magiskboot/elf.h
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
#ifndef _ELF_H_
|
||||
#define _ELF_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
** ELF structure
|
||||
**
|
||||
** +-----------------+
|
||||
** | ELF magic | | 4 bytes
|
||||
** +------------ +
|
||||
** | ELF class | | 1 byte
|
||||
** +------------ +
|
||||
** | ELF header |
|
||||
** +-----------------+
|
||||
** ~
|
||||
** +-----------------+
|
||||
** | program header | kernel info
|
||||
** +-----------------+
|
||||
** | program header | ramdisk info
|
||||
** +-----------------+
|
||||
** | program header | dtb info
|
||||
** +-----------------+
|
||||
** | program header | (possible) cmdline info
|
||||
** +-----------------+
|
||||
** ~
|
||||
** +-----------------+
|
||||
** | section header | cmdline info
|
||||
** +-----------------+
|
||||
** ~
|
||||
** +-----------------+
|
||||
** | |
|
||||
** | Data |
|
||||
** | |
|
||||
** +-----------------+
|
||||
|
||||
*/
|
||||
|
||||
typedef uint32_t elf32_addr;
|
||||
typedef uint16_t elf32_half;
|
||||
typedef uint32_t elf32_off;
|
||||
typedef uint32_t elf32_word;
|
||||
|
||||
typedef uint64_t elf64_addr;
|
||||
typedef uint16_t elf64_half;
|
||||
typedef uint64_t elf64_off;
|
||||
typedef uint32_t elf64_word;
|
||||
typedef uint64_t elf64_xword;
|
||||
|
||||
#define ELF_MAGIC "\x7f""ELF"
|
||||
#define ELF_MAGIC_SIZE 4
|
||||
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EI_VERSION 6
|
||||
#define EI_OSABI 7
|
||||
#define EI_PAD 8
|
||||
|
||||
#define ELFCLASSNONE 0
|
||||
#define ELFCLASS32 1
|
||||
#define ELFCLASS64 2
|
||||
#define ELFCLASSNUM 3
|
||||
|
||||
#define ET_EXEC 2
|
||||
#define EM_ARM 40
|
||||
#define EI_NIDENT 16
|
||||
|
||||
typedef struct elf32_ehdr {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
elf32_half e_type;
|
||||
elf32_half e_machine;
|
||||
elf32_word e_version;
|
||||
elf32_addr e_entry; /* Entry point */
|
||||
elf32_off e_phoff;
|
||||
elf32_off e_shoff;
|
||||
elf32_word e_flags;
|
||||
elf32_half e_ehsize;
|
||||
elf32_half e_phentsize;
|
||||
elf32_half e_phnum;
|
||||
elf32_half e_shentsize;
|
||||
elf32_half e_shnum;
|
||||
elf32_half e_shstrndx;
|
||||
} elf32_ehdr;
|
||||
|
||||
typedef struct elf64_ehdr {
|
||||
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
|
||||
elf64_half e_type;
|
||||
elf64_half e_machine;
|
||||
elf64_word e_version;
|
||||
elf64_addr e_entry; /* Entry point virtual address */
|
||||
elf64_off e_phoff; /* Program header table file offset */
|
||||
elf64_off e_shoff; /* Section header table file offset */
|
||||
elf64_word e_flags;
|
||||
elf64_half e_ehsize;
|
||||
elf64_half e_phentsize;
|
||||
elf64_half e_phnum;
|
||||
elf64_half e_shentsize;
|
||||
elf64_half e_shnum;
|
||||
elf64_half e_shstrndx;
|
||||
} elf64_ehdr;
|
||||
|
||||
typedef struct elf32_phdr {
|
||||
elf32_word p_type;
|
||||
elf32_off p_offset;
|
||||
elf32_addr p_vaddr;
|
||||
elf32_addr p_paddr;
|
||||
elf32_word p_filesz;
|
||||
elf32_word p_memsz;
|
||||
elf32_word p_flags;
|
||||
elf32_word p_align;
|
||||
} elf32_phdr;
|
||||
|
||||
typedef struct elf64_phdr {
|
||||
elf64_word p_type;
|
||||
elf64_word p_flags;
|
||||
elf64_off p_offset; /* Segment file offset */
|
||||
elf64_addr p_vaddr; /* Segment virtual address */
|
||||
elf64_addr p_paddr; /* Segment physical address */
|
||||
elf64_xword p_filesz; /* Segment size in file */
|
||||
elf64_xword p_memsz; /* Segment size in memory */
|
||||
elf64_xword p_align; /* Segment alignment, file & memory */
|
||||
} elf64_phdr;
|
||||
|
||||
typedef struct elf32_shdr {
|
||||
elf32_word s_name;
|
||||
elf32_word s_type;
|
||||
elf32_word s_flags;
|
||||
elf32_addr s_addr;
|
||||
elf32_off s_offset;
|
||||
elf32_word s_size;
|
||||
elf32_word s_link;
|
||||
elf32_word s_info;
|
||||
elf32_word s_addralign;
|
||||
elf32_word s_entsize;
|
||||
} elf32_shdr;
|
||||
|
||||
typedef struct elf64_shdr {
|
||||
elf64_word s_name; /* Section name, index in string tbl */
|
||||
elf64_word s_type; /* Type of section */
|
||||
elf64_xword s_flags; /* Miscellaneous section attributes */
|
||||
elf64_addr s_addr; /* Section virtual addr at execution */
|
||||
elf64_off s_offset; /* Section file offset */
|
||||
elf64_xword s_size; /* Size of section in bytes */
|
||||
elf64_word s_link; /* Index of another section */
|
||||
elf64_word s_info; /* Additional section information */
|
||||
elf64_xword s_addralign; /* Section alignment */
|
||||
elf64_xword s_entsize; /* Entry size if section holds table */
|
||||
} elf64_shdr;
|
||||
|
||||
#endif
|
||||
32
jni/magiskboot/hexpatch.c
Normal file
32
jni/magiskboot/hexpatch.c
Normal 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 = malloc(patternsize);
|
||||
patch = malloc(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);
|
||||
}
|
||||
127
jni/magiskboot/magiskboot.h
Normal file
127
jni/magiskboot/magiskboot.h
Normal file
@@ -0,0 +1,127 @@
|
||||
#ifndef _MAGISKBOOT_H_
|
||||
#define _MAGISKBOOT_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bootimg.h"
|
||||
#include "sha1.h"
|
||||
|
||||
#define windowBits 15
|
||||
#define ZLIB_GZIP 16
|
||||
#define memLevel 8
|
||||
#define CHUNK 0x40000
|
||||
|
||||
#define LZ4_HEADER_SIZE 19
|
||||
#define LZ4_FOOTER_SIZE 4
|
||||
|
||||
#define CHROMEOS_MAGIC "CHROMEOS"
|
||||
#define CHROMEOS_MAGIC_SIZE 8
|
||||
|
||||
#define KERNEL_FILE "kernel"
|
||||
#define RAMDISK_FILE "ramdisk.cpio"
|
||||
#define SECOND_FILE "second"
|
||||
#define DTB_FILE "dtb"
|
||||
#define NEW_BOOT "new-boot.img"
|
||||
|
||||
#define SUP_LIST "gzip, xz, lzma, lz4, bzip2"
|
||||
#define SUP_NUM 5
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
CHROMEOS,
|
||||
AOSP,
|
||||
ELF,
|
||||
GZIP,
|
||||
LZOP,
|
||||
XZ,
|
||||
LZMA,
|
||||
BZIP2,
|
||||
LZ4,
|
||||
MTK,
|
||||
QCDT,
|
||||
} file_t;
|
||||
|
||||
typedef enum {
|
||||
NONE,
|
||||
RM,
|
||||
MKDIR,
|
||||
ADD,
|
||||
EXTRACT,
|
||||
TEST,
|
||||
DMVERITY,
|
||||
FORCEENCRYPT,
|
||||
BACKUP,
|
||||
RESTORE
|
||||
} command_t;
|
||||
|
||||
extern char *SUP_EXT_LIST[SUP_NUM];
|
||||
extern file_t SUP_TYPE_LIST[SUP_NUM];
|
||||
// Cannot declare in header, but place a copy here for convenience
|
||||
// char *SUP_EXT_LIST[SUP_NUM] = { "gz", "xz", "lzma", "bz2", "lz4" };
|
||||
// file_t SUP_TYPE_LIST[SUP_NUM] = { GZIP, XZ, LZMA, BZIP2, LZ4 };
|
||||
|
||||
// Vector
|
||||
typedef struct vector {
|
||||
size_t size;
|
||||
size_t cap;
|
||||
void **data;
|
||||
} vector;
|
||||
void vec_init(vector *v);
|
||||
void vec_push_back(vector *v, void *p);
|
||||
void vec_sort(vector *v, int (*compar)(const void *, const void *));
|
||||
void vec_destroy(vector *v);
|
||||
|
||||
#define vec_size(v) (v)->size
|
||||
#define vec_cap(v) (v)->cap
|
||||
#define vec_entry(v) (v)->data
|
||||
// vec_for_each(vector *v, void *e)
|
||||
#define vec_for_each(v, e) \
|
||||
e = (v)->data[0]; \
|
||||
for (size_t _i = 0; _i < (v)->size; ++_i, e = (v)->data[_i])
|
||||
|
||||
// Global variables
|
||||
extern unsigned char *kernel, *ramdisk, *second, *dtb, *extra;
|
||||
extern boot_img_hdr hdr;
|
||||
extern file_t boot_type, ramdisk_type, dtb_type;
|
||||
extern int mtk_kernel, mtk_ramdisk;
|
||||
|
||||
// Main entries
|
||||
void unpack(const char *image);
|
||||
void repack(const char* orig_image, const char* out_image);
|
||||
void hexpatch(const char *image, const char *from, const char *to);
|
||||
void error(int rc, const char *msg, ...);
|
||||
void parse_img(unsigned char *orig, size_t size);
|
||||
int cpio_commands(const char *command, int argc, char *argv[]);
|
||||
void cleanup();
|
||||
|
||||
// Compressions
|
||||
void gzip(int mode, const char* filename, const unsigned char* buf, size_t size);
|
||||
void lzma(int mode, const char* filename, const unsigned char* buf, size_t size);
|
||||
void lz4(int mode, const char* filename, const unsigned char* buf, size_t size);
|
||||
void bzip2(int mode, const char* filename, const unsigned char* buf, size_t size);
|
||||
int comp(file_t type, const char *to, const unsigned char *from, size_t size);
|
||||
void comp_file(const char *method, const char *from, const char *to);
|
||||
int decomp(file_t type, const char *to, const unsigned char *from, size_t size);
|
||||
void decomp_file(char *from, const char *to);
|
||||
|
||||
// Utils
|
||||
void mmap_ro(const char *filename, unsigned char **buf, size_t *size);
|
||||
void mmap_rw(const char *filename, unsigned char **buf, size_t *size);
|
||||
file_t check_type(const unsigned char *buf);
|
||||
void write_zero(int fd, size_t size);
|
||||
void mem_align(size_t *pos, size_t align);
|
||||
void file_align(int fd, size_t align, int out);
|
||||
int open_new(const char *filename);
|
||||
void print_info();
|
||||
|
||||
#endif
|
||||
104
jni/magiskboot/main.c
Normal file
104
jni/magiskboot/main.c
Normal file
@@ -0,0 +1,104 @@
|
||||
#include "magiskboot.h"
|
||||
|
||||
/********************
|
||||
Patch Boot Image
|
||||
*********************/
|
||||
|
||||
static void usage(char *arg0) {
|
||||
fprintf(stderr, "%s --unpack <bootimg>\n", arg0);
|
||||
fprintf(stderr, " Unpack <bootimg> to kernel, ramdisk.cpio, (second), (dtb) into the\n current directory\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --repack <origbootimg> [outbootimg]\n", arg0);
|
||||
fprintf(stderr, " Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n");
|
||||
fprintf(stderr, " to [outbootimg], or new-boot.img if not specified.\n");
|
||||
fprintf(stderr, " It will compress ramdisk.cpio with the same method used in <origbootimg>\n");
|
||||
fprintf(stderr, " if exists, or attempt to find ramdisk.cpio.[ext], and repack\n");
|
||||
fprintf(stderr, " directly with the compressed ramdisk file\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --hexpatch <file> <hexpattern1> <hexpattern2>\n", arg0);
|
||||
fprintf(stderr, " Search <hexpattern1> in <file>, and replace with <hexpattern2>\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --cpio-<cmd> <incpio> [flags...] [params...]\n", arg0);
|
||||
fprintf(stderr, " Do cpio related cmds to <incpio> (modifications are done directly)\n Supported commands:\n");
|
||||
fprintf(stderr, " --cpio-rm <incpio> [-r] <entry>\n Remove entry from cpio, flag -r to remove recursively\n");
|
||||
fprintf(stderr, " --cpio-mkdir <incpio> <mode> <entry>\n Create directory as an <entry>\n");
|
||||
fprintf(stderr, " --cpio-add <incpio> <mode> <entry> <infile>\n Add <infile> as an <entry>; replaces <entry> if already exists\n");
|
||||
fprintf(stderr, " --cpio-extract <incpio> <entry> <outfile>\n Extract <entry> to <outfile>\n");
|
||||
fprintf(stderr, " --cpio-test <incpio>\n Return value: 0/not patched 1/Magisk 2/SuperSU\n");
|
||||
fprintf(stderr, " --cpio-patch-dmverity <incpio>\n Remove dm-verity\n");
|
||||
fprintf(stderr, " --cpio-patch-forceencrypt <incpio>\n Change forceencrypt flag to encryptable\n");
|
||||
fprintf(stderr, " --cpio-backup <incpio> <origcpio>\n Create ramdisk backups into <incpio> from <origcpio>\n");
|
||||
fprintf(stderr, " --cpio-restore <incpio>\n Restore ramdisk from ramdisk backup within <incpio>\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --compress[=method] <infile> [outfile]\n", arg0);
|
||||
fprintf(stderr, " Compress <infile> with [method](default: gzip), optionally to [outfile]\n Supported methods: " SUP_LIST "\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --decompress <infile> [outfile]\n", arg0);
|
||||
fprintf(stderr, " Detect method and decompress <infile>, optionally to [outfile]\n Supported methods: " SUP_LIST "\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --sha1 <file>\n", arg0);
|
||||
fprintf(stderr, " Print the SHA1 checksum for <file>\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "%s --cleanup\n", arg0);
|
||||
fprintf(stderr, " Cleanup the current working directory\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void error(int rc, const char *msg, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, msg, ap);
|
||||
fprintf(stderr,"\n\n");
|
||||
va_end(ap);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("MagiskBoot (by topjohnwu) - Boot Image Modification Tool\n\n");
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "--cleanup") == 0) {
|
||||
cleanup();
|
||||
} else if (argc > 2 && strcmp(argv[1], "--sha1") == 0) {
|
||||
char sha1[21], *buf;
|
||||
size_t size;
|
||||
mmap_ro(argv[2], (unsigned char **) &buf, &size);
|
||||
SHA1(sha1, buf, size);
|
||||
for (int i = 0; i < 20; ++i)
|
||||
printf("%02x", sha1[i]);
|
||||
printf("\n");
|
||||
munmap(buf, size);
|
||||
} else if (argc > 2 && strcmp(argv[1], "--unpack") == 0) {
|
||||
unpack(argv[2]);
|
||||
} else if (argc > 2 && strcmp(argv[1], "--repack") == 0) {
|
||||
repack(argv[2], argc > 3 ? argv[3] : NEW_BOOT);
|
||||
} else if (argc > 2 && strcmp(argv[1], "--decompress") == 0) {
|
||||
decomp_file(argv[2], argc > 3 ? argv[3] : NULL);
|
||||
} else if (argc > 2 && strncmp(argv[1], "--compress", 10) == 0) {
|
||||
char *method;
|
||||
method = strchr(argv[1], '=');
|
||||
if (method == NULL) method = "gzip";
|
||||
else method++;
|
||||
comp_file(method, argv[2], argc > 3 ? argv[3] : NULL);
|
||||
} else if (argc > 4 && strcmp(argv[1], "--hexpatch") == 0) {
|
||||
hexpatch(argv[2], argv[3], argv[4]);
|
||||
} else if (argc > 2 && strncmp(argv[1], "--cpio", 6) == 0) {
|
||||
char *command;
|
||||
command = strchr(argv[1] + 2, '-');
|
||||
if (command == NULL) usage(argv[0]);
|
||||
else ++command;
|
||||
if (cpio_commands(command, argc - 2, argv + 2)) usage(argv[0]);
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
252
jni/magiskboot/parseimg.c
Normal file
252
jni/magiskboot/parseimg.c
Normal file
@@ -0,0 +1,252 @@
|
||||
#include "bootimg.h"
|
||||
#include "elf.h"
|
||||
#include "magiskboot.h"
|
||||
|
||||
unsigned char *kernel, *ramdisk, *second, *dtb, *extra;
|
||||
boot_img_hdr hdr;
|
||||
int mtk_kernel = 0, mtk_ramdisk = 0;
|
||||
file_t boot_type, ramdisk_type, dtb_type;
|
||||
|
||||
static void check_headers() {
|
||||
// Check ramdisk compression type
|
||||
ramdisk_type = check_type(ramdisk);
|
||||
|
||||
// Check MTK
|
||||
if (check_type(kernel) == MTK) {
|
||||
printf("MTK header found in kernel\n");
|
||||
mtk_kernel = 1;
|
||||
}
|
||||
if (check_type(ramdisk) == MTK) {
|
||||
printf("MTK header found in ramdisk\n");
|
||||
mtk_ramdisk = 1;
|
||||
}
|
||||
|
||||
// Check dtb if ELF boot
|
||||
if (boot_type == ELF && hdr.dt_size) {
|
||||
dtb_type = check_type(dtb);
|
||||
}
|
||||
|
||||
// Print info
|
||||
print_info();
|
||||
}
|
||||
|
||||
static void elf_header_check(void *elf, int is64) {
|
||||
|
||||
size_t e_size, mach, ver, p_size, p_num, s_size, s_num;
|
||||
size_t r_e_size, r_p_size, r_s_size;
|
||||
|
||||
if (is64) {
|
||||
e_size = ((elf64_ehdr *) elf)->e_ehsize;
|
||||
mach = ((elf64_ehdr *) elf)->e_machine;
|
||||
ver = ((elf64_ehdr *) elf)->e_version;
|
||||
p_size = ((elf64_ehdr *) elf)->e_phentsize;
|
||||
p_num = ((elf64_ehdr *) elf)->e_phnum;
|
||||
s_size = ((elf64_ehdr *) elf)->e_shentsize;
|
||||
s_num = ((elf64_ehdr *) elf)->e_shnum;
|
||||
r_e_size = sizeof(elf64_ehdr);
|
||||
r_p_size = sizeof(elf64_phdr);
|
||||
r_s_size = sizeof(elf64_shdr);
|
||||
} else {
|
||||
e_size = ((elf32_ehdr *) elf)->e_ehsize;
|
||||
mach = ((elf32_ehdr *) elf)->e_machine;
|
||||
ver = ((elf32_ehdr *) elf)->e_version;
|
||||
p_size = ((elf32_ehdr *) elf)->e_phentsize;
|
||||
p_num = ((elf32_ehdr *) elf)->e_phnum;
|
||||
s_size = ((elf32_ehdr *) elf)->e_shentsize;
|
||||
s_num = ((elf32_ehdr *) elf)->e_shnum;
|
||||
r_e_size = sizeof(elf32_ehdr);
|
||||
r_p_size = sizeof(elf32_phdr);
|
||||
r_s_size = sizeof(elf32_shdr);
|
||||
}
|
||||
|
||||
if (e_size != r_e_size)
|
||||
error(1, "Header size not %d", r_e_size);
|
||||
|
||||
if (mach != EM_ARM)
|
||||
error(1, "ELF machine is not ARM");
|
||||
|
||||
if (ver != 1)
|
||||
error(1, "Unknown ELF version");
|
||||
|
||||
if (p_size != r_p_size)
|
||||
error(1, "Program header size not %d", r_p_size);
|
||||
|
||||
if (p_num < 2 || p_num > 4)
|
||||
error(1, "Unexpected number of elements: %d", p_num);
|
||||
|
||||
if (s_num && s_size != r_s_size)
|
||||
error(1, "Section header size not %d", r_s_size);
|
||||
|
||||
if (s_num > 1)
|
||||
error(1, "More than one section header");
|
||||
}
|
||||
|
||||
static void elf_set(int i, unsigned char *base, size_t size, size_t offset, size_t addr) {
|
||||
if (size <= 4096) {
|
||||
// Possible cmdline
|
||||
memset(hdr.cmdline, 0, BOOT_ARGS_SIZE);
|
||||
strncpy((char *) hdr.cmdline, (char *) (base + offset), BOOT_ARGS_SIZE);
|
||||
hdr.cmdline[strcspn((char*) hdr.cmdline, "\n")] = '\0';
|
||||
return;
|
||||
}
|
||||
switch(i) {
|
||||
case 0:
|
||||
// kernel
|
||||
kernel = base + offset;
|
||||
hdr.kernel_size = size;
|
||||
hdr.kernel_addr = addr;
|
||||
break;
|
||||
case 1:
|
||||
// ramdisk
|
||||
ramdisk = base + offset;
|
||||
hdr.ramdisk_size = size;
|
||||
hdr.ramdisk_addr = addr;
|
||||
break;
|
||||
case 2:
|
||||
// dtb
|
||||
dtb = base + offset;
|
||||
hdr.dt_size = size;
|
||||
hdr.tags_addr = addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_elf(unsigned char *base) {
|
||||
|
||||
// Reset boot image header
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
|
||||
// Hardcode header magic and pagesize
|
||||
memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);
|
||||
hdr.page_size = 4096;
|
||||
|
||||
switch(base[EI_CLASS]) {
|
||||
|
||||
case ELFCLASS32: {
|
||||
|
||||
elf32_ehdr *elf32;
|
||||
elf32_phdr *ph32;
|
||||
elf32_shdr *sh32;
|
||||
|
||||
printf("IMAGE [ELF32]\n");
|
||||
|
||||
elf32 = (elf32_ehdr *) base;
|
||||
|
||||
elf_header_check(elf32, 0);
|
||||
|
||||
ph32 = (elf32_phdr *) (base + elf32->e_phoff);
|
||||
sh32 = (elf32_shdr *) (base + elf32->e_shoff);
|
||||
|
||||
for (int i = 0; i < elf32->e_phnum; ++i) {
|
||||
elf_set(i, base, ph32[i].p_filesz, ph32[i].p_offset, ph32[i].p_paddr);
|
||||
}
|
||||
|
||||
if (elf32->e_shnum) {
|
||||
// cmdline
|
||||
memset(hdr.cmdline, 0, BOOT_ARGS_SIZE);
|
||||
strncpy((char *) hdr.cmdline, (char *) (base + sh32->s_offset + 8), BOOT_ARGS_SIZE);
|
||||
hdr.cmdline[strcspn((char*) hdr.cmdline, "\n")] = '\0';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ELFCLASS64: {
|
||||
|
||||
elf64_ehdr *elf64;
|
||||
elf64_phdr *ph64;
|
||||
elf64_shdr *sh64;
|
||||
|
||||
printf("IMAGE [ELF64]\n");
|
||||
|
||||
elf64 = (elf64_ehdr *) base;
|
||||
|
||||
elf_header_check(elf64, 1);
|
||||
|
||||
ph64 = (elf64_phdr *) (base + elf64->e_phoff);
|
||||
sh64 = (elf64_shdr *) (base + elf64->e_shoff);
|
||||
|
||||
for (int i = 0; i < elf64->e_phnum; ++i) {
|
||||
elf_set(i, base, ph64[i].p_filesz, ph64[i].p_offset, ph64[i].p_paddr);
|
||||
}
|
||||
|
||||
if (elf64->e_shnum) {
|
||||
// cmdline
|
||||
memset(hdr.cmdline, 0, BOOT_ARGS_SIZE);
|
||||
strncpy((char *) hdr.cmdline, (char *) (base + sh64->s_offset + 8), BOOT_ARGS_SIZE);
|
||||
hdr.cmdline[strcspn((char*) hdr.cmdline, "\n")] = '\0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
error(1, "ELF format error!");
|
||||
}
|
||||
|
||||
check_headers();
|
||||
}
|
||||
|
||||
static void parse_aosp(unsigned char *base, size_t size) {
|
||||
|
||||
printf("IMG [AOSP]\n");
|
||||
|
||||
size_t pos = 0;
|
||||
|
||||
// Read the header
|
||||
memcpy(&hdr, base, sizeof(hdr));
|
||||
pos += hdr.page_size;
|
||||
|
||||
// Kernel position
|
||||
kernel = base + pos;
|
||||
pos += hdr.kernel_size;
|
||||
mem_align(&pos, hdr.page_size);
|
||||
|
||||
// Ramdisk position
|
||||
ramdisk = base + pos;
|
||||
pos += hdr.ramdisk_size;
|
||||
mem_align(&pos, hdr.page_size);
|
||||
|
||||
if (hdr.second_size) {
|
||||
// Second position
|
||||
second = base + pos;
|
||||
pos += hdr.second_size;
|
||||
mem_align(&pos, hdr.page_size);
|
||||
}
|
||||
|
||||
if (hdr.dt_size) {
|
||||
// dtb position
|
||||
dtb = base + pos;
|
||||
pos += hdr.dt_size;
|
||||
mem_align(&pos, hdr.page_size);
|
||||
}
|
||||
|
||||
if (pos < size) {
|
||||
extra = base + pos;
|
||||
}
|
||||
|
||||
check_headers();
|
||||
}
|
||||
|
||||
void parse_img(unsigned char *orig, size_t size) {
|
||||
unsigned char *base, *end;
|
||||
for(base = orig, end = orig + size; base < end; base += 256, size -= 256) {
|
||||
switch (check_type(base)) {
|
||||
case CHROMEOS:
|
||||
boot_type = CHROMEOS;
|
||||
continue;
|
||||
case AOSP:
|
||||
// Don't override CHROMEOS
|
||||
if (boot_type != CHROMEOS)
|
||||
boot_type = AOSP;
|
||||
parse_aosp(base, size);
|
||||
return;
|
||||
case ELF:
|
||||
boot_type = ELF;
|
||||
parse_elf(base);
|
||||
return;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
error(1, "No boot image magic found!");
|
||||
}
|
||||
146
jni/magiskboot/repack.c
Normal file
146
jni/magiskboot/repack.c
Normal file
@@ -0,0 +1,146 @@
|
||||
#include "magiskboot.h"
|
||||
|
||||
static size_t restore(const char *filename, int fd) {
|
||||
int ifd = open(filename, O_RDONLY);
|
||||
if (ifd < 0)
|
||||
error(1, "Cannot open %s\n", filename);
|
||||
|
||||
size_t size = lseek(ifd, 0, SEEK_END);
|
||||
lseek(ifd, 0, SEEK_SET);
|
||||
if (sendfile(fd, ifd, NULL, size) != size) {
|
||||
error(1, "Cannot write %s\n", filename);
|
||||
}
|
||||
close(ifd);
|
||||
return size;
|
||||
}
|
||||
|
||||
static void restore_buf(int fd, const void *buf, size_t size) {
|
||||
if (write(fd, buf, size) != size) {
|
||||
error(1, "Cannot dump from input file\n");
|
||||
}
|
||||
}
|
||||
|
||||
void repack(const char* orig_image, const char* out_image) {
|
||||
size_t size;
|
||||
unsigned char *orig;
|
||||
char name[PATH_MAX];
|
||||
|
||||
// There are possible two MTK headers
|
||||
mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr;
|
||||
size_t mtk_kernel_off, mtk_ramdisk_off;
|
||||
|
||||
// Load original image
|
||||
mmap_ro(orig_image, &orig, &size);
|
||||
|
||||
// Parse original image
|
||||
printf("Parsing boot image: [%s]\n\n", orig_image);
|
||||
parse_img(orig, size);
|
||||
|
||||
printf("Repack to boot image: [%s]\n\n", out_image);
|
||||
|
||||
// Create new image
|
||||
int fd = open_new(out_image);
|
||||
|
||||
// Set all sizes to 0
|
||||
hdr.kernel_size = 0;
|
||||
hdr.ramdisk_size = 0;
|
||||
hdr.second_size = 0;
|
||||
hdr.dt_size = 0;
|
||||
|
||||
// Skip a page for header
|
||||
write_zero(fd, hdr.page_size);
|
||||
|
||||
// Restore kernel
|
||||
if (mtk_kernel) {
|
||||
mtk_kernel_off = lseek(fd, 0, SEEK_CUR);
|
||||
write_zero(fd, 512);
|
||||
memcpy(&mtk_kernel_hdr, kernel, sizeof(mtk_kernel_hdr));
|
||||
}
|
||||
hdr.kernel_size = restore(KERNEL_FILE, fd);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
|
||||
// Restore ramdisk
|
||||
if (mtk_ramdisk) {
|
||||
mtk_ramdisk_off = lseek(fd, 0, SEEK_CUR);
|
||||
write_zero(fd, 512);
|
||||
memcpy(&mtk_ramdisk_hdr, ramdisk, sizeof(mtk_ramdisk_hdr));
|
||||
}
|
||||
if (access(RAMDISK_FILE, R_OK) == 0) {
|
||||
// If we found raw cpio, compress to original format
|
||||
|
||||
// Before we start, clean up previous compressed files
|
||||
for (int i = 0; i < SUP_NUM; ++i) {
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
||||
unlink(name);
|
||||
}
|
||||
|
||||
size_t cpio_size;
|
||||
unsigned char *cpio;
|
||||
mmap_ro(RAMDISK_FILE, &cpio, &cpio_size);
|
||||
|
||||
if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size))
|
||||
error(1, "Unsupported ramdisk format!");
|
||||
|
||||
munmap(cpio, cpio_size);
|
||||
}
|
||||
|
||||
int found = 0;
|
||||
for (int i = 0; i < SUP_NUM; ++i) {
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
||||
if (access(name, R_OK) == 0) {
|
||||
ramdisk_type = SUP_TYPE_LIST[i];
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
error(1, "No ramdisk exists!");
|
||||
hdr.ramdisk_size = restore(name, fd);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
|
||||
// Restore second
|
||||
if (access(SECOND_FILE, R_OK) == 0) {
|
||||
hdr.second_size = restore(SECOND_FILE, fd);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
}
|
||||
|
||||
// Restore dtb
|
||||
if (access(DTB_FILE, R_OK) == 0) {
|
||||
hdr.dt_size = restore(DTB_FILE, fd);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
}
|
||||
|
||||
// Check extra info, currently only for LG Bump and Samsung SEANDROIDENFORCE
|
||||
if (extra) {
|
||||
if (memcmp(extra, "SEANDROIDENFORCE", 16) == 0 ||
|
||||
memcmp(extra, "\x41\xa9\xe4\x67\x74\x4d\x1d\x1b\xa4\x29\xf2\xec\xea\x65\x52\x79", 16) == 0 ) {
|
||||
restore_buf(fd, extra, 16);
|
||||
}
|
||||
}
|
||||
|
||||
// Write headers back
|
||||
if (mtk_kernel) {
|
||||
lseek(fd, mtk_kernel_off, SEEK_SET);
|
||||
mtk_kernel_hdr.size = hdr.kernel_size;
|
||||
hdr.kernel_size += 512;
|
||||
restore_buf(fd, &mtk_kernel_hdr, sizeof(mtk_kernel_hdr));
|
||||
}
|
||||
if (mtk_ramdisk) {
|
||||
lseek(fd, mtk_ramdisk_off, SEEK_SET);
|
||||
mtk_ramdisk_hdr.size = hdr.ramdisk_size;
|
||||
hdr.ramdisk_size += 512;
|
||||
restore_buf(fd, &mtk_ramdisk_hdr, sizeof(mtk_ramdisk_hdr));
|
||||
}
|
||||
// Main header
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
restore_buf(fd, &hdr, sizeof(hdr));
|
||||
|
||||
// Print new image info
|
||||
print_info();
|
||||
|
||||
munmap(orig, size);
|
||||
if (lseek(fd, 0, SEEK_END) > size) {
|
||||
error(2, "Boot partition too small!");
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
295
jni/magiskboot/sha1.c
Normal file
295
jni/magiskboot/sha1.c
Normal file
File diff suppressed because it is too large
Load Diff
44
jni/magiskboot/sha1.h
Normal file
44
jni/magiskboot/sha1.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef SHA1_H
|
||||
#define SHA1_H
|
||||
|
||||
/*
|
||||
SHA-1 in C
|
||||
By Steve Reid <steve@edmweb.com>
|
||||
100% Public Domain
|
||||
*/
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t state[5];
|
||||
uint32_t count[2];
|
||||
unsigned char buffer[64];
|
||||
} SHA1_CTX;
|
||||
|
||||
void SHA1Transform(
|
||||
uint32_t state[5],
|
||||
const unsigned char buffer[64]
|
||||
);
|
||||
|
||||
void SHA1Init(
|
||||
SHA1_CTX * context
|
||||
);
|
||||
|
||||
void SHA1Update(
|
||||
SHA1_CTX * context,
|
||||
const unsigned char *data,
|
||||
uint32_t len
|
||||
);
|
||||
|
||||
void SHA1Final(
|
||||
unsigned char digest[20],
|
||||
SHA1_CTX * context
|
||||
);
|
||||
|
||||
void SHA1(
|
||||
char *hash_out,
|
||||
const char *str,
|
||||
int len);
|
||||
|
||||
#endif /* SHA1_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user