Add b64xz to handle busybox decode/decompress in scripts
This commit is contained in:
parent
b37bad35c2
commit
eae611c54d
30
build.py
30
build.py
@ -35,7 +35,7 @@ import zipfile
|
|||||||
import datetime
|
import datetime
|
||||||
import errno
|
import errno
|
||||||
import shutil
|
import shutil
|
||||||
import gzip
|
import lzma
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
def silentremove(file):
|
def silentremove(file):
|
||||||
@ -164,18 +164,24 @@ def sign_adjust_zip(unsigned, output):
|
|||||||
|
|
||||||
def gen_update_binary():
|
def gen_update_binary():
|
||||||
update_bin = []
|
update_bin = []
|
||||||
bb = os.path.join('libs', 'armeabi-v7a', 'busybox')
|
binary = os.path.join('libs', 'armeabi-v7a', 'b64xz')
|
||||||
if not os.path.exists(bb):
|
if not os.path.exists(binary):
|
||||||
error('{} does not exist! Please build \'binary\' before zipping!'.format(bb))
|
error('Please build \'binary\' before zipping!')
|
||||||
with open(bb, 'rb') as busybox:
|
with open(binary, 'rb') as b64xz:
|
||||||
update_bin.append('#! /sbin/sh\nBB_ARM=')
|
update_bin.append('#! /sbin/sh\nEX_ARM=')
|
||||||
update_bin.append(base64.b64encode(gzip.compress(busybox.read())).decode('ascii'))
|
update_bin.append(''.join("\\\\x{:02X}".format(c) for c in b64xz.read()))
|
||||||
bb = os.path.join('libs', 'x86', 'busybox')
|
binary = os.path.join('libs', 'x86', 'b64xz')
|
||||||
if not os.path.exists(bb):
|
with open(binary, 'rb') as b64xz:
|
||||||
error('{} does not exist! Please build \'binary\' before zipping!'.format(bb))
|
update_bin.append('\nEX_X86=')
|
||||||
with open(bb, 'rb') as busybox:
|
update_bin.append(''.join("\\\\x{:02X}".format(c) for c in b64xz.read()))
|
||||||
|
binary = os.path.join('libs', 'armeabi-v7a', 'busybox')
|
||||||
|
with open(binary, 'rb') as busybox:
|
||||||
|
update_bin.append('\nBB_ARM=')
|
||||||
|
update_bin.append(base64.b64encode(lzma.compress(busybox.read())).decode('ascii'))
|
||||||
|
binary = os.path.join('libs', 'x86', 'busybox')
|
||||||
|
with open(binary, 'rb') as busybox:
|
||||||
update_bin.append('\nBB_X86=')
|
update_bin.append('\nBB_X86=')
|
||||||
update_bin.append(base64.b64encode(gzip.compress(busybox.read())).decode('ascii'))
|
update_bin.append(base64.b64encode(lzma.compress(busybox.read())).decode('ascii'))
|
||||||
update_bin.append('\n')
|
update_bin.append('\n')
|
||||||
with open(os.path.join('scripts', 'update_binary.sh'), 'r') as script:
|
with open(os.path.join('scripts', 'update_binary.sh'), 'r') as script:
|
||||||
update_bin.append(script.read())
|
update_bin.append(script.read())
|
||||||
|
@ -74,9 +74,18 @@ LOCAL_SRC_FILES := \
|
|||||||
LOCAL_CFLAGS := -DZLIB_CONST
|
LOCAL_CFLAGS := -DZLIB_CONST
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
# busybox (32-bit only)
|
# 32-bit static binaries
|
||||||
ifneq ($(TARGET_ARCH_ABI), x86_64)
|
ifneq ($(TARGET_ARCH_ABI), x86_64)
|
||||||
ifneq ($(TARGET_ARCH_ABI), arm64-v8a)
|
ifneq ($(TARGET_ARCH_ABI), arm64-v8a)
|
||||||
|
# b64xz
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := b64xz
|
||||||
|
LOCAL_STATIC_LIBRARIES := liblzma
|
||||||
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ndk-compression/xz/src/liblzma/api
|
||||||
|
LOCAL_SRC_FILES := b64xz.c
|
||||||
|
LOCAL_LDFLAGS := -static
|
||||||
|
include $(BUILD_EXECUTABLE)
|
||||||
|
# Busybox
|
||||||
include jni/busybox/Android.mk
|
include jni/busybox/Android.mk
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
83
jni/b64xz.c
Normal file
83
jni/b64xz.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/* b64xz.c - Base64-XZ Extractor
|
||||||
|
*
|
||||||
|
* This program expects data from stdin. The data should be compressed with xz and
|
||||||
|
* then encoded into base64 format. What b64xz does is basically the reverse of the
|
||||||
|
* mentioned process: decode base64 to uint8_ts, decompress xz, then dump to stdout
|
||||||
|
*
|
||||||
|
* The compiled binary will be hex-dumped into update-binary
|
||||||
|
* Busybox will be xz-compressed, base64 encoded and dumped into update-binary
|
||||||
|
* This program is to recover busybox for Magisk installation environment
|
||||||
|
*
|
||||||
|
* I intentionally removed stdio. This will result in a smaller binary size because
|
||||||
|
* all I/O are handled by system calls (read/write) instead of libc wrappers
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <lzma.h>
|
||||||
|
|
||||||
|
#define BUFSIZE 8192
|
||||||
|
|
||||||
|
static const char trans_tbl[] =
|
||||||
|
"|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
|
||||||
|
|
||||||
|
static void decodeblock(uint8_t* in, uint8_t* out) {
|
||||||
|
out[0] = (uint8_t)(in[0] << 2 | in[1] >> 4);
|
||||||
|
out[1] = (uint8_t)(in[1] << 4 | in[2] >> 2);
|
||||||
|
out[2] = (uint8_t)(((in[2] << 6) & 0xc0) | in[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int unxz(lzma_stream *strm, void *buf, size_t size) {
|
||||||
|
lzma_ret ret = 0;
|
||||||
|
uint8_t out[BUFSIZE];
|
||||||
|
strm->next_in = buf;
|
||||||
|
strm->avail_in = size;
|
||||||
|
do {
|
||||||
|
strm->next_out = out;
|
||||||
|
strm->avail_out = sizeof(out);
|
||||||
|
ret = lzma_code(strm, LZMA_RUN);
|
||||||
|
write(STDOUT_FILENO, out, sizeof(out) - strm->avail_out);
|
||||||
|
} while (strm->avail_out == 0 && ret == LZMA_OK);
|
||||||
|
|
||||||
|
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
||||||
|
write(STDERR_FILENO, "LZMA error!\n", 13);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char const* argv[]) {
|
||||||
|
if (argc > 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint8_t in[4], buf[BUFSIZE];
|
||||||
|
int len = 0, pos = 0;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
// Setup lzma stream
|
||||||
|
lzma_stream strm = LZMA_STREAM_INIT;
|
||||||
|
if (lzma_auto_decoder(&strm, UINT64_MAX, 0) != LZMA_OK) {
|
||||||
|
write(STDERR_FILENO, "Unable to init lzma stream\n", 28);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (read(STDIN_FILENO, &c, sizeof(c)) == 1) {
|
||||||
|
c = ((c < 43 || c > 122) ? -1 : (trans_tbl[c - 43] == '$' ? -1 : trans_tbl[c - 43] - 62));
|
||||||
|
if (c >= 0)
|
||||||
|
in[len++] = c;
|
||||||
|
if (len < 4)
|
||||||
|
continue;
|
||||||
|
len = 0;
|
||||||
|
decodeblock(in, buf + pos);
|
||||||
|
pos += 3;
|
||||||
|
if (pos > sizeof(buf) - 3) {
|
||||||
|
// Buffer is full, unxz
|
||||||
|
if (unxz(&strm, buf, pos))
|
||||||
|
return 1;
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pos) {
|
||||||
|
if (unxz(&strm, buf, pos))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
lzma_end(&strm);
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,14 +1,16 @@
|
|||||||
# BB_ARM and BB_X86 should be generated in build.py
|
# EX_ARM, EX_X86, BB_ARM, and BB_X86 should be generated in build.py
|
||||||
TMPDIR=/dev/tmp
|
TMPDIR=/dev/tmp; INSTALLER=$TMPDIR/install; BBDIR=$TMPDIR/bin
|
||||||
INSTALLER=$TMPDIR/install
|
EXBIN=$BBDIR/b64xz; BBBIN=$BBDIR/busybox
|
||||||
BBDIR=$TMPDIR/bin
|
rm -rf $TMPDIR 2>/dev/null; mkdir -p $BBDIR
|
||||||
BBBIN=$BBDIR/busybox
|
touch $EXBIN $BBBIN; chmod 755 $EXBIN $BBBIN
|
||||||
rm -rf $TMPDIR 2>/dev/null; mkdir -p $BBDIR; touch $BBBIN; chmod 755 $BBBIN
|
echo -ne $EX_ARM > $EXBIN
|
||||||
echo $BB_ARM | base64 -d | gzip -d > $BBBIN
|
if $EXBIN --test 2>/dev/null; then
|
||||||
if ! $BBBIN --install -s $TMPDIR/bin >/dev/null 2>&1; then
|
echo $BB_ARM | $EXBIN > $BBBIN
|
||||||
echo $BB_X86 | base64 -d | gzip -d > $BBBIN
|
else
|
||||||
$BBBIN --install -s $TMPDIR/bin >/dev/null 2>&1 || exit 1
|
echo -ne $EX_x86 > $EXBIN
|
||||||
|
echo $BB_x86 | $EXBIN > $BBBIN
|
||||||
fi
|
fi
|
||||||
|
$BBBIN --install -s $TMPDIR/bin
|
||||||
export PATH=$BBDIR:$PATH
|
export PATH=$BBDIR:$PATH
|
||||||
mkdir -p $INSTALLER
|
mkdir -p $INSTALLER
|
||||||
unzip -o "$3" -d $INSTALLER
|
unzip -o "$3" -d $INSTALLER
|
||||||
|
Loading…
Reference in New Issue
Block a user