From 82e969627a93772bedcbb55332a03c934cff7219 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Wed, 5 Apr 2017 03:44:13 +0800 Subject: [PATCH] Start unifying with log monitor --- jni/Android.mk | 37 ++++++++++++++++++++++++++++++++----- jni/magisk.h | 24 ++++++++++++++++++++++++ jni/main.c | 16 ++++++++++++++++ jni/utils/log_monitor.c | 32 ++++++++++++++++++++++++++++++++ jni/utils/utils.h | 21 +++++++++++++++++++++ jni/utils/vector.c | 34 ++++++++++++++++++++++++++++++++++ jni/utils/vector.h | 26 ++++++++++++++++++++++++++ jni/utils/xwrap.c | 21 +++++++++++++++++++++ 8 files changed, 206 insertions(+), 5 deletions(-) create mode 100644 jni/magisk.h create mode 100644 jni/main.c create mode 100644 jni/utils/log_monitor.c create mode 100644 jni/utils/utils.h create mode 100644 jni/utils/vector.c create mode 100644 jni/utils/vector.h create mode 100644 jni/utils/xwrap.c diff --git a/jni/Android.mk b/jni/Android.mk index 5e0bd875c..6e284e02d 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -1,7 +1,34 @@ LOCAL_PATH := $(call my-dir) -include jni/magiskboot/Android.mk -include jni/magiskhide/Android.mk -include jni/resetprop/Android.mk -include jni/magiskpolicy/Android.mk -include jni/su/Android.mk +include $(CLEAR_VARS) +LOCAL_MODULE := magisk +LOCAL_STATIC_LIBRARIES := libselinux libsepol + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/utils \ + $(LOCAL_PATH)/selinux/libselinux/include \ + $(LOCAL_PATH)/selinux/libsepol/include + +LOCAL_SRC_FILES := \ + main.c \ + utils/log_monitor.c \ + utils/vector.c \ + utils/xwrap.c + +LOCAL_CFLAGS := -static +LOCAL_LDLIBS := -llog + +include $(BUILD_EXECUTABLE) + +# Libraries +include jni/selinux/libselinux/Android.mk +include jni/selinux/libsepol/Android.mk + +# Enable these for seperate binaries +# By default, we create a unified binary + +# include jni/magiskboot/Android.mk +# include jni/magiskhide/Android.mk +# include jni/resetprop/Android.mk +# include jni/magiskpolicy/Android.mk +# include jni/su/Android.mk diff --git a/jni/magisk.h b/jni/magisk.h new file mode 100644 index 000000000..afaae0707 --- /dev/null +++ b/jni/magisk.h @@ -0,0 +1,24 @@ +#ifndef _MAGISK_H_ +#define _MAGISK_H_ + +#include +#include +#include + +#define LOG_TAG "Magisk" + +#ifdef DEBUG +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) +#else +#define LOGD(...) stub(__VA_ARGS__) +#endif +#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)) + +void stub(const char *fmt, ...); + +// Global buffer +#define BUF_SIZE 4096 +extern char magiskbuf[BUF_SIZE]; + +#endif diff --git a/jni/main.c b/jni/main.c new file mode 100644 index 000000000..55ca072b9 --- /dev/null +++ b/jni/main.c @@ -0,0 +1,16 @@ +/* main.c - The entry point, should be mutli-call + */ + +#include "utils.h" +#include "magisk.h" + +// Global buffer +char magiskbuf[BUF_SIZE]; + +void stub(const char *fmt, ...) {} + +int main(int argc, char const *argv[]) { + // Start new thread to monitor logs + monitor_logs(); + return 0; +} \ No newline at end of file diff --git a/jni/utils/log_monitor.c b/jni/utils/log_monitor.c new file mode 100644 index 000000000..bc280722c --- /dev/null +++ b/jni/utils/log_monitor.c @@ -0,0 +1,32 @@ +/* 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 +#include + +#include "utils.h" + +static void *logger_thread(void *args) { + rename("/cache/magisk.log", "/cache/last_magisk.log"); + FILE *logfile = xfopen("/cache/magisk.log", "w"); + // Disable buffering + setbuf(logfile, NULL); + // Start logcat + FILE *p = popen("logcat -s Magisk", "r"); + while (fgets(magiskbuf, BUF_SIZE, p)) { + fprintf(logfile, "%s", magiskbuf); + } + return NULL; +} + +/* Start a new thread to monitor logcat and dump to file */ +void monitor_logs() { + pthread_t log_monitor; + pthread_create(&log_monitor, NULL, logger_thread, NULL); + printf("Hello :)\n"); + pthread_join(log_monitor, NULL); +} \ No newline at end of file diff --git a/jni/utils/utils.h b/jni/utils/utils.h new file mode 100644 index 000000000..ba05f4c23 --- /dev/null +++ b/jni/utils/utils.h @@ -0,0 +1,21 @@ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include +#include + +#include "magisk.h" + +// xwrap.c + +FILE *xfopen(const char *pathname, const char *mode); + +// vector.c + +#include "vector.h" + +// log_monitor.c + +void monitor_logs(); + +#endif \ No newline at end of file diff --git a/jni/utils/vector.c b/jni/utils/vector.c new file mode 100644 index 000000000..986dae60e --- /dev/null +++ b/jni/utils/vector.c @@ -0,0 +1,34 @@ +/* vector.c - A simple vector implementation in c + */ + +#include + +#include "vector.h" + +void vec_init(struct vector *v) { + vec_size(v) = 0; + vec_cap(v) = 1; + vec_entry(v) = malloc(sizeof(void*)); +} + +void vec_push_back(struct vector *v, void *p) { + if (v == NULL) return; + if (vec_size(v) == vec_cap(v)) { + vec_cap(v) *= 2; + vec_entry(v) = realloc(vec_entry(v), sizeof(void*) * vec_cap(v)); + } + vec_entry(v)[vec_size(v)] = p; + ++vec_size(v); +} + +void vec_sort(struct vector *v, int (*compar)(const void *, const void *)) { + qsort(vec_entry(v), vec_size(v), sizeof(void*), compar); +} + +void vec_destroy(struct vector *v) { + // Will not free each entry! + // Manually free each entry, then call this function + vec_size(v) = 0; + vec_cap(v) = 0; + free(v->data); +} \ No newline at end of file diff --git a/jni/utils/vector.h b/jni/utils/vector.h new file mode 100644 index 000000000..7f6db9ddd --- /dev/null +++ b/jni/utils/vector.h @@ -0,0 +1,26 @@ +/* vector.h - A simple vector implementation in c + */ + +#ifndef _VECTOR_H_ +#define _VECTOR_H_ + +#include + +struct vector { + size_t size; + size_t cap; + void **data; +}; +void vec_init(struct vector *v); +void vec_push_back(struct vector *v, void *p); +void vec_sort(struct vector *v, int (*compar)(const void *, const void *)); +void vec_destroy(struct vector *v); +#define vec_size(v) (v)->size +#define vec_cap(v) (v)->cap +#define vec_entry(v) (v)->data +/* Usage: vec_for_each(vector *v, void *e) */ +#define vec_for_each(v, e) \ + e = (v)->data[0]; \ + for (size_t _ = 0; _ < (v)->size; ++_, e = (v)->data[_]) + +#endif \ No newline at end of file diff --git a/jni/utils/xwrap.c b/jni/utils/xwrap.c new file mode 100644 index 000000000..c398dd8a8 --- /dev/null +++ b/jni/utils/xwrap.c @@ -0,0 +1,21 @@ +/* xwrap.c - wrappers around existing library functions. + * + * Functions with the x prefix are wrappers that either succeed or kill the + * program with an error message, but never return failure. They usually have + * the same arguments and return value as the function they wrap. + * + */ + +#include +#include + +#include "utils.h" + +FILE *xfopen(const char *pathname, const char *mode) { + FILE *fp = fopen(pathname, mode); + if (fp == NULL) { + PLOGE("fopen"); + exit(1); + } + return fp; +} \ No newline at end of file