From 7307c136ee5d492ea6e5d51e29f9f3d0a1bd27c1 Mon Sep 17 00:00:00 2001 From: tarsin Date: Sat, 21 May 2022 17:24:03 +0800 Subject: [PATCH] Drop useless native part --- native/src/main/jni/CMakeLists.txt | 10 +- native/src/main/jni/integrity/CMakeLists.txt | 12 - native/src/main/jni/integrity/am-proxy.c | 824 ------------- native/src/main/jni/integrity/am-proxy.h | 21 - native/src/main/jni/integrity/apk-sign-v2.c | 169 --- native/src/main/jni/integrity/apk-sign-v2.h | 18 - native/src/main/jni/integrity/common.c | 233 ---- native/src/main/jni/integrity/common.h | 73 -- native/src/main/jni/integrity/genuine.c | 1090 ------------------ native/src/main/jni/integrity/genuine.h | 43 - native/src/main/jni/integrity/inline.c | 333 ------ native/src/main/jni/integrity/inline.h | 45 - native/src/main/jni/integrity/openat.c | 56 - native/src/main/jni/integrity/openat.h | 28 - native/src/main/jni/integrity/path.c | 95 -- native/src/main/jni/integrity/path.h | 16 - native/src/main/jni/integrity/plt.c | 355 ------ native/src/main/jni/integrity/plt.h | 42 - native/src/main/jni/main.c | 2 +- 19 files changed, 3 insertions(+), 3462 deletions(-) delete mode 100644 native/src/main/jni/integrity/CMakeLists.txt delete mode 100644 native/src/main/jni/integrity/am-proxy.c delete mode 100644 native/src/main/jni/integrity/am-proxy.h delete mode 100644 native/src/main/jni/integrity/apk-sign-v2.c delete mode 100644 native/src/main/jni/integrity/apk-sign-v2.h delete mode 100644 native/src/main/jni/integrity/common.c delete mode 100644 native/src/main/jni/integrity/common.h delete mode 100644 native/src/main/jni/integrity/genuine.c delete mode 100644 native/src/main/jni/integrity/genuine.h delete mode 100644 native/src/main/jni/integrity/inline.c delete mode 100644 native/src/main/jni/integrity/inline.h delete mode 100644 native/src/main/jni/integrity/openat.c delete mode 100644 native/src/main/jni/integrity/openat.h delete mode 100644 native/src/main/jni/integrity/path.c delete mode 100644 native/src/main/jni/integrity/path.h delete mode 100644 native/src/main/jni/integrity/plt.c delete mode 100644 native/src/main/jni/integrity/plt.h diff --git a/native/src/main/jni/CMakeLists.txt b/native/src/main/jni/CMakeLists.txt index 233c2e47d..e36105f9f 100644 --- a/native/src/main/jni/CMakeLists.txt +++ b/native/src/main/jni/CMakeLists.txt @@ -1,16 +1,10 @@ project(ehviewer) cmake_minimum_required(VERSION 3.4.1) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti -fno-stack-protector") - add_subdirectory(image) -add_subdirectory(integrity) add_library(${PROJECT_NAME} SHARED main.c) -target_compile_options(${PROJECT_NAME} PUBLIC -fvisibility=hidden -fvisibility-inlines-hidden -fno-exceptions) +target_include_directories(${PROJECT_NAME} PUBLIC image/image) -target_include_directories(${PROJECT_NAME} PUBLIC image/image integrity) - -target_link_libraries(${PROJECT_NAME} image genuine) \ No newline at end of file +target_link_libraries(${PROJECT_NAME} image) \ No newline at end of file diff --git a/native/src/main/jni/integrity/CMakeLists.txt b/native/src/main/jni/integrity/CMakeLists.txt deleted file mode 100644 index e32ee3d44..000000000 --- a/native/src/main/jni/integrity/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -project(genuine C) - -add_library(genuine STATIC - am-proxy.c - apk-sign-v2.c - common.c - genuine.c - inline.c - openat.c - path.c - plt.c) -target_include_directories(genuine PUBLIC integrity) diff --git a/native/src/main/jni/integrity/am-proxy.c b/native/src/main/jni/integrity/am-proxy.c deleted file mode 100644 index 00626a642..000000000 --- a/native/src/main/jni/integrity/am-proxy.c +++ /dev/null @@ -1,824 +0,0 @@ -// -// Created by Thom on 2019/3/15. -// - -#include "common.h" -#include "am-proxy.h" - -static inline void fill_android_app_ActivityManager(char v[]) { - // android/app/ActivityManager - static unsigned int m = 0; - - if (m == 0) { - m = 23; - } else if (m == 29) { - m = 31; - } - - v[0x0] = 'e'; - v[0x1] = 'k'; - v[0x2] = 'b'; - v[0x3] = 'u'; - v[0x4] = 'g'; - v[0x5] = '`'; - v[0x6] = 'n'; - v[0x7] = '$'; - v[0x8] = 'm'; - v[0x9] = '}'; - v[0xa] = '~'; - v[0xb] = ' '; - v[0xc] = 'Q'; - v[0xd] = 'r'; - v[0xe] = 'f'; - v[0xf] = 'z'; - v[0x10] = 'b'; - v[0x11] = '|'; - v[0x12] = 'b'; - v[0x13] = 'y'; - v[0x14] = 'L'; - v[0x15] = 'c'; - v[0x16] = 'm'; - v[0x17] = 'e'; - v[0x18] = 'b'; - v[0x19] = 'c'; - v[0x1a] = 'u'; - for (unsigned int i = 0; i < 0x1b; ++i) { - v[i] ^= ((i + 0x1b) % m); - } - v[0x1b] = '\0'; -} - -static inline void fill_getService(char v[]) { - // getService - static unsigned int m = 0; - - if (m == 0) { - m = 7; - } else if (m == 11) { - m = 13; - } - - v[0x0] = 'd'; - v[0x1] = 'a'; - v[0x2] = 'q'; - v[0x3] = 'U'; - v[0x4] = 'e'; - v[0x5] = 's'; - v[0x6] = 't'; - v[0x7] = 'j'; - v[0x8] = 'g'; - v[0x9] = '`'; - for (unsigned int i = 0; i < 0xa; ++i) { - v[i] ^= ((i + 0xa) % m); - } - v[0xa] = '\0'; -} - -static inline void fill_getService_signature(char v[]) { - // ()Landroid/app/IActivityManager; - static unsigned int m = 0; - - if (m == 0) { - m = 31; - } else if (m == 37) { - m = 41; - } - - v[0x0] = ')'; - v[0x1] = '+'; - v[0x2] = 'O'; - v[0x3] = 'e'; - v[0x4] = 'k'; - v[0x5] = 'b'; - v[0x6] = 'u'; - v[0x7] = 'g'; - v[0x8] = '`'; - v[0x9] = 'n'; - v[0xa] = '$'; - v[0xb] = 'm'; - v[0xc] = '}'; - v[0xd] = '~'; - v[0xe] = ' '; - v[0xf] = 'Y'; - v[0x10] = 'P'; - v[0x11] = 'q'; - v[0x12] = 'g'; - v[0x13] = '}'; - v[0x14] = 'c'; - v[0x15] = '\x7f'; - v[0x16] = 'c'; - v[0x17] = 'a'; - v[0x18] = 'T'; - v[0x19] = '{'; - v[0x1a] = 'u'; - v[0x1b] = '}'; - v[0x1c] = 'z'; - v[0x1d] = '{'; - v[0x1e] = 'r'; - v[0x1f] = ':'; - for (unsigned int i = 0; i < 0x20; ++i) { - v[i] ^= ((i + 0x20) % m); - } - v[0x20] = '\0'; -} - -static inline void fill_android_app_ActivityManagerNative(char v[]) { - // android/app/ActivityManagerNative - static unsigned int m = 0; - - if (m == 0) { - m = 31; - } else if (m == 37) { - m = 41; - } - - v[0x0] = 'c'; - v[0x1] = 'm'; - v[0x2] = '`'; - v[0x3] = 'w'; - v[0x4] = 'i'; - v[0x5] = 'n'; - v[0x6] = 'l'; - v[0x7] = '&'; - v[0x8] = 'k'; - v[0x9] = '{'; - v[0xa] = '|'; - v[0xb] = '"'; - v[0xc] = 'O'; - v[0xd] = 'l'; - v[0xe] = 'd'; - v[0xf] = 'x'; - v[0x10] = 'd'; - v[0x11] = 'z'; - v[0x12] = '`'; - v[0x13] = 'l'; - v[0x14] = '['; - v[0x15] = 'v'; - v[0x16] = 'v'; - v[0x17] = 'x'; - v[0x18] = '}'; - v[0x19] = '~'; - v[0x1a] = 'n'; - v[0x1b] = 'S'; - v[0x1c] = '\x7f'; - v[0x1d] = 't'; - v[0x1e] = 'h'; - v[0x1f] = 't'; - v[0x20] = 'f'; - for (unsigned int i = 0; i < 0x21; ++i) { - v[i] ^= ((i + 0x21) % m); - } - v[0x21] = '\0'; -} - -static inline void fill_getDefault(char v[]) { - // getDefault - static unsigned int m = 0; - - if (m == 0) { - m = 7; - } else if (m == 11) { - m = 13; - } - - v[0x0] = 'd'; - v[0x1] = 'a'; - v[0x2] = 'q'; - v[0x3] = 'B'; - v[0x4] = 'e'; - v[0x5] = 'g'; - v[0x6] = 'c'; - v[0x7] = 'v'; - v[0x8] = 'h'; - v[0x9] = 'q'; - for (unsigned int i = 0; i < 0xa; ++i) { - v[i] ^= ((i + 0xa) % m); - } - v[0xa] = '\0'; -} - -static inline void fill_getDefault_signature(char v[]) { - // ()Landroid/app/IActivityManager; - static unsigned int m = 0; - - if (m == 0) { - m = 31; - } else if (m == 37) { - m = 41; - } - - v[0x0] = ')'; - v[0x1] = '+'; - v[0x2] = 'O'; - v[0x3] = 'e'; - v[0x4] = 'k'; - v[0x5] = 'b'; - v[0x6] = 'u'; - v[0x7] = 'g'; - v[0x8] = '`'; - v[0x9] = 'n'; - v[0xa] = '$'; - v[0xb] = 'm'; - v[0xc] = '}'; - v[0xd] = '~'; - v[0xe] = ' '; - v[0xf] = 'Y'; - v[0x10] = 'P'; - v[0x11] = 'q'; - v[0x12] = 'g'; - v[0x13] = '}'; - v[0x14] = 'c'; - v[0x15] = '\x7f'; - v[0x16] = 'c'; - v[0x17] = 'a'; - v[0x18] = 'T'; - v[0x19] = '{'; - v[0x1a] = 'u'; - v[0x1b] = '}'; - v[0x1c] = 'z'; - v[0x1d] = '{'; - v[0x1e] = 'r'; - v[0x1f] = ':'; - for (unsigned int i = 0; i < 0x20; ++i) { - v[i] ^= ((i + 0x20) % m); - } - v[0x20] = '\0'; -} - -static inline void fill_android_os_BinderProxy(char v[]) { - // android/os/BinderProxy - static unsigned int m = 0; - - if (m == 0) { - m = 19; - } else if (m == 23) { - m = 29; - } - - v[0x0] = 'b'; - v[0x1] = 'j'; - v[0x2] = 'a'; - v[0x3] = 't'; - v[0x4] = 'h'; - v[0x5] = 'a'; - v[0x6] = 'm'; - v[0x7] = '%'; - v[0x8] = 'd'; - v[0x9] = '\x7f'; - v[0xa] = '"'; - v[0xb] = 'L'; - v[0xc] = 'f'; - v[0xd] = '~'; - v[0xe] = 'u'; - v[0xf] = 'w'; - v[0x10] = 'r'; - v[0x11] = 'Q'; - v[0x12] = 'p'; - v[0x13] = 'l'; - v[0x14] = '|'; - v[0x15] = '|'; - for (unsigned int i = 0; i < 0x16; ++i) { - v[i] ^= ((i + 0x16) % m); - } - v[0x16] = '\0'; -} - -static inline void fill_android_os_IInterface(char v[]) { - // android/os/IInterface - static unsigned int m = 0; - - if (m == 0) { - m = 19; - } else if (m == 23) { - m = 29; - } - - v[0x0] = 'c'; - v[0x1] = 'm'; - v[0x2] = '`'; - v[0x3] = 'w'; - v[0x4] = 'i'; - v[0x5] = 'n'; - v[0x6] = 'l'; - v[0x7] = '&'; - v[0x8] = 'e'; - v[0x9] = 'x'; - v[0xa] = '#'; - v[0xb] = 'D'; - v[0xc] = 'G'; - v[0xd] = 'a'; - v[0xe] = 'd'; - v[0xf] = 't'; - v[0x10] = '`'; - v[0x11] = 'f'; - v[0x12] = '`'; - v[0x13] = 'a'; - v[0x14] = 'f'; - for (unsigned int i = 0; i < 0x15; ++i) { - v[i] ^= ((i + 0x15) % m); - } - v[0x15] = '\0'; -} - -static inline void fill_asBinder(char v[]) { - // asBinder - static unsigned int m = 0; - - if (m == 0) { - m = 7; - } else if (m == 11) { - m = 13; - } - - v[0x0] = '`'; - v[0x1] = 'q'; - v[0x2] = 'A'; - v[0x3] = 'm'; - v[0x4] = 'k'; - v[0x5] = 'b'; - v[0x6] = 'e'; - v[0x7] = 's'; - for (unsigned int i = 0; i < 0x8; ++i) { - v[i] ^= ((i + 0x8) % m); - } - v[0x8] = '\0'; -} - -static inline void fill_asBinder_signature(char v[]) { - // ()Landroid/os/IBinder; - static unsigned int m = 0; - - if (m == 0) { - m = 19; - } else if (m == 23) { - m = 29; - } - - v[0x0] = '+'; - v[0x1] = '-'; - v[0x2] = 'I'; - v[0x3] = 'g'; - v[0x4] = 'i'; - v[0x5] = 'l'; - v[0x6] = '{'; - v[0x7] = 'e'; - v[0x8] = 'b'; - v[0x9] = 'h'; - v[0xa] = '"'; - v[0xb] = 'a'; - v[0xc] = '|'; - v[0xd] = '?'; - v[0xe] = 'X'; - v[0xf] = 'P'; - v[0x10] = 'i'; - v[0x11] = 'o'; - v[0x12] = 'f'; - v[0x13] = 'f'; - v[0x14] = 'v'; - v[0x15] = '>'; - for (unsigned int i = 0; i < 0x16; ++i) { - v[i] ^= ((i + 0x16) % m); - } - v[0x16] = '\0'; -} - -static inline void fill_android_os_ServiceManager(char v[]) { - // android/os/ServiceManager - static unsigned int m = 0; - - if (m == 0) { - m = 23; - } else if (m == 29) { - m = 31; - } - - v[0x0] = 'c'; - v[0x1] = 'm'; - v[0x2] = '`'; - v[0x3] = 'w'; - v[0x4] = 'i'; - v[0x5] = 'n'; - v[0x6] = 'l'; - v[0x7] = '&'; - v[0x8] = 'e'; - v[0x9] = 'x'; - v[0xa] = '#'; - v[0xb] = '^'; - v[0xc] = 'k'; - v[0xd] = '}'; - v[0xe] = 'f'; - v[0xf] = 'x'; - v[0x10] = 'q'; - v[0x11] = 'v'; - v[0x12] = 'Y'; - v[0x13] = 't'; - v[0x14] = 'x'; - v[0x15] = 'a'; - v[0x16] = 'f'; - v[0x17] = 'g'; - v[0x18] = 'q'; - for (unsigned int i = 0; i < 0x19; ++i) { - v[i] ^= ((i + 0x19) % m); - } - v[0x19] = '\0'; -} - -static inline void fill_getService_signature_IBinder(char v[]) { - // (Ljava/lang/String;)Landroid/os/IBinder; - static unsigned int m = 0; - - if (m == 0) { - m = 37; - } else if (m == 41) { - m = 43; - } - - v[0x0] = '+'; - v[0x1] = 'H'; - v[0x2] = 'o'; - v[0x3] = 'g'; - v[0x4] = 'q'; - v[0x5] = 'i'; - v[0x6] = '&'; - v[0x7] = 'f'; - v[0x8] = 'j'; - v[0x9] = 'b'; - v[0xa] = 'j'; - v[0xb] = '!'; - v[0xc] = '\\'; - v[0xd] = 'd'; - v[0xe] = 'c'; - v[0xf] = '{'; - v[0x10] = '}'; - v[0x11] = 's'; - v[0x12] = '.'; - v[0x13] = '?'; - v[0x14] = '['; - v[0x15] = 'y'; - v[0x16] = 'w'; - v[0x17] = '~'; - v[0x18] = 'i'; - v[0x19] = 's'; - v[0x1a] = 't'; - v[0x1b] = 'z'; - v[0x1c] = '0'; - v[0x1d] = 'O'; - v[0x1e] = 'R'; - v[0x1f] = '\r'; - v[0x20] = 'j'; - v[0x21] = 'f'; - v[0x22] = 'i'; - v[0x23] = 'o'; - v[0x24] = 'f'; - v[0x25] = 'f'; - v[0x26] = 'v'; - v[0x27] = '>'; - for (unsigned int i = 0; i < 0x28; ++i) { - v[i] ^= ((i + 0x28) % m); - } - v[0x28] = '\0'; -} - -static inline void fill_activity(char v[]) { - // activity - static unsigned int m = 0; - - if (m == 0) { - m = 7; - } else if (m == 11) { - m = 13; - } - - v[0x0] = '`'; - v[0x1] = 'a'; - v[0x2] = 'w'; - v[0x3] = 'm'; - v[0x4] = 's'; - v[0x5] = 'o'; - v[0x6] = 't'; - v[0x7] = 'x'; - for (unsigned int i = 0; i < 0x8; ++i) { - v[i] ^= ((i + 0x8) % m); - } - v[0x8] = '\0'; -} - -static inline void fill_getName(char v[]) { - // getName - static unsigned int m = 0; - - if (m == 0) { - m = 5; - } else if (m == 7) { - m = 11; - } - - v[0x0] = 'e'; - v[0x1] = 'f'; - v[0x2] = 'p'; - v[0x3] = 'N'; - v[0x4] = '`'; - v[0x5] = 'o'; - v[0x6] = 'f'; - for (unsigned int i = 0; i < 0x7; ++i) { - v[i] ^= ((i + 0x7) % m); - } - v[0x7] = '\0'; -} - -static inline void fill_getName_signature(char v[]) { - // ()Ljava/lang/String; - static unsigned int m = 0; - - if (m == 0) { - m = 19; - } else if (m == 23) { - m = 29; - } - - v[0x0] = ')'; - v[0x1] = '+'; - v[0x2] = 'O'; - v[0x3] = 'n'; - v[0x4] = 'd'; - v[0x5] = 'p'; - v[0x6] = 'f'; - v[0x7] = '\''; - v[0x8] = 'e'; - v[0x9] = 'k'; - v[0xa] = 'e'; - v[0xb] = 'k'; - v[0xc] = '"'; - v[0xd] = ']'; - v[0xe] = '{'; - v[0xf] = 'b'; - v[0x10] = 'x'; - v[0x11] = '|'; - v[0x12] = 'g'; - v[0x13] = ':'; - for (unsigned int i = 0; i < 0x14; ++i) { - v[i] ^= ((i + 0x14) % m); - } - v[0x14] = '\0'; -} - -static inline void fill_activity_manager_service_is_s(char v[]) { - // activity manager service is %s - static unsigned int m = 0; - - if (m == 0) { - m = 29; - } else if (m == 31) { - m = 37; - } - - v[0x0] = '`'; - v[0x1] = 'a'; - v[0x2] = 'w'; - v[0x3] = 'm'; - v[0x4] = 's'; - v[0x5] = 'o'; - v[0x6] = 's'; - v[0x7] = 'q'; - v[0x8] = ')'; - v[0x9] = 'g'; - v[0xa] = 'j'; - v[0xb] = 'b'; - v[0xc] = 'l'; - v[0xd] = 'i'; - v[0xe] = 'j'; - v[0xf] = 'b'; - v[0x10] = '1'; - v[0x11] = 'a'; - v[0x12] = 'v'; - v[0x13] = 'f'; - v[0x14] = 'c'; - v[0x15] = '\x7f'; - v[0x16] = 't'; - v[0x17] = '}'; - v[0x18] = '9'; - v[0x19] = 's'; - v[0x1a] = 'h'; - v[0x1b] = '<'; - v[0x1c] = '%'; - v[0x1d] = 'r'; - for (unsigned int i = 0; i < 0x1e; ++i) { - v[i] ^= ((i + 0x1e) % m); - } - v[0x1e] = '\0'; -} - -static inline void showError(JNIEnv *env, jclass object) { - char v1[0x8], v2[0x1f]; - - if (object == NULL) { - fill_activity_manager_service_is_s(v2); // 0x1f - LOGE(v2, NULL); - } else { - fill_getName(v1); // 0x8 - fill_getName_signature(v2); // 0x15 - - jclass clazz = (*env)->GetObjectClass(env, object); - jmethodID method = (*env)->GetMethodID(env, clazz, v1, v2); - jstring string = (*env)->CallObjectMethod(env, object, method); - - const char *name = (*env)->GetStringUTFChars(env, string, NULL); - fill_activity_manager_service_is_s(v2); // 0x1f - LOGE(v2, name); - - (*env)->ReleaseStringUTFChars(env, string, name); - (*env)->DeleteLocalRef(env, string); - (*env)->DeleteLocalRef(env, clazz); - } -} - -bool isAmProxy(JNIEnv *env, int sdk) { - char v1[0xb], v2[0x29]; - bool proxy = false; - jmethodID method; - jclass classActivityManager; - - if (sdk >= 26) { - fill_android_app_ActivityManager(v2); // 0x1b + 1 - classActivityManager = (*env)->FindClass(env, v2); - debug(env, "ActivityManager: %s", classActivityManager); - fill_getService(v1); // 0xa + 1 - fill_getService_signature(v2); // 0x20 + 1 - method = (*env)->GetStaticMethodID(env, classActivityManager, v1, v2); -#ifdef DEBUG - LOGI("ActivityManager.getService: %p", method); -#endif - if (method == NULL) { -#ifdef DEBUG - LOGW("cannot find ActivityManager.getService"); -#endif - (*env)->ExceptionClear(env); - goto clean3; - } - } else { - fill_android_app_ActivityManagerNative(v2); // 0x21 + 1 - classActivityManager = (*env)->FindClass(env, v2); - debug(env, "ActivityManagerNative: %s", classActivityManager); - fill_getDefault(v1); // 0xa + 1 - fill_getDefault_signature(v2); // 0x20 + 1 - method = (*env)->GetStaticMethodID(env, classActivityManager, v1, v2); -#ifdef DEBUG - LOGI("ActivityManagerNative.getDefault: %p", method); -#endif - } - - jobject activityManager = (*env)->CallStaticObjectMethod(env, classActivityManager, method); - if (activityManager == NULL) { -#ifdef DEBUG - LOGW("activity manager is null"); -#endif - if ((*env)->ExceptionCheck(env)) { -#ifdef DEBUG - (*env)->ExceptionDescribe(env); -#endif - (*env)->ExceptionClear(env); - } - goto clean3; - } - debug(env, "activity manager: %s", activityManager); - - jclass binderClass = NULL; - jobject binder = NULL; - - fill_android_os_BinderProxy(v2); // 0x16 + 1 - jclass classBinderProxy = (*env)->FindClass(env, v2); - if (classBinderProxy == NULL) { -#ifdef DEBUG - LOGW("cannot find BinderProxy"); -#endif - (*env)->ExceptionClear(env); - } else { - debug(env, "BinderProxy: %s", classBinderProxy); - } - - fill_android_os_IInterface(v2); // 0x15 + 1 - jclass classIInterface = (*env)->FindClass(env, v2); - debug(env, "IInterface: %s", classIInterface); - - if (!(*env)->IsInstanceOf(env, activityManager, classIInterface)) { -#ifdef DEBUG - LOGW("activity manager is not IInterface"); -#endif - goto clean2; - } - - fill_asBinder(v1); // 0x8 + 1 - fill_asBinder_signature(v2); // 0x16 + 1 - method = (*env)->GetMethodID(env, classIInterface, v1, v2); -#ifdef DEBUG - LOGI("IInterface.asBinder: %p", method); -#endif - binder = (*env)->CallObjectMethod(env, activityManager, method); - if (binder == NULL) { - if ((*env)->ExceptionCheck(env)) { -#ifdef DEBUG - (*env)->ExceptionDescribe(env); -#endif - (*env)->ExceptionClear(env); - } - showError(env, NULL); - proxy = true; - goto clean2; - } - debug(env, "binder: %s", binder); - - binderClass = (*env)->GetObjectClass(env, binder); - debug(env, "binder class: %s", binderClass); - - if (classBinderProxy != NULL && !(*env)->IsSameObject(env, binderClass, classBinderProxy)) { - showError(env, binderClass); - proxy = true; - goto clean2; - } - - fill_android_os_ServiceManager(v2); // 0x19 + 1 - jclass classServiceManager = (*env)->FindClass(env, v2); - if (classServiceManager == NULL) { -#ifdef DEBUG - LOGW("cannot find ServiceManager"); -#endif - (*env)->ExceptionClear(env); - goto clean2; - } - debug(env, "ServiceManager: %s", classServiceManager); - - fill_getService(v1); // 0xa + 1 - fill_getService_signature_IBinder(v2); // 0x28 + 1 - method = (*env)->GetStaticMethodID(env, classServiceManager, v1, v2); - -#ifdef DEBUG - LOGI("ServiceManager.getService: %p", method); -#endif - if (method == NULL) { - (*env)->ExceptionClear(env); - goto clean1; - } - - fill_activity(v2); // 0x8 + 1 - jstring stringActivity = (*env)->NewStringUTF(env, v2); - jobject service = (*env)->CallStaticObjectMethod(env, classServiceManager, method, - stringActivity); - jclass serviceClass = NULL; - - if (service == NULL) { - if ((*env)->ExceptionCheck(env)) { -#ifdef DEBUG - (*env)->ExceptionDescribe(env); -#endif - (*env)->ExceptionClear(env); - } - showError(env, NULL); - proxy = true; - goto clean; - } - debug(env, "service: %s", service); - - serviceClass = (*env)->GetObjectClass(env, service); - debug(env, "service class: %s", serviceClass); - if (classBinderProxy != NULL && !(*env)->IsSameObject(env, serviceClass, classBinderProxy)) { - showError(env, serviceClass); - proxy = true; - goto clean; - } - - bool equals = (*env)->IsSameObject(env, binder, service); -#ifdef DEBUG - LOGI("binder: %p, service: %p, equals: %d", binder, service, equals); -#endif - proxy = !equals; - -clean: - if (serviceClass != NULL) { - (*env)->DeleteLocalRef(env, serviceClass); - } - if (service != NULL) { - (*env)->DeleteLocalRef(env, service); - } - (*env)->DeleteLocalRef(env, stringActivity); - -clean1: - (*env)->DeleteLocalRef(env, classServiceManager); - -clean2: - if (binderClass != NULL) { - (*env)->DeleteLocalRef(env, binderClass); - } - if (binder != NULL) { - (*env)->DeleteLocalRef(env, binder); - } - if (classBinderProxy != NULL) { - (*env)->DeleteLocalRef(env, classBinderProxy); - } - (*env)->DeleteLocalRef(env, classIInterface); - (*env)->DeleteLocalRef(env, activityManager); - -clean3: - (*env)->DeleteLocalRef(env, classActivityManager); - - return proxy; -} diff --git a/native/src/main/jni/integrity/am-proxy.h b/native/src/main/jni/integrity/am-proxy.h deleted file mode 100644 index 7eee7a366..000000000 --- a/native/src/main/jni/integrity/am-proxy.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// Created by Thom on 2019/3/15. -// - -#ifndef BREVENT_AM_PROXY_H -#define BREVENT_AM_PROXY_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -bool isAmProxy(JNIEnv *env, int sdk); - -#ifdef __cplusplus -} -#endif - -#endif //BREVENT_AM_PROXY_H diff --git a/native/src/main/jni/integrity/apk-sign-v2.c b/native/src/main/jni/integrity/apk-sign-v2.c deleted file mode 100644 index f1ca4b9d6..000000000 --- a/native/src/main/jni/integrity/apk-sign-v2.c +++ /dev/null @@ -1,169 +0,0 @@ -// -// Created by Thom on 2019/3/8. -// - -#include -#include -#include - -#ifdef MAIN -#include -#else - -#include "common.h" -#include "openat.h" - -#endif - -static bool isApkSigBlock42(const char *buffer) { - // APK Sig Block 42 - return *buffer == 'A' - && *++buffer == 'P' - && *++buffer == 'K' - && *++buffer == ' ' - && *++buffer == 'S' - && *++buffer == 'i' - && *++buffer == 'g' - && *++buffer == ' ' - && *++buffer == 'B' - && *++buffer == 'l' - && *++buffer == 'o' - && *++buffer == 'c' - && *++buffer == 'k' - && *++buffer == ' ' - && *++buffer == '4' - && *++buffer == '2'; -} - -int checkSignature(const char *path) { - unsigned char buffer[0x11] = {0}; - uint32_t size4; - uint64_t size8, size_of_block; - -#ifdef DEBUG - LOGI("check signature for %s", path); -#endif - - int sign = -1; - int fd = (int) openAt(AT_FDCWD, path, O_RDONLY); -#ifdef DEBUG_OPENAT - LOGI("openat %s returns %d", path, fd); -#endif - if (fd < 0) { - return sign; - } - - sign = 1; - // https://en.wikipedia.org/wiki/Zip_(file_format)#End_of_central_directory_record_(EOCD) - for (int i = 0;; ++i) { - unsigned short n; - lseek(fd, -i - 2, SEEK_END); - read(fd, &n, 2); - if (n == i) { - lseek(fd, -22, SEEK_CUR); - read(fd, &size4, 4); - if ((size4 ^ 0xcafebabeu) == 0xccfbf1eeu) { -#ifdef MAIN - if (i > 0) { - printf("warning: comment length is %d\n", i); - } -#endif - break; - } - } - if (i == 0xffff) { -#ifdef MAIN - printf("error: cannot find eocd\n"); -#endif - goto clean; - } - } - - lseek(fd, 12, SEEK_CUR); - // offset - read(fd, &size4, 0x4); - lseek(fd, (off_t) (size4 - 0x18), SEEK_SET); - - read(fd, &size8, 0x8); - read(fd, buffer, 0x10); - if (!isApkSigBlock42((char *) buffer)) { - goto clean; - } - - lseek(fd, (off_t) (size4 - (size8 + 0x8)), SEEK_SET); - read(fd, &size_of_block, 0x8); - if (size_of_block != size8) { - goto clean; - } - - for (;;) { - uint32_t id; - uint32_t offset; - read(fd, &size8, 0x8); // sequence length - if (size8 == size_of_block) { - break; - } - read(fd, &id, 0x4); // id - offset = 4; -#ifdef MAIN - printf("id: 0x%08x\n", id); -#endif - if ((id ^ 0xdeadbeefu) == 0xafa439f5u || (id ^ 0xdeadbeefu) == 0x2efed62f) { - read(fd, &size4, 0x4); // signer-sequence length - read(fd, &size4, 0x4); // signer length - read(fd, &size4, 0x4); // signed data length - offset += 0x4 * 3; - - read(fd, &size4, 0x4); // digests-sequence length - lseek(fd, (off_t) (size4), SEEK_CUR);// skip digests - offset += 0x4 + size4; - - read(fd, &size4, 0x4); // certificates length - read(fd, &size4, 0x4); // certificate length - offset += 0x4 * 2; -#ifdef MAIN - int hash = 1; - signed char c; - for (unsigned i = 0; i < size4; ++i) { - read(fd, &c, 0x1); - hash = 31 * hash + c; - } - offset += size4; - printf(" size: 0x%04x, hash: 0x%08x\n", size4, ((unsigned) hash) ^ 0x14131211u); -#else -#if defined(GENUINE_SIZE) && defined(GENUINE_HASH) - if (size4 == GENUINE_SIZE) { - int hash = 1; - signed char c; - for (unsigned i = 0; i < size4; ++i) { - read(fd, &c, 0x1); - hash = 31 * hash + c; - } - offset += size4; - if ((((unsigned) hash) ^ 0x14131211u) == GENUINE_HASH) { - sign = 0; - break; - } - } -#else - sign = 0; - break; -#endif -#endif - } - lseek(fd, (off_t) (size8 - offset), SEEK_CUR); - } - -clean: - close(fd); - - return sign; -} - -#ifdef MAIN -int main(int argc, char **argv) { - if (argc > 1) { - checkSignature(argv[1]); - } -} -#endif diff --git a/native/src/main/jni/integrity/apk-sign-v2.h b/native/src/main/jni/integrity/apk-sign-v2.h deleted file mode 100644 index 653e6dca9..000000000 --- a/native/src/main/jni/integrity/apk-sign-v2.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Created by Thom on 2019/3/8. -// - -#ifndef BREVENT_APK_SIGN_V2_H -#define BREVENT_APK_SIGN_V2_H - -#ifdef __cplusplus -extern "C" { -#endif - -int checkSignature(const char *path); - -#ifdef __cplusplus -} -#endif - -#endif //BREVENT_APK_SIGN_V2_H diff --git a/native/src/main/jni/integrity/common.c b/native/src/main/jni/integrity/common.c deleted file mode 100644 index dd92b5d97..000000000 --- a/native/src/main/jni/integrity/common.c +++ /dev/null @@ -1,233 +0,0 @@ -// -// Created by Thom on 2019/3/20. -// - -#include -#include -#include -#include -#include "common.h" -#include "plt.h" - -static volatile int mGenuine; - -static bool onCheckTrue(JNIEnv *env __unused) { -#ifdef DEBUG_NATIVE - has_native_libs(); -#endif -#ifdef DEBUG_GENUINE_MOCK - start_native_activity_async(env); -#endif - return true; -} - -static bool onCheckFalse(JNIEnv *env __unused) { -#if defined(GENUINE_FALSE_CRASH) - return false; -#elif defined(GENUINE_FALSE_NATIVE) - start_native_activity_async(env); -#endif - return true; -} - -static bool onCheckFake(JNIEnv *env __unused) { -#if defined(GENUINE_FAKE_CRASH) - return false; -#elif defined(GENUINE_FAKE_NATIVE) - start_native_activity_async(env); -#endif - return true; -} - -static bool onCheckOverlay(JNIEnv *env __unused) { -#if defined(GENUINE_OVERLAY_CRASH) - return false; -#elif defined(GENUINE_OVERLAY_NATIVE) - start_native_activity_async(env); -#endif - return true; -} - -static bool onCheckOdex(JNIEnv *env __unused) { -#if defined(GENUINE_ODEX_CRASH) - return false; -#elif defined(GENUINE_ODEX_NATIVE) - start_native_activity_async(env); -#endif - return true; -} - -static bool onCheckDex(JNIEnv *env __unused) { -#if defined(GENUINE_DEX_CRASH) - return false; -#elif defined(GENUINE_DEX_NATIVE) - start_native_activity_async(env); -#endif - return true; -} - -static bool onCheckProxy(JNIEnv *env __unused) { -#if defined(GENUINE_PROXY_CRASH) - return false; -#elif defined(GENUINE_PROXY_NATIVE) - start_native_activity_async(env); -#endif - return true; -} - -static bool onCheckError(JNIEnv *env __unused) { -#if defined(GENUINE_ERROR_CRASH) - return false; -#elif defined(GENUINE_ERROR_NATIVE) - start_native_activity_async(env); -#endif - return true; -} - -static bool onCheckFatal(JNIEnv *env __unused) { -#if defined(GENUINE_FATAL_CRASH) - return false; -#elif defined(GENUINE_FATAL_NATIVE) - start_native_activity_async(env); -#endif - return true; -} - -static bool onCheckNoapk(JNIEnv *env __unused) { -#if defined(GENUINE_NOAPK_CRASH) - return false; -#elif defined(GENUINE_NOAPK_NATIVE) - start_native_activity_async(env); -#endif - return true; -} - -bool setGenuine(JNIEnv *env, int genuine) { - mGenuine = genuine; - switch (genuine) { - case CHECK_TRUE: - return onCheckTrue(env); - case CHECK_FALSE: - return onCheckFalse(env); - case CHECK_FAKE: - return onCheckFake(env); - case CHECK_OVERLAY: - return onCheckOverlay(env); - case CHECK_ODEX: - return onCheckOdex(env); - case CHECK_DEX: - return onCheckDex(env); - case CHECK_PROXY: - return onCheckProxy(env); - case CHECK_ERROR: - return onCheckError(env); - case CHECK_FATAL: - return onCheckFatal(env); - case CHECK_NOAPK: - return onCheckNoapk(env); - default: - return true; - } -} - -int getGenuine() { - return mGenuine; -} - -char *getGenuinePackageName() { -#ifdef GET_GENUINE_PACKAGE_NAME - return GET_GENUINE_PACKAGE_NAME(); -#elif defined(GENUINE_NAME) - static unsigned int m = 0; - if (m == 0) { - m = 20; - } else if (m == 23) { - m = 29; - } - char name[] = GENUINE_NAME; - unsigned int length = sizeof(name) - 1; - for (unsigned int i = 0; i < length; ++i) { - name[i] ^= ((i + length) % m); - } - name[length] = '\0'; - return strdup(name); -#else - return NULL; -#endif -} - -__attribute__((__format__ (__printf__, 2, 0))) -void genuine_log_print(int prio, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - __android_log_vprint(prio, TAG, fmt, ap); - va_end(ap); -} - -static inline void fill_ro_build_version_sdk(char v[]) { - // ro.build.version.sdk - static unsigned int m = 0; - - if (m == 0) { - m = 19; - } else if (m == 23) { - m = 29; - } - - v[0x0] = 's'; - v[0x1] = 'm'; - v[0x2] = '-'; - v[0x3] = 'f'; - v[0x4] = 'p'; - v[0x5] = 'o'; - v[0x6] = 'k'; - v[0x7] = 'l'; - v[0x8] = '\''; - v[0x9] = '|'; - v[0xa] = 'n'; - v[0xb] = '~'; - v[0xc] = '~'; - v[0xd] = 'g'; - v[0xe] = '`'; - v[0xf] = '~'; - v[0x10] = '?'; - v[0x11] = 'a'; - v[0x12] = 'd'; - v[0x13] = 'j'; - for (unsigned int i = 0; i < 0x14; ++i) { - v[i] ^= ((i + 0x14) % m); - } - v[0x14] = '\0'; -} - -int getSdk() { - static int sdk = 0; - if (sdk == 0) { - char v1[0x20]; - char prop[PROP_VALUE_MAX] = {0}; - fill_ro_build_version_sdk(v1); - __system_property_get(v1, prop); - sdk = (int) strtol(prop, NULL, 10); - } - return sdk; -} - -#ifdef DEBUG - -void debug(JNIEnv *env, const char *format, jobject object) { - if (object == NULL) { - LOGI(format, NULL); - } else { - jclass objectClass = (*env)->FindClass(env, "java/lang/Object"); - jmethodID toString = (*env)->GetMethodID(env, objectClass, "toString", - "()Ljava/lang/String;"); - jstring string = (jstring) (*env)->CallObjectMethod(env, object, toString); - const char *value = (*env)->GetStringUTFChars(env, string, NULL); - LOGI(format, value); - (*env)->ReleaseStringUTFChars(env, string, value); - (*env)->DeleteLocalRef(env, string); - (*env)->DeleteLocalRef(env, objectClass); - } -} - -#endif diff --git a/native/src/main/jni/integrity/common.h b/native/src/main/jni/integrity/common.h deleted file mode 100644 index 20103b894..000000000 --- a/native/src/main/jni/integrity/common.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// Created by Thom on 2019/3/20. -// - -#ifndef BREVENT_COMMON_H -#define BREVENT_COMMON_H - -#include -#include -#include - -#if __has_include("genuine.h") -#include "genuine.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - CHECK_TRUE, - CHECK_FALSE, - CHECK_FAKE, - CHECK_OVERLAY, - CHECK_ODEX, - CHECK_DEX, - CHECK_PROXY, - CHECK_ERROR, - CHECK_FATAL, - CHECK_NOAPK, -}; - -#ifndef TAG -#define TAG "Genuine" -#endif - -#ifndef LOGI -#define LOGI(...) (genuine_log_print(ANDROID_LOG_INFO, __VA_ARGS__)) -#endif - -#ifndef LOGW -#define LOGW(...) (genuine_log_print(ANDROID_LOG_WARN, __VA_ARGS__)) -#endif - -#ifndef LOGE -#define LOGE(...) (genuine_log_print(ANDROID_LOG_ERROR, __VA_ARGS__)) -#endif - -void genuine_log_print(int prio, const char *fmt, ...); - -char *getGenuinePackageName(); - -bool setGenuine(JNIEnv *env, int genuine); - -int getGenuine(); - -int getSdk(); - -bool has_native_libs(); - -#ifdef DEBUG - -void debug(JNIEnv *env, const char *format, jobject object); - -#else -#define debug(...) do {} while(0); -#endif - -#ifdef __cplusplus -} -#endif - -#endif //BREVENT_COMMON_H diff --git a/native/src/main/jni/integrity/genuine.c b/native/src/main/jni/integrity/genuine.c deleted file mode 100644 index 0b136ae90..000000000 --- a/native/src/main/jni/integrity/genuine.c +++ /dev/null @@ -1,1090 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "plt.h" -#include "inline.h" -#include "apk-sign-v2.h" -#include "am-proxy.h" -#include "common.h" -#include "openat.h" -#include "path.h" - -#ifdef CHECK_MOUNT -#include "mount.h" -#endif - -static int genuine = CHECK_TRUE; - -static int sdk; - -static int uid; - -static inline void fill_maps(char v[]) { - static unsigned int m = 0; - if (m == 0) { - m = 13; - } else if (m == 17) { - m = 19; - } - v[0x0] = '-'; - v[0x1] = 's'; - v[0x2] = 'v'; - v[0x3] = 'j'; - v[0x4] = 'e'; - v[0x5] = '('; - v[0x6] = '{'; - v[0x7] = 'l'; - v[0x8] = 'f'; - v[0x9] = 'm'; - v[0xa] = '#'; - v[0xb] = 'm'; - v[0xc] = '`'; - v[0xd] = 'r'; - v[0xe] = 'p'; - for (unsigned int i = 0; i < 0xf; ++i) { - v[i] ^= ((i + 0xf) % m); - } - v[0xf] = '\0'; -} - -#ifndef NO_CHECK_MAPS -static inline void fill_cannot_open_proc_self_maps(char v[]) { - // cannot open /proc/self/maps - static unsigned int m = 0; - - if (m == 0) { - m = 23; - } else if (m == 29) { - m = 31; - } - - v[0x0] = 'g'; - v[0x1] = 'd'; - v[0x2] = 'h'; - v[0x3] = 'i'; - v[0x4] = 'g'; - v[0x5] = '}'; - v[0x6] = '*'; - v[0x7] = 'd'; - v[0x8] = '|'; - v[0x9] = 'h'; - v[0xa] = '`'; - v[0xb] = '/'; - v[0xc] = '?'; - v[0xd] = 'a'; - v[0xe] = '`'; - v[0xf] = '|'; - v[0x10] = 'w'; - v[0x11] = ':'; - v[0x12] = 'e'; - v[0x13] = 'e'; - v[0x14] = 'm'; - v[0x15] = 'd'; - v[0x16] = ','; - v[0x17] = 'i'; - v[0x18] = 'd'; - v[0x19] = 'v'; - v[0x1a] = 't'; - for (unsigned int i = 0; i < 0x1b; ++i) { - v[i] ^= ((i + 0x1b) % m); - } - v[0x1b] = '\0'; -} - -static inline void fill_r(char v[]) { - static unsigned int m = 0; - - if (m == 0) { - m = 2; - } else if (m == 3) { - m = 5; - } - - v[0x0] = 's'; - for (unsigned int i = 0; i < 0x1; ++i) { - v[i] ^= ((i + 0x1) % m); - } - v[0x1] = '\0'; -} - -static inline void rstrip(char *line) { - char *path = line; - if (line != NULL) { - while (*path && *path != '\r' && *path != '\n') { - ++path; - } - if (*path) { - *path = '\0'; - } - } -} - -static inline bool isapk(const char *str) { - const char *dot = strrchr(str, '.'); - return dot != NULL - && *++dot == 'a' - && *++dot == 'p' - && *++dot == 'k' - && (*++dot == '\0' || *dot == '\r' || *dot == '\n'); -} - -static inline bool isdex(const char *str) { - const char *dot = strrchr(str, '.'); - return dot != NULL - && *++dot == 'd' - && *++dot == 'e' - && *++dot == 'x' - && (*++dot == '\0' || *dot == '\r' || *dot == '\n'); -} - -static inline bool isodex(const char *str) { - const char *dot = strrchr(str, '.'); - return dot != NULL - && *++dot == 'o' - && *++dot == 'd' - && *++dot == 'e' - && *++dot == 'x' - && (*++dot == '\0' || *dot == '\r' || *dot == '\n'); -} - -static inline bool isso(const char *str) { - const char *dot = strrchr(str, '.'); - return dot != NULL - && *++dot == 's' - && *++dot == 'o' - && (*++dot == '\0' || *dot == '\r' || *dot == '\n'); -} - -#ifdef ANTI_ODEX -static inline size_t fill_dex2oat_cmdline(char v[]) { - // dex2oat-cmdline - static unsigned int m = 0; - - if (m == 0) { - m = 13; - } else if (m == 17) { - m = 19; - } - - v[0x0] = 'f'; - v[0x1] = 'f'; - v[0x2] = '|'; - v[0x3] = '7'; - v[0x4] = 'i'; - v[0x5] = 'f'; - v[0x6] = '|'; - v[0x7] = '$'; - v[0x8] = 'i'; - v[0x9] = 'f'; - v[0xa] = 'h'; - v[0xb] = 'l'; - v[0xc] = 'h'; - v[0xd] = 'l'; - v[0xe] = 'f'; - for (unsigned int i = 0; i < 0xf; ++i) { - v[i] ^= ((i + 0xf) % m); - } - v[0xf] = '\0'; - return 0xf; -} - -static inline size_t fill_dex_file(char v[]) { - // --dex-file - static unsigned int m = 0; - - if (m == 0) { - m = 7; - } else if (m == 11) { - m = 13; - } - - v[0x0] = '.'; - v[0x1] = ')'; - v[0x2] = 'a'; - v[0x3] = 'c'; - v[0x4] = 'x'; - v[0x5] = ','; - v[0x6] = 'd'; - v[0x7] = 'j'; - v[0x8] = 'h'; - v[0x9] = '`'; - for (unsigned int i = 0; i < 0xa; ++i) { - v[i] ^= ((i + 0xa) % m); - } - v[0xa] = '\0'; - return 0xa; -} - -static inline int checkOdex(const char *path) { - size_t len; - char *cmdline; - char buffer[0x400], find[64]; - - int ret = 0; - int fd = open(path, (unsigned) O_RDONLY | (unsigned) O_CLOEXEC); - if (fd == -1) { - return 1; - } - - lseek(fd, 0x1000, SEEK_SET); - read(fd, buffer, 0x400); - - cmdline = buffer; - len = fill_dex2oat_cmdline(find) + 1; - for (int i = 0; i < 0x200; ++i, ++cmdline) { - if (memcmp(cmdline, find, len) == 0) { - cmdline += len; - fill_dex_file(find); - if ((ret = (strstr(cmdline, find) != NULL))) { - fill_dex2oat_cmdline(find); - LOGE(find); - LOGE(cmdline); - } - break; - } - } - - close(fd); - - return ret; -} -#endif - -static inline bool isSameFile(const char *path1, const char *path2) { - struct stat stat1, stat2; - if (path1 == NULL || path2 == NULL) { - return false; - } - if (lstat(path1, &stat1)) { - return false; - } - if (lstat(path2, &stat2)) { - return false; - } - return stat1.st_dev == stat2.st_dev && stat1.st_ino == stat2.st_ino; -} - -static inline void fill_ba88(char v[]) { - // ba887869b4a4a6d1e915d383fad97c49 - static unsigned int m = 0; - if (m == 0) { - m = 13; - } else if (m == 17) { - m = 19; - } - v[0x0] = 'f'; - v[0x1] = 'o'; - v[0x2] = '['; - v[0x3] = 'l'; - v[0x4] = 'r'; - v[0x5] = 'b'; - v[0x6] = 'z'; - v[0x7] = 'h'; - v[0x8] = '~'; - v[0x9] = 'n'; - v[0xa] = 'S'; - v[0xb] = 'p'; - v[0xc] = 'i'; - v[0xd] = 'f'; - v[0xe] = 'q'; - for (unsigned int i = 0; i < 0xf; ++i) { - v[i] ^= ((i + 0xf) % m); - } - v[0xf] = '\0'; -} - -static inline bool isSame(const char *path1, const char *path2) { - if (path1[0] == '/') { - return strcmp(path1, path2) == 0; - } else { - return strcmp(path1, strrchr(path2, '/') + 1) == 0; - } -} - -static inline void fill_cannot_find_s(char v[]) { - // cannot find %s - static unsigned int m = 0; - - if (m == 0) { - m = 13; - } else if (m == 17) { - m = 19; - } - - v[0x0] = 'b'; - v[0x1] = 'c'; - v[0x2] = 'm'; - v[0x3] = 'j'; - v[0x4] = 'j'; - v[0x5] = 'r'; - v[0x6] = '\''; - v[0x7] = 'n'; - v[0x8] = '`'; - v[0x9] = 'd'; - v[0xa] = 'o'; - v[0xb] = ','; - v[0xc] = '%'; - v[0xd] = 'r'; - for (unsigned int i = 0; i < 0xe; ++i) { - v[i] ^= ((i + 0xe) % m); - } - v[0xe] = '\0'; -} - -static inline void fill_invalid_signature_path_s(char v[]) { - // invalid signature, path: %s - static unsigned int m = 0; - - if (m == 0) { - m = 23; - } else if (m == 29) { - m = 31; - } - - v[0x0] = 'm'; - v[0x1] = 'k'; - v[0x2] = 'p'; - v[0x3] = 'f'; - v[0x4] = 'd'; - v[0x5] = '`'; - v[0x6] = 'n'; - v[0x7] = '+'; - v[0x8] = '\x7f'; - v[0x9] = 'd'; - v[0xa] = 'i'; - v[0xb] = 'a'; - v[0xc] = 'q'; - v[0xd] = 'e'; - v[0xe] = 'g'; - v[0xf] = 'a'; - v[0x10] = 'q'; - v[0x11] = '9'; - v[0x12] = '6'; - v[0x13] = 'p'; - v[0x14] = '`'; - v[0x15] = 'v'; - v[0x16] = 'k'; - v[0x17] = '>'; - v[0x18] = '%'; - v[0x19] = '#'; - v[0x1a] = 't'; - for (unsigned int i = 0; i < 0x1b; ++i) { - v[i] ^= ((i + 0x1b) % m); - } - v[0x1b] = '\0'; -} - -enum { - TYPE_NON, - TYPE_APK, - TYPE_DEX, - TYPE_SO, -}; - -static inline int checkMaps(const char *packageName) { - FILE *fp = NULL; - char line[PATH_MAX]; - char maps[0x10]; - int check = genuine; - bool loaded = false; - - fill_maps(maps); - int fd = (int) openAt(AT_FDCWD, maps, O_RDONLY); -#ifdef DEBUG_OPENAT - LOGI("openat %s returns %d", maps, fd); -#endif - if (fd < 0) { - fill_cannot_open_proc_self_maps(line); - LOGE(line); - return CHECK_ERROR; - } - - Symbol symbol; - fill_ba88(line); - memset(&symbol, 0, sizeof(Symbol)); - symbol.check = (PLT_CHECK_PLT_APP | PLT_CHECK_NAME); - symbol.symbol_name = (char *) line; - if (dl_iterate_phdr_symbol(&symbol)) { - LOGE(line); - check = CHECK_ERROR; - goto clean2; - } - -#if __ANDROID_API__ >= 21 || !defined(__arm__) - if (symbol.size == 0) { - LOGE(line); - check = CHECK_ERROR; - goto clean2; - } -#endif - - char mode[0x2]; - fill_r(mode); - - fp = fdopen(fd, mode); - if (fp == NULL) { - fill_cannot_open_proc_self_maps(line); - LOGE(line); - check = CHECK_ERROR; - goto clean3; - } - - while (fgets(line, PATH_MAX - 1, fp) != NULL) { - int type; - char *path = line; - if (strchr(line, '/') == NULL) { - continue; - } - while (*path != '/') { - ++path; - } - rstrip(path); - if (isapk(path)) { - type = TYPE_APK; - } else if (isodex(path) || isdex(path)) { - type = TYPE_DEX; - } else if (isso(path)) { - type = TYPE_SO; - if (symbol.size > 0) { - bool found = false; - for (int i = 0; i < symbol.size; ++i) { - if (symbol.names[i] != NULL) { - if (isSame(symbol.names[i], path)) { - free(symbol.names[i]); - symbol.names[i] = NULL; - } else { - found = true; - } - } - } - if (!found) { - symbol.size = 0; - } - } - } else { - type = TYPE_NON; - } -#ifdef DEBUG_MAPS - LOGI("type: %d, line: %s", type, line); -#endif - if (strstr(path, packageName) != NULL) { - if (type == TYPE_APK) { -#ifdef DEBUG - LOGI("check %s", path); -#endif - if (isDataApp(path) || isExternalSdApp(path)) { - loaded = true; - int sign = checkSignature(path); - if (sign) { - fill_invalid_signature_path_s(line); - LOGE(line, path); -#ifndef DEBUG_FAKE - check = sign < 0 ? CHECK_NOAPK : CHECK_FAKE; -#endif - } - } - } else if (type == TYPE_DEX) { -#ifdef ANTI_ODEX -#ifdef DEBUG - LOGI("check %s", path); -#endif - if (checkOdex(path)) { - LOGE(path); - check = CHECK_ODEX; - } -#endif - } - } else if (isDataApp(path)) { - if (type == TYPE_DEX) { - LOGE(path); - check = CHECK_DEX; - } else if (type == TYPE_APK) { -#ifdef ANTI_OVERLAY - LOGE(path); - check = CHECK_OVERLAY; -#endif - } - } - } - - fclose(fp); - -clean3: - close(fd); - -clean2: - fill_cannot_find_s(line); - if (!loaded) { - LOGE(line, ""); - check = CHECK_ERROR; - } - for (int i = 0; i < symbol.size; ++i) { - if (symbol.names[i] != NULL) { - if (strchr(symbol.names[i], '!') == NULL) { - LOGE(line, symbol.names[i]); - check = CHECK_ERROR; - } - free(symbol.names[i]); - symbol.names[i] = NULL; - } - } - if (symbol.names != NULL) { - free(symbol.names); - symbol.names = NULL; - } - - return check; -} -#endif - -#ifdef CHECK_HOOK -static inline void fill_jniRegisterNativeMethods(char v[]) { - // jniRegisterNativeMethods - static unsigned int m = 0; - - if (m == 0) { - m = 23; - } else if (m == 29) { - m = 31; - } - - v[0x0] = 'k'; - v[0x1] = 'l'; - v[0x2] = 'j'; - v[0x3] = 'V'; - v[0x4] = '`'; - v[0x5] = 'a'; - v[0x6] = 'n'; - v[0x7] = '{'; - v[0x8] = '}'; - v[0x9] = 'o'; - v[0xa] = 'y'; - v[0xb] = 'B'; - v[0xc] = 'l'; - v[0xd] = 'z'; - v[0xe] = 'f'; - v[0xf] = 'f'; - v[0x10] = 't'; - v[0x11] = '_'; - v[0x12] = 'v'; - v[0x13] = '`'; - v[0x14] = '}'; - v[0x15] = 'y'; - v[0x16] = 'd'; - v[0x17] = 'r'; - for (unsigned int i = 0; i < 0x18; ++i) { - v[i] ^= ((i + 0x18) % m); - } - v[0x18] = '\0'; -} - -static inline void fill___openat(char v[]) { - // __openat - static unsigned int m = 0; - - if (m == 0) { - m = 7; - } else if (m == 11) { - m = 13; - } - - v[0x0] = '^'; - v[0x1] = ']'; - v[0x2] = 'l'; - v[0x3] = 't'; - v[0x4] = '`'; - v[0x5] = 'h'; - v[0x6] = 'a'; - v[0x7] = 'u'; - for (unsigned int i = 0; i < 0x8; ++i) { - v[i] ^= ((i + 0x8) % m); - } - v[0x8] = '\0'; -} - -static inline void fill_openat(char v[]) { - // openat - static unsigned int m = 0; - - if (m == 0) { - m = 5; - } else if (m == 7) { - m = 11; - } - - v[0x0] = 'n'; - v[0x1] = 'r'; - v[0x2] = 'f'; - v[0x3] = 'j'; - v[0x4] = 'a'; - v[0x5] = 'u'; - for (unsigned int i = 0; i < 0x6; ++i) { - v[i] ^= ((i + 0x6) % m); - } - v[0x6] = '\0'; -} - -static inline void fill_open(char v[]) { - // open - static unsigned int m = 0; - - if (m == 0) { - m = 3; - } else if (m == 5) { - m = 7; - } - - v[0x0] = 'n'; - v[0x1] = 'r'; - v[0x2] = 'e'; - v[0x3] = 'o'; - for (unsigned int i = 0; i < 0x4; ++i) { - v[i] ^= ((i + 0x4) % m); - } - v[0x4] = '\0'; -} - -#endif - -static inline void fill_sdk_d_genuine_d(char v[]) { - // sdk: %d, genuine: %d - static unsigned int m = 0; - - if (m == 0) { - m = 19; - } else if (m == 23) { - m = 29; - } - - v[0x0] = 'r'; - v[0x1] = 'f'; - v[0x2] = 'h'; - v[0x3] = '>'; - v[0x4] = '%'; - v[0x5] = '#'; - v[0x6] = 'c'; - v[0x7] = '$'; - v[0x8] = ')'; - v[0x9] = 'm'; - v[0xa] = 'n'; - v[0xb] = 'b'; - v[0xc] = 'x'; - v[0xd] = 'g'; - v[0xe] = 'a'; - v[0xf] = 'u'; - v[0x10] = '+'; - v[0x11] = '2'; - v[0x12] = '%'; - v[0x13] = 'e'; - for (unsigned int i = 0; i < 0x14; ++i) { - v[i] ^= ((i + 0x14) % m); - } - v[0x14] = '\0'; -} - -static inline void fill_add_sigcont(char v[]) { - // add sigcont handler - static unsigned int m = 0; - - if (m == 0) { - m = 17; - } else if (m == 19) { - m = 23; - } - - v[0x0] = 'c'; - v[0x1] = 'g'; - v[0x2] = '`'; - v[0x3] = '%'; - v[0x4] = 'u'; - v[0x5] = 'n'; - v[0x6] = 'o'; - v[0x7] = 'j'; - v[0x8] = 'e'; - v[0x9] = 'e'; - v[0xa] = 'x'; - v[0xb] = '-'; - v[0xc] = 'f'; - v[0xd] = 'n'; - v[0xe] = '~'; - v[0xf] = 'd'; - v[0x10] = 'm'; - v[0x11] = 'g'; - v[0x12] = 'q'; - for (unsigned int i = 0; i < 0x13; ++i) { - v[i] ^= ((i + 0x13) % m); - } - v[0x13] = '\0'; -} - -static inline void fill_received_sigcont(char v[]) { - // received sigcont - static unsigned int m = 0; - - if (m == 0) { - m = 13; - } else if (m == 17) { - m = 19; - } - - v[0x0] = 'q'; - v[0x1] = 'a'; - v[0x2] = 'f'; - v[0x3] = 'c'; - v[0x4] = 'n'; - v[0x5] = '~'; - v[0x6] = 'l'; - v[0x7] = 'n'; - v[0x8] = '+'; - v[0x9] = '\x7f'; - v[0xa] = 'i'; - v[0xb] = 'f'; - v[0xc] = 'a'; - v[0xd] = 'l'; - v[0xe] = 'j'; - v[0xf] = 'q'; - for (unsigned int i = 0; i < 0x10; ++i) { - v[i] ^= ((i + 0x10) % m); - } - v[0x10] = '\0'; -} - -#if defined(CHECK_ARM64) && defined(__arm__) -static inline void fill_ro_product_cpu_abi(char v[]) { - // ro.product.cpu.abi - static unsigned int m = 0; - - if (m == 0) { - m = 17; - } else if (m == 19) { - m = 23; - } - - v[0x0] = 's'; - v[0x1] = 'm'; - v[0x2] = '-'; - v[0x3] = 't'; - v[0x4] = 'w'; - v[0x5] = 'i'; - v[0x6] = 'c'; - v[0x7] = '}'; - v[0x8] = 'j'; - v[0x9] = '~'; - v[0xa] = '%'; - v[0xb] = 'o'; - v[0xc] = '}'; - v[0xd] = '{'; - v[0xe] = '!'; - v[0xf] = 'q'; - v[0x10] = 'b'; - v[0x11] = 'h'; - for (unsigned int i = 0; i < 0x12; ++i) { - v[i] ^= ((i + 0x12) % m); - } - v[0x12] = '\0'; -} - -static inline bool isArm64V8a(const char *str) { - return str != NULL - && *str == 'a' - && *++str == 'r' - && *++str == 'm' - && *++str == '6' - && *++str == '4' - && *++str == '-' - && *++str == 'v' - && *++str == '8' - && *++str == 'a'; -} - -static inline void fill_32_64(char v[]) { - // run in 32 on 64 machine - static unsigned int m = 0; - - if (m == 0) { - m = 19; - } else if (m == 23) { - m = 29; - } - - v[0x0] = 'v'; - v[0x1] = 'p'; - v[0x2] = 'h'; - v[0x3] = '\''; - v[0x4] = 'a'; - v[0x5] = 'g'; - v[0x6] = '*'; - v[0x7] = '8'; - v[0x8] = '>'; - v[0x9] = '-'; - v[0xa] = 'a'; - v[0xb] = 'a'; - v[0xc] = '0'; - v[0xd] = '\''; - v[0xe] = '&'; - v[0xf] = ' '; - v[0x10] = 'l'; - v[0x11] = 'c'; - v[0x12] = '`'; - v[0x13] = 'l'; - v[0x14] = 'l'; - v[0x15] = 'h'; - v[0x16] = 'b'; - for (unsigned int i = 0; i < 0x17; ++i) { - v[i] ^= ((i + 0x17) % m); - } - v[0x17] = '\0'; -} -#endif - -static void handler(int sig __unused) { - char v[0x11]; - fill_received_sigcont(v); - LOGI(v); -} - -#ifdef DEBUG_HOOK_IO - -static void check_hook_function(void *handle, const char *name) { - void *symbol = dlsym(handle, name); -#ifdef DEBUG - void *symbol2 = plt_dlsym(name, NULL); - LOGI("symbol: %s, dlsym: %p, dl_iterate_phdr: %p", name, symbol, symbol2); -#endif - if (symbol != NULL && setRead(symbol) && isInlineHooked(symbol)) { - LOGI("%s is hooked", name); - } -} - -#define HOOK_SYMBOL(x, y) check_hook_function(x, #y) - -static void check_inline_hook_io() { - void *handle = dlopen("libc.so", RTLD_NOW); - if (handle) { - HOOK_SYMBOL(handle, faccessat); - HOOK_SYMBOL(handle, __openat); - HOOK_SYMBOL(handle, fchmodat); - HOOK_SYMBOL(handle, fchownat); - HOOK_SYMBOL(handle, renameat); - HOOK_SYMBOL(handle, fstatat64); - HOOK_SYMBOL(handle, __statfs); - HOOK_SYMBOL(handle, __statfs64); - HOOK_SYMBOL(handle, mkdirat); - HOOK_SYMBOL(handle, mknodat); - HOOK_SYMBOL(handle, truncate); - HOOK_SYMBOL(handle, linkat); - HOOK_SYMBOL(handle, readlinkat); - HOOK_SYMBOL(handle, unlinkat); - HOOK_SYMBOL(handle, symlinkat); - HOOK_SYMBOL(handle, utimensat); - HOOK_SYMBOL(handle, __getcwd); - HOOK_SYMBOL(handle, chdir); - HOOK_SYMBOL(handle, execve); - } - dlclose(handle); -} - -#endif - -static inline void fill_openat_is_hooked(char v[]) { - // openAt is hooked - static unsigned int m = 0; - - if (m == 0) { - m = 13; - } else if (m == 17) { - m = 19; - } - - v[0x0] = 'l'; - v[0x1] = 't'; - v[0x2] = '`'; - v[0x3] = 'h'; - v[0x4] = 'F'; - v[0x5] = '|'; - v[0x6] = ')'; - v[0x7] = 'c'; - v[0x8] = 'x'; - v[0x9] = ','; - v[0xa] = 'h'; - v[0xb] = 'n'; - v[0xc] = 'm'; - v[0xd] = 'h'; - v[0xe] = 'a'; - v[0xf] = 'a'; - for (unsigned int i = 0; i < 0x10; ++i) { - v[i] ^= ((i + 0x10) % m); - } - v[0x10] = '\0'; -} - -bool has_native_libs() { -#if __ANDROID_API__ >= 24 - return true; -#else - Symbol symbol; - char v[0x10]; - fill_ba88(v); - memset(&symbol, 0, sizeof(Symbol)); - symbol.check = (PLT_CHECK_PLT_APP | PLT_CHECK_NAME); - symbol.symbol_name = (char *) v; - if (dl_iterate_phdr_symbol(&symbol)) { -#ifdef DEBUG_NATIVE - LOGW("cannot dl_iterate_phdr_symbol"); -#endif - return false; - } - - bool extractNativeLibs = true; - for (int i = 0; i < symbol.size; ++i) { - if (symbol.names[i] != NULL) { -#ifdef DEBUG_NATIVE - LOGW("%s: %s", v, symbol.names[i]); -#endif - if (extractNativeLibs && strstr(symbol.names[i], "apk!") != NULL) { - extractNativeLibs = false; - } - free(symbol.names[i]); - symbol.names[i] = NULL; - } - } - if (symbol.names != NULL) { - free(symbol.names); - symbol.names = NULL; - } - -#ifdef DEBUG_NATIVE - LOGW("has_native_libs: %s", extractNativeLibs ? "true" : "false"); -#endif - return extractNativeLibs; -#endif -} - -bool checkGenuine(JNIEnv *env) { - char v1[0x20]; - - signal(SIGCONT, handler); - fill_add_sigcont(v1); - LOGI(v1); // 0x14 - - sdk = getSdk(); - - if (sdk < 23) { - genuine = CHECK_FATAL; - goto done; - } - - uid = getuid(); - -#ifdef DEBUG_HOOK_SELF - LOGI("+++ whale +++"); - check_inline_hook_whale(); - LOGI("--- whale ----"); -#if defined(__arm__) || defined(__aarch64__) - LOGI("+++ hookzz-b +++"); - check_inline_hook_hookzz_b(); - LOGI("--- hookzz-b ---"); - LOGI("+++ hookzz +++"); - check_inline_hook_hookzz(); - LOGI("--- hookzz ---"); -#endif -#if defined(__arm__) - LOGI("+++ hookzz-b +++"); - check_inline_hook_hookzz_b(); - LOGI("--- hookzz-b ---"); - LOGI("+++ substrate +++"); - check_inline_hook_substrate(); - LOGI("--- substrate ---"); -#endif -#endif - -#ifdef DEBUG - LOGI("JNI_OnLoad start, sdk: %d, uid: %d", sdk, uid); -#endif - -#ifdef DEBUG_HOOK_IO - check_inline_hook_io(); -#endif - -#ifdef DEBUG_MAPS - LOGI("openAt: %p", &openAt); -#endif - if (isInlineHooked(&openAt)) { - fill_openat_is_hooked(v1); - LOGE(v1); - genuine = CHECK_FATAL; - goto done; - } - - char *packageName = getGenuinePackageName(); - - if (uid < 10000) { - goto clean; - } - -#ifdef CHECK_MOUNT - checkMount(maps); -#endif - -#ifndef NO_CHECK_MAPS -#ifdef DEBUG - LOGI("checkMaps start"); -#endif - genuine = checkMaps(packageName); -#endif - -#ifdef CHECK_HOOK -#define CHECK_HOOK_SYMBOL(x) do {\ - if (genuine == CHECK_TRUE) {\ - fill_##x(v1);\ - if (isPltHooked(v1, true)) {\ - genuine = CHECK_FALSE;\ - }\ - }\ - } while(0); - CHECK_HOOK_SYMBOL(open); - CHECK_HOOK_SYMBOL(openat); - CHECK_HOOK_SYMBOL(__openat); - CHECK_HOOK_SYMBOL(jniRegisterNativeMethods); -#endif - -#if defined(CHECK_ARM64) && defined(__arm__) - if (genuine == CHECK_TRUE) { - fill_ro_product_cpu_abi(v1); - __system_property_get(v1, prop); - if (isArm64V8a(prop)) { - fill_32_64(v1); - LOGW(v1); - genuine = CHECK_FALSE; - } - } -#endif - -clean: -#ifdef GENUINE_NAME - free(packageName); -#endif -#ifdef DEBUG - LOGI("JNI_OnLoad end, genuine: %d", genuine); -#endif - - if (genuine != CHECK_PROXY && isAmProxy(env, sdk)) { - genuine = CHECK_PROXY; - } - -done: - fill_sdk_d_genuine_d(v1); // 0x15 - LOGI(v1, sdk, genuine); - - return setGenuine(env, genuine); -} diff --git a/native/src/main/jni/integrity/genuine.h b/native/src/main/jni/integrity/genuine.h deleted file mode 100644 index 28c38fe99..000000000 --- a/native/src/main/jni/integrity/genuine.h +++ /dev/null @@ -1,43 +0,0 @@ -#include - -#define GENUINE_NAME {0x62, 0x63, 0x23, 0x69, 0x66, 0x64, 0x79, 0x67, 0x71, 0x2e, 0x6f, 0x67, 0x68, 0x6b, 0x6c, 0x68, 0x71, 0x6d, 0x7b, 0x7e, 0x6e, 0x7e, 0x23, 0x6b, 0x67, 0x66, 0x78, 0x77, 0x64, 0x65, 0x73, 0x0} -#define GENUINE_SIZE 0x02d1 -#define GENUINE_HASH 0x9a99ba0c - -/* genuine false handler */ -#define GENUINE_FALSE_CRASH -// #define GENUINE_FALSE_NATIVE - -/* genuine fake handler */ -#define GENUINE_FAKE_CRASH -// #define GENUINE_FAKE_NATIVE - -/* genuine overlay handler */ -// #define GENUINE_OVERLAY_CRASH -// #define GENUINE_OVERLAY_NATIVE - -/* genuine odex handler */ -// #define GENUINE_ODEX_CRASH -// #define GENUINE_ODEX_NATIVE - -/* genuine dex handler */ -#define GENUINE_DEX_CRASH -// #define GENUINE_DEX_NATIVE - -/* genuine proxy handler */ -#define GENUINE_PROXY_CRASH -// #define GENUINE_PROXY_NATIVE - -/* genuine error handler */ -#define GENUINE_ERROR_CRASH -// #define GENUINE_ERROR_NATIVE - -/* genuine fatal handler */ -#define GENUINE_FATAL_CRASH -// #define GENUINE_FATAL_NATIVE - -/* genuine noapk handler */ -#define GENUINE_NOAPK_CRASH -// #define GENUINE_NOAPK_NATIVE - -bool checkGenuine(JNIEnv *env); diff --git a/native/src/main/jni/integrity/inline.c b/native/src/main/jni/integrity/inline.c deleted file mode 100644 index 508a86d82..000000000 --- a/native/src/main/jni/integrity/inline.c +++ /dev/null @@ -1,333 +0,0 @@ -// -// Created by Thom on 2019/3/18. -// - -#include -#include -#include -#include -#include -#include "inline.h" -#include "common.h" - -#ifdef DEBUG_HOOK_SELF - -#include -#include -#include -#include "whale/whale.h" - -static long faccessat_replace(int dirfd, const char *pathname, int mode, int flags) { - return syscall(__NR_faccessat, dirfd, pathname, mode, flags); -} - -static long fchownat_replace(int dirfd, const char *pathname, uid_t owner, gid_t group, int flags) { - return syscall(__NR_fchownat, dirfd, pathname, owner, group, flags); -} - -static int futimens_replace(int fd, const struct timespec times[2]) { - return utimensat(fd, NULL, times, 0); -} - -#if defined(__arm__) || defined(__aarch64__) - -void check_inline_hook_hookzz() { - void *backup; - zz_disable_arm_arm64_b_branch(); - - ZzReplace(&fchownat, &fchownat_replace, &backup); - LOGI("hookzz fchownat: %p, replace: %p, hooked: %d", &fchownat, &fchownat_replace, - isInlineHooked(&fchownat)); - - ZzReplace(&faccessat, &faccessat_replace, &backup); - LOGI("hookzz faccessat: %p, repalce: %p, hooked: %d", &faccessat, &faccessat_replace, - isInlineHooked(&faccessat)); - - ZzReplace(&futimens, &futimens_replace, &backup); - LOGI("hookzz futimens: %p, replace: %p, hooked: %d", &futimens, &futimens_replace, - isInlineHooked(&futimens)); -} - -void check_inline_hook_hookzz_b() { - void *backup; - zz_enable_arm_arm64_b_branch(); - - ZzReplace(&fchownat, &fchownat_replace, &backup); - LOGI("hookzz-b fchownat: %p, replace: %p, hooked: %d", &fchownat, &fchownat_replace, - isInlineHooked(&fchownat)); - - ZzReplace(&faccessat, &faccessat_replace, &backup); - LOGI("hookzz-b faccessat: %p, repalce: %p, hooked: %d", &faccessat, &faccessat_replace, - isInlineHooked(&faccessat)); - - ZzReplace(&futimens, &futimens_replace, &backup); - LOGI("hookzz-b futimens: %p, replace: %p, hooked: %d", &futimens, &futimens_replace, - isInlineHooked(&futimens)); -} - -#endif - -void check_inline_hook_whale() { - WInlineHookFunction(&fchownat, &fchownat_replace, NULL); - LOGI("whale fchownat: %p, replace: %p, hooked: %d", &fchownat, &fchownat_replace, - isInlineHooked(&fchownat)); - - WInlineHookFunction(&faccessat, &faccessat_replace, NULL); - LOGI("whale faccessat: %p, repalce: %p, hooked: %d", &faccessat, &faccessat_replace, - isInlineHooked(&faccessat)); - - WInlineHookFunction(&futimens, &futimens_replace, NULL); - LOGI("whale futimens: %p, replace: %p, hooked: %d", &futimens, &futimens_replace, - isInlineHooked(&futimens)); -} - -#if defined(__arm__) || defined(DEBUG_HOOK_IDE) - -#include "substrate/CydiaSubstrate.h" - -void check_inline_hook_substrate() { - MSHookFunction(&fchownat, &fchownat_replace, NULL); - LOGI("substrate fchownat: %p, replace: %p, hooked: %d", &fchownat, &fchownat_replace, - isInlineHooked(&fchownat)); - - MSHookFunction(&faccessat, &faccessat_replace, NULL); - LOGI("substrate faccessat: %p, repalce: %p, hooked: %d", &faccessat, &faccessat_replace, - isInlineHooked(&faccessat)); - - MSHookFunction(&futimens, &futimens_replace, NULL); - LOGI("substrate futimens: %p, replace: %p, hooked: %d", &futimens, &futimens_replace, - isInlineHooked(&futimens)); -} - -#endif - -#endif - -bool isInlineHooked(void *symbol) { - if (symbol == NULL) { - return false; - } -#if defined(__arm__) || defined(DEBUG_HOOK_IDE) - -// https://developer.arm.com/docs/ddi0597/b/base-instructions-alphabetic-order/ldr-literal-load-register-literal -// A1, !(P == 0 && W == 1), we don't check P and W -// cond 010P U0W1 1111 _Rt_ xxxx xxxx xxxx -#define IS_LDR_PC_A1(x) (((x) & 0xfe5ff000u) == 0xe41ff000u) -// T2 -// 1111 1000 U101 1111 | _Rt_ xxxx xxxx xxxx -#define IS_LDR_PC_T2(x) (((x) & 0xf000ff7fu) == 0xf000f85fu) - -// https://developer.arm.com/docs/ddi0597/b/base-instructions-alphabetic-order/b-branch -// A1 -// cond 100 xxxx xxxx xxxx xxxx xxxx xxxx -#define IS_B_A1(x) (((x) & 0xff000000u) == 0xea000000u) -// T2 -// 1110 0xxx xxxx xxxx -#define IS_B_T2(x) (((x) & 0xf800u) == 0xe000u) -// T4 -// 1111 0Sxx xxxx xxxx | 10J1 Jxxx xxxx xxxx -// -- imm10 --- | --- imm11 --- -#define IS_B_T4(x) (((x) & 0xd000f800u) == 0x9000f000u) - -// https://developer.arm.com/docs/ddi0597/b/base-instructions-alphabetic-order/nop-no-operation -// T1, hint should be 0000, we don't check -// 1011 1111 hint 0000 -#define IS_NOP_T1(x) (((x) & 0xff0fu) == 0xbf00u) - -// https://developer.arm.com/docs/ddi0597/b/base-instructions-alphabetic-order/mov-movs-register-move-register -// cydia use `mov r8, r8` for Nop -// T1, Mmmm is Rm, Dddd is Rd -// 0100 0110 DMmm mddd -#define _IS_MOV_T1(x) (((x) & 0xff00u) == 0x4600u) -#define _RM_MOV_T1(x) ((((x) & 0x78u) >> 3u)) -#define _RD_MOV_T1(x) ((((x) & 0x80u) >> 4u) | ((x) & 7u)) -#define IS_MOV_T1_RR(x) (_IS_MOV_T1(x) && _RM_MOV_T1(x) == _RD_MOV_T1(x)) - -// https://developer.arm.com/docs/ddi0597/b/base-instructions-alphabetic-order/bx-branch-and-exchange -// cydia use `bx` -// T1 -// 0100 0111 0Rmm m000 -#define IS_BX_T1(x) (((x) & 0xff87u) == 0x4700u) -#define RM_BX_T1(x) (((x) & 0x0078u) >> 3u) -#define IS_BX_PC_T1(x) ((x) == 0x4778u) - - uintptr_t address = (uintptr_t) symbol; - if ((address & 1U) == 0) { - uint32_t *value32 = (uint32_t *) address; - if (IS_LDR_PC_A1(*value32)) { -#ifdef DEBUG_HOOK - LOGW("(arm ldr pc) symbol: %p, value: %08x", symbol, *value32); -#endif - return true; - } - if (IS_B_A1(*value32)) { -#ifdef DEBUG_HOOK - LOGW("(arm b) symbol: %p, value: %08x", symbol, *value32); -#endif - return true; - } -#ifdef DEBUG - LOGI("(arm) symbol: %p, value: %08x", symbol, *value32); -#endif - } else { - address = address & ~1U; - uint16_t *value16 = (uint16_t *) address; - uint32_t *value32 = (uint32_t *) address; - if (IS_LDR_PC_T2(*value32)) { -#ifdef DEBUG_HOOK - LOGW("(thumb ldr pc) symbol: %p, address: %p, value: %08x", - symbol, address, *value32); -#endif - return true; - } - if (IS_B_T4(*value32)) { -#ifdef DEBUG_HOOK - LOGW("(thumb b) symbol: %p, address: %p, value: %08x", - symbol, address, *value32); -#endif - return true; - } - if (IS_B_T2(*value16)) { -#ifdef DEBUG_HOOK - LOGW("(thumb b) symbol: %p, address: %p, value: %04x", - symbol, address, *value16); -#endif - return true; - } - if (IS_NOP_T1(*value16) || IS_MOV_T1_RR(*value16)) { -#ifdef DEBUG_HOOK - LOGW("(thumb nop) symbol: %p, address: %p, value: %04x", - symbol, address, *value16); -#endif - address += 2; - value16 = (uint16_t *) address; - value32 = (uint32_t *) address; - } - if (IS_LDR_PC_T2(*value32)) { -#ifdef DEBUG_HOOK - LOGW("(thumb ldr pc) symbol: %p, address: %p, value: %08x", - symbol, address, *value32); -#endif - return true; - } - if (IS_BX_PC_T1(*value16) && IS_LDR_PC_A1(*(value32 + 1))) { -#ifdef DEBUG_HOOK - LOGW("(thumb bx + arm ldr pc) symbol: %p, address: %p, value: %08x %08x", - symbol, address, *value32, *(value32 + 1)); -#endif - return true; - } -#ifdef DEBUG - LOGI("(thumb) symbol: %p, address: %p, value: %08x %08x", - symbol, address, *value32, *(value32 + 1)); -#endif - } -#endif -#if defined(__aarch64__) || defined(DEBUG_HOOK_IDE) - -// https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/b-branch -// 0001 01xx xxxx xxxx xxxx xxxx xxxx xxxx -// ------------ imm26 ------------- -#define IS_B(x) (((x) & 0xfc000000u) == 0x14000000u) - -// https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/ldr-literal-load-register-literal -// 0101 1000 xxxx xxxx xxxx xxxx xxxR tttt -// -------- imm19 -------- -#define IS_LDR_X(x) (((x) & 0xff000000u) == 0x58000000u) -#define X_LDR(x) ((x) & 0x1fu) - -// https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/adrp-form-pc-relative-address-to-4kb-page -// 1xx1 0000 xxxx xxxx xxxx xxxx xxxR dddd -// lo -------- immhi -------- -#define IS_ADRP_X(x) (((x) & 0x9f000000u) == 0x90000000u) -#define X_ADRP(x) ((x) & 0x1fu) - -// https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/br-branch-to-register -// 1101 0110 0001 1111 0000 00Rn nnn0 0000 -#define IS_BR_X(x) (((x) & 0xfffffc0f) == 0xd61f0000u) -#define X_BR(x) (((x) & 0x3e0u) >> 0x5u) - -// https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/movz-move-wide-with-zero -// 1op1 0010 1hwx xxxx xxxx xxxx xxxR dddd -// ------ imm16 ------- -// for op, 00 -> MOVN, 10 -> MOVZ, 11 -> MOVK -#define IS_MOV_X(x) (((x) & 0x9f800000u) == 0x92800000u) -#define X_MOV(x) ((x) & 0x1fu) - - uint32_t *value32 = symbol; - if (IS_B(*value32)) { -#ifdef DEBUG_HOOK - LOGW("(arm64 b) symbol: %p, value: %08x", symbol, *value32); -#endif - return true; - } - if (IS_LDR_X(*value32) && IS_BR_X(*(value32 + 1))) { - uint32_t x = X_LDR(*value32); - if (x == X_BR(*(value32 + 1))) { -#ifdef DEBUG_HOOK - LOGW("(arm64 ldr+br x%d) symbol: %p, value: %08x %08x", - x, symbol, *value32, *(value32 + 1)); -#endif - return true; - } - } - if (IS_ADRP_X(*value32) && IS_BR_X(*(value32 + 1))) { - uint32_t x = X_ADRP(*value32); - if (x == X_BR(*(value32 + 1))) { -#ifdef DEBUG_HOOK - LOGW("(arm64 adrp+br x%d) symbol: %p, value: %08x %08x", - x, symbol, *value32, *(value32 + 1)); -#endif - return true; - } - } - if (IS_MOV_X(*value32)) { - uint32_t x = X_MOV(*value32); - for (int i = 1; i <= 4; ++i) { - if (IS_BR_X(*(value32 + i))) { - if (x != X_BR(*(value32 + i))) { - break; - } -#ifdef DEBUG_HOOK - for (int k = 0; k < i; ++k) { - LOGW("(arm64 mov x%d) symbol: %p, value: %08x", - x, symbol + sizeof(uint32_t) * k, *(value32 + k)); - } - LOGW("(arm64 br x%d) symbol: %p, value: %08x", - x, symbol + sizeof(uint32_t) * i, *(value32 + i)); -#endif - return true; - } else if (IS_MOV_X(*(value32 + i))) { - if (x != X_MOV(*(value32 + i))) { - break; - } - } - } - } -#ifdef DEBUG - LOGI("(arm64) symbol: %p, value: %08x %08x", symbol, *value32, *(value32 + 1)); -#endif -#endif - return false; -} - -#ifdef DEBUG_HOOK_IO -bool setRead(void *symbol) { - uintptr_t address = (uintptr_t) symbol; - uintptr_t page_size = (uintptr_t) getpagesize(); - uintptr_t base = address & ~(page_size - 1); - // inline check read at most 20 bytes - uintptr_t end = (address + 20 + page_size - 1) & -page_size; -#ifdef DEBUG - LOGI("set r+x from %p to %p", base, end); -#endif - if (mprotect((void *) base, end - base, PROT_READ | PROT_EXEC)) { -#ifdef DEBUG - LOGW("cannot mprotect: %s", strerror(errno)); -#endif - return false; - } else { - return true; - } -} -#endif diff --git a/native/src/main/jni/integrity/inline.h b/native/src/main/jni/integrity/inline.h deleted file mode 100644 index 52f3936bd..000000000 --- a/native/src/main/jni/integrity/inline.h +++ /dev/null @@ -1,45 +0,0 @@ -// -// Created by Thom on 2019/3/18. -// - -#ifndef BREVENT_INLINE_H -#define BREVENT_INLINE_H - -#include -#include "common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef DEBUG_HOOK_IO -bool setRead(void *symbol); -#endif - -bool isInlineHooked(void *symbol); - -#ifdef DEBUG_HOOK_SELF -#if defined(__arm__) || defined(__aarch64__) - -#include "hookzz/hookzz.h" - -void check_inline_hook_hookzz(); - -void check_inline_hook_hookzz_b(); - -#endif - -void check_inline_hook_whale(); - -#if defined(__arm__) - -void check_inline_hook_substrate(); - -#endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif //BREVENT_INLINE_H diff --git a/native/src/main/jni/integrity/openat.c b/native/src/main/jni/integrity/openat.c deleted file mode 100644 index e1e467594..000000000 --- a/native/src/main/jni/integrity/openat.c +++ /dev/null @@ -1,56 +0,0 @@ -// -// Created by Thom on 2019/3/30. -// - -#include -#include -#include "openat.h" - -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) - -intptr_t openAt(intptr_t fd, const char *path, intptr_t flag) { -#if defined(__arm__) - intptr_t r; - __asm__ volatile( -#ifndef OPTIMIZE_ASM - "mov r0, %1\n\t" - "mov r1, %2\n\t" - "mov r2, %3\n\t" -#endif - - "mov ip, r7\n\t" - ".cfi_register r7, ip\n\t" - "ldr r7, =" STR(__NR_openat) "\n\t" - "svc #0\n\t" - "mov r7, ip\n\t" - ".cfi_restore r7\n\t" - -#ifndef OPTIMIZE_ASM - "mov %0, r0\n\t" -#endif - : "=r" (r) - : "r" (fd), "r" (path), "r" (flag)); - return r; -#elif defined(__aarch64__) - intptr_t r; - __asm__ volatile( -#ifndef OPTIMIZE_ASM - "mov x0, %1\n\t" - "mov x1, %2\n\t" - "mov x2, %3\n\t" -#endif - - "mov x8, " STR(__NR_openat) "\n\t" - "svc #0\n\t" - -#ifndef OPTIMIZE_ASM - "mov %0, x0\n\t" -#endif - : "=r" (r) - : "r" (fd), "r" (path), "r" (flag)); - return r; -#else - return (intptr_t) syscall(__NR_openat, fd, path, flag); -#endif -} diff --git a/native/src/main/jni/integrity/openat.h b/native/src/main/jni/integrity/openat.h deleted file mode 100644 index 212f98535..000000000 --- a/native/src/main/jni/integrity/openat.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// Created by Thom on 2019/3/30. -// - -#ifndef BREVENT_OPENAT_H -#define BREVENT_OPENAT_H - -#include -#include -#include "common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __ANDROID__ - -intptr_t openAt(intptr_t fd, const char *path, intptr_t flag); - -#else -#define openAt openat -#endif - -#ifdef __cplusplus -} -#endif - -#endif //BREVENT_OPENAT_H diff --git a/native/src/main/jni/integrity/path.c b/native/src/main/jni/integrity/path.c deleted file mode 100644 index 7332e2f3a..000000000 --- a/native/src/main/jni/integrity/path.c +++ /dev/null @@ -1,95 +0,0 @@ -// -// Created by Thom on 2019-05-03. -// - -#include "path.h" -#include - -static inline bool isSystem(const char *str) { - return str != NULL - && *str == '/' - && *++str == 's' - && *++str == 'y' - && *++str == 's' - && *++str == 't' - && *++str == 'e' - && *++str == 'm' - && *++str == '/'; -} - -static inline bool isVendor(const char *str) { - return str != NULL - && *str == '/' - && *++str == 'v' - && *++str == 'e' - && *++str == 'n' - && *++str == 'd' - && *++str == 'o' - && *++str == 'r' - && *++str == '/'; -} - -static inline bool isOem(const char *str) { - return str != NULL - && *str == '/' - && *++str == 'o' - && *++str == 'e' - && *++str == 'm' - && *++str == '/'; -} - -bool isThirdParty(const char *str) { - if (isSystem(str) || isVendor(str) || isOem(str)) { - return false; - } else { - return true; - } -} - -bool isDataApp(const char *str) { - return str != NULL - && *str == '/' - && *++str == 'd' - && *++str == 'a' - && *++str == 't' - && *++str == 'a' - && *++str == '/' - && *++str == 'a' - && *++str == 'p' - && *++str == 'p' - && *++str == '/'; -} - -bool isAsecApp(const char *str) { - return str != NULL - && *str == '/' - && *++str == 'm' - && *++str == 'n' - && *++str == 't' - && *++str == '/' - && *++str == 'a' - && *++str == 's' - && *++str == 'e' - && *++str == 'c' - && *++str == '/'; -} - -bool isExpandApp(const char *str) { - return str != NULL - && *str == '/' - && *++str == 'm' - && *++str == 'n' - && *++str == 't' - && *++str == '/' - && *++str == 'e' - && *++str == 'x' - && *++str == 'p' - && *++str == 'a' - && *++str == 'n' - && *++str == 'd' - && *++str == '/'; -} - -bool isExternalSdApp(const char *str) { - return isAsecApp(str) || isExpandApp(str); -} \ No newline at end of file diff --git a/native/src/main/jni/integrity/path.h b/native/src/main/jni/integrity/path.h deleted file mode 100644 index 813e8b681..000000000 --- a/native/src/main/jni/integrity/path.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// Created by Thom on 2019-05-03. -// - -#ifndef BREVENT_PATH_H -#define BREVENT_PATH_H - -#include - -bool isThirdParty(const char *str); - -bool isDataApp(const char *str); - -bool isExternalSdApp(const char *str); - -#endif //BREVENT_PATH_H diff --git a/native/src/main/jni/integrity/plt.c b/native/src/main/jni/integrity/plt.c deleted file mode 100644 index b1bc6486d..000000000 --- a/native/src/main/jni/integrity/plt.c +++ /dev/null @@ -1,355 +0,0 @@ -// -// Created by Thom on 2019/2/16. -// - -#include -#include -#include -#include -#include -#include "plt.h" -#include "common.h" -#include "path.h" - -/* - * reference: https://android.googlesource.com/platform/bionic/+/master/linker/linker_soinfo.cpp - */ -static uint32_t gnu_hash(const uint8_t *name) { - uint32_t h = 5381; - - while (*name) { - h += (h << 5) + *name++; - } - return h; -} - -static uint32_t elf_hash(const uint8_t *name) { - uint32_t h = 0, g; - - while (*name) { - h = (h << 4) + *name++; - g = h & 0xf0000000; - h ^= g; - h ^= g >> 24; - } - - return h; -} - -static ElfW(Dyn) *find_dyn_by_tag(ElfW(Dyn) *dyn, ElfW(Sxword) tag) { - while (dyn->d_tag != DT_NULL) { - if (dyn->d_tag == tag) { - return dyn; - } - ++dyn; - } - return NULL; -} - -static inline bool is_global(ElfW(Sym) *sym) { - unsigned char stb = ELF_ST_BIND(sym->st_info); - if (stb == STB_GLOBAL || stb == STB_WEAK) { - return sym->st_shndx != SHN_UNDEF; - } else { - return false; - } -} - -static ElfW(Addr) * -find_symbol(struct dl_phdr_info *info, ElfW(Dyn) *base_addr, const char *symbol) { - ElfW(Dyn) *dyn; - - dyn = find_dyn_by_tag(base_addr, DT_SYMTAB); - ElfW(Sym) *dynsym = (ElfW(Sym) *) (info->dlpi_addr + dyn->d_un.d_ptr); - - dyn = find_dyn_by_tag(base_addr, DT_STRTAB); - char *dynstr = (char *) (info->dlpi_addr + dyn->d_un.d_ptr); - - dyn = find_dyn_by_tag(base_addr, DT_GNU_HASH); - if (dyn != NULL) { - ElfW(Word) *dt_gnu_hash = (ElfW(Word) *) (info->dlpi_addr + dyn->d_un.d_ptr); - size_t gnu_nbucket_ = dt_gnu_hash[0]; - uint32_t gnu_maskwords_ = dt_gnu_hash[2]; - uint32_t gnu_shift2_ = dt_gnu_hash[3]; - ElfW(Addr) *gnu_bloom_filter_ = (ElfW(Addr) *) (dt_gnu_hash + 4); - uint32_t *gnu_bucket_ = (uint32_t *) (gnu_bloom_filter_ + gnu_maskwords_); - uint32_t *gnu_chain_ = gnu_bucket_ + gnu_nbucket_ - dt_gnu_hash[1]; - - --gnu_maskwords_; - - uint32_t hash = gnu_hash((uint8_t *) symbol); - uint32_t h2 = hash >> gnu_shift2_; - - uint32_t bloom_mask_bits = sizeof(ElfW(Addr)) * 8; - uint32_t word_num = (hash / bloom_mask_bits) & gnu_maskwords_; - ElfW(Addr) bloom_word = gnu_bloom_filter_[word_num]; - - if ((1 & (bloom_word >> (hash % bloom_mask_bits)) & - (bloom_word >> (h2 % bloom_mask_bits))) == 0) { - return NULL; - } - - uint32_t n = gnu_bucket_[hash % gnu_nbucket_]; - - if (n == 0) { - return NULL; - } - - do { - ElfW(Sym) *sym = dynsym + n; - if (((gnu_chain_[n] ^ hash) >> 1) == 0 - && is_global(sym) - && strcmp(dynstr + sym->st_name, symbol) == 0) { - ElfW(Addr) *symbol_sym = (ElfW(Addr) *) (info->dlpi_addr + sym->st_value); -#ifdef DEBUG_PLT - LOGI("found %s(gnu+%u) in %s, %p", symbol, n, info->dlpi_name, symbol_sym); -#endif - return symbol_sym; - } - } while ((gnu_chain_[n++] & 1) == 0); - - return NULL; - } - - dyn = find_dyn_by_tag(base_addr, DT_HASH); - if (dyn != NULL) { - ElfW(Word) *dt_hash = (ElfW(Word) *) (info->dlpi_addr + dyn->d_un.d_ptr); - size_t nbucket_ = dt_hash[0]; - uint32_t *bucket_ = dt_hash + 2; - uint32_t *chain_ = bucket_ + nbucket_; - - uint32_t hash = elf_hash((uint8_t *) (symbol)); - for (uint32_t n = bucket_[hash % nbucket_]; n != 0; n = chain_[n]) { - ElfW(Sym) *sym = dynsym + n; - if (is_global(sym) && - strcmp(dynstr + sym->st_name, symbol) == 0) { - ElfW(Addr) *symbol_sym = (ElfW(Addr) *) (info->dlpi_addr + sym->st_value); -#ifdef DEBUG_PLT - LOGI("found %s(elf+%u) in %s, %p", symbol, n, info->dlpi_name, symbol_sym); -#endif - return symbol_sym; - } - } - - return NULL; - } - - return NULL; -} - -#if defined(__LP64__) -#define Elf_Rela ElfW(Rela) -#define ELF_R_SYM ELF64_R_SYM -#else -#define Elf_Rela ElfW(Rel) -#define ELF_R_SYM ELF32_R_SYM -#endif - -#ifdef DEBUG_PLT -#if defined(__x86_64__) -#define R_JUMP_SLOT R_X86_64_JUMP_SLOT -#define ELF_R_TYPE ELF64_R_TYPE -#elif defined(__i386__) -#define R_JUMP_SLOT R_386_JMP_SLOT -#define ELF_R_TYPE ELF32_R_TYPE -#elif defined(__arm__) -#define R_JUMP_SLOT R_ARM_JUMP_SLOT -#define ELF_R_TYPE ELF32_R_TYPE -#elif defined(__aarch64__) -#define R_JUMP_SLOT R_AARCH64_JUMP_SLOT -#define ELF_R_TYPE ELF64_R_TYPE -#else -#error unsupported OS -#endif -#endif - -static ElfW(Addr) *find_plt(struct dl_phdr_info *info, ElfW(Dyn) *base_addr, const char *symbol) { - ElfW(Dyn) *dyn = find_dyn_by_tag(base_addr, DT_JMPREL); - if (dyn == NULL) { - return NULL; - } - Elf_Rela *dynplt = (Elf_Rela *) (info->dlpi_addr + dyn->d_un.d_ptr); - - dyn = find_dyn_by_tag(base_addr, DT_SYMTAB); - ElfW(Sym) *dynsym = (ElfW(Sym) *) (info->dlpi_addr + dyn->d_un.d_ptr); - - dyn = find_dyn_by_tag(base_addr, DT_STRTAB); - char *dynstr = (char *) (info->dlpi_addr + dyn->d_un.d_ptr); - - dyn = find_dyn_by_tag(base_addr, DT_PLTRELSZ); - if (dyn == NULL) { - return NULL; - } - size_t count = dyn->d_un.d_val / sizeof(Elf_Rela); - - for (size_t i = 0; i < count; ++i) { - Elf_Rela *plt = dynplt + i; -#ifdef DEBUG_PLT - if (ELF_R_TYPE(plt->r_info) != R_JUMP_SLOT) { - LOGW("invalid type for plt+%zu in %s", i, info->dlpi_name); - continue; - } -#endif - size_t idx = ELF_R_SYM(plt->r_info); - idx = dynsym[idx].st_name; - if (strcmp(dynstr + idx, symbol) == 0) { - ElfW(Addr) *symbol_plt = (ElfW(Addr) *) (info->dlpi_addr + plt->r_offset); -#ifdef DEBUG_PLT - ElfW(Addr) *symbol_plt_value = (ElfW(Addr) *) *symbol_plt; - LOGI("found %s(plt+%zu) in %s, %p -> %p", symbol, i, info->dlpi_name, symbol_plt, - symbol_plt_value); -#endif - return symbol_plt; - } - } - - return NULL; -} - -static inline bool isso(const char *str) { - if (str == NULL) { - return false; - } - const char *dot = strrchr(str, '.'); - return dot != NULL - && *++dot == 's' - && *++dot == 'o' - && (*++dot == '\0' || *dot == '\r' || *dot == '\n'); -} - -static inline bool should_check_plt(Symbol *symbol, struct dl_phdr_info *info) { - const char *path = info->dlpi_name; - if (symbol->check & PLT_CHECK_PLT_ALL) { - return true; - } else if (symbol->check & PLT_CHECK_PLT_APP) { - return *path != '/' || isThirdParty(path); - } else { - return false; - } -} - -static int callback(struct dl_phdr_info *info, __unused size_t size, void *data) { - if (!isso(info->dlpi_name)) { -#ifdef DEBUG_PLT - LOGW("ignore non-so: %s", info->dlpi_name); -#endif - return 0; - } - Symbol *symbol = (Symbol *) data; -#if 0 - LOGI("Name: \"%s\" (%d segments)", info->dlpi_name, info->dlpi_phnum); -#endif - ++symbol->total; - for (ElfW(Half) phdr_idx = 0; phdr_idx < info->dlpi_phnum; ++phdr_idx) { - ElfW(Phdr) phdr = info->dlpi_phdr[phdr_idx]; - if (phdr.p_type != PT_DYNAMIC) { - continue; - } - ElfW(Dyn) *base_addr = (ElfW(Dyn) *) (info->dlpi_addr + phdr.p_vaddr); - ElfW(Addr) *addr; - addr = should_check_plt(symbol, info) ? find_plt(info, base_addr, symbol->symbol_name) : NULL; - if (addr != NULL) { - if (symbol->symbol_plt != NULL) { - ElfW(Addr) *addr_value = (ElfW(Addr) *) *addr; - ElfW(Addr) *symbol_plt_value = (ElfW(Addr) *) *symbol->symbol_plt; - if (addr_value != symbol_plt_value) { -#ifdef DEBUG_PLT - LOGW("%s, plt %p -> %p != %p", symbol->symbol_name, addr, addr_value, - symbol_plt_value); -#endif - return 1; - } - } - symbol->symbol_plt = addr; - if (symbol->check & PLT_CHECK_NAME) { - if (symbol->size == 0) { - symbol->size = 1; - symbol->names = calloc(1, sizeof(char *)); - } else { - ++symbol->size; - symbol->names = realloc(symbol->names, symbol->size * sizeof(char *)); - } -#ifdef DEBUG_PLT - LOGI("[%d]: %s", symbol->size - 1, info->dlpi_name); -#endif - symbol->names[symbol->size - 1] = strdup(info->dlpi_name); - } - } - addr = find_symbol(info, base_addr, symbol->symbol_name); - if (addr != NULL) { - symbol->symbol_sym = addr; - if (symbol->check == PLT_CHECK_SYM_ONE) { - return PLT_CHECK_SYM_ONE; - } - } - if (symbol->symbol_plt != NULL && symbol->symbol_sym != NULL) { - ElfW(Addr) *symbol_plt_value = (ElfW(Addr) *) *symbol->symbol_plt; - // stop if unmatch - if (symbol_plt_value != symbol->symbol_sym) { -#ifdef DEBUG_PLT - LOGW("%s, plt: %p -> %p != %p", symbol->symbol_name, symbol->symbol_plt, - symbol_plt_value, symbol->symbol_sym); -#endif - return 1; - } - } - } - return 0; -} - -void *plt_dlsym(const char *name, size_t *total) { - Symbol symbol; - memset(&symbol, 0, sizeof(Symbol)); - if (total == NULL) { - symbol.check = PLT_CHECK_SYM_ONE; - } - symbol.symbol_name = name; - dl_iterate_phdr_symbol(&symbol); - if (total != NULL) { - *total = symbol.total; - } - return symbol.symbol_sym; -} - -bool isPltHooked(const char *name, bool all) { - Symbol symbol; - memset(&symbol, 0, sizeof(Symbol)); - symbol.check = all ? PLT_CHECK_PLT_ALL : PLT_CHECK_PLT_APP; - symbol.symbol_name = name; - return dl_iterate_phdr_symbol(&symbol) ? true : false; -} - -/** - * symbol->check PLT_CHECK_PLT | PLT_CHECK_NAME - * @param symbol - * @return - */ -int dl_iterate_phdr_symbol(Symbol *symbol) { - int result; -#ifdef DEBUG_PLT - LOGI("start dl_iterate_phdr: %s", symbol->symbol_name); -#endif -#if __ANDROID_API__ >= 21 || !defined(__arm__) - result = dl_iterate_phdr(callback, symbol); -#else - int (*dl_iterate_phdr)(int (*)(struct dl_phdr_info *, size_t, void *), void *); - dl_iterate_phdr = dlsym(RTLD_NEXT, "dl_iterate_phdr"); - if (dl_iterate_phdr != NULL) { - result = dl_iterate_phdr(callback, symbol); - } else { - result = 0; - void *handle = dlopen("libdl.so", RTLD_NOW); - dl_iterate_phdr = dlsym(handle, "dl_iterate_phdr"); - if (dl_iterate_phdr != NULL) { - result = dl_iterate_phdr(callback, symbol); - } else { - LOGW("cannot dlsym dl_iterate_phdr"); - } - dlclose(handle); - } -#endif -#ifdef DEBUG_PLT - LOGI("complete dl_iterate_phdr: %s", symbol->symbol_name); -#endif - return result; -} diff --git a/native/src/main/jni/integrity/plt.h b/native/src/main/jni/integrity/plt.h deleted file mode 100644 index e6c7010b1..000000000 --- a/native/src/main/jni/integrity/plt.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Created by Thom on 2019/2/16. -// - -#ifndef BREVENT_PLT_H -#define BREVENT_PLT_H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define PLT_CHECK_PLT_APP ((unsigned short) 0x1u) -#define PLT_CHECK_PLT_ALL ((unsigned short) 0x2u) -#define PLT_CHECK_NAME ((unsigned short) 0x4u) -#define PLT_CHECK_SYM_ONE ((unsigned short) 0x8u) - -typedef struct Symbol { - unsigned short check; - unsigned short size; - size_t total; - ElfW(Addr) *symbol_plt; - ElfW(Addr) *symbol_sym; - const char *symbol_name; - char **names; -} Symbol; - -int dl_iterate_phdr_symbol(Symbol *symbol); - -void *plt_dlsym(const char *name, size_t *total); - -bool isPltHooked(const char *name, bool all); - -#ifdef __cplusplus -} -#endif - -#endif //BREVENT_PLT_H diff --git a/native/src/main/jni/main.c b/native/src/main/jni/main.c index 60fc17348..35d4b7f48 100644 --- a/native/src/main/jni/main.c +++ b/native/src/main/jni/main.c @@ -1,11 +1,11 @@ #include -#include "genuine.h" #include "java_wrapper.h" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv* env; + if ((*vm)->GetEnv(vm, (void**) (&env), JNI_VERSION_1_6) != JNI_OK) { return JNI_ERR; }