├── app ├── Readme.md ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── values │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ └── themes.xml │ │ │ ├── values-night │ │ │ │ └── themes.xml │ │ │ ├── drawable-v24 │ │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── layout │ │ │ │ └── activity_main.xml │ │ │ └── drawable │ │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── tg │ │ │ │ └── anti │ │ │ │ ├── AntiApp.java │ │ │ │ └── MainActivity.java │ │ └── AndroidManifest.xml │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── tg │ │ │ └── anti │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── tg │ │ └── anti │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── anti ├── consumer-rules.pro ├── .gitignore ├── src │ ├── main │ │ ├── cpp │ │ │ ├── mini_io │ │ │ │ ├── syscall │ │ │ │ │ ├── arm64-v8a │ │ │ │ │ │ └── def.h │ │ │ │ │ ├── armeabi-v7a │ │ │ │ │ │ └── def.h │ │ │ │ │ ├── private │ │ │ │ │ │ ├── common.c │ │ │ │ │ │ ├── bionic_asm_x86_64.h │ │ │ │ │ │ ├── bionic_asm_arm64.h │ │ │ │ │ │ ├── bionic_asm_x86.h │ │ │ │ │ │ ├── bionic_asm_arm.h │ │ │ │ │ │ └── bionic_asm.h │ │ │ │ │ ├── arm64-v8a.S │ │ │ │ │ ├── x86_64.S │ │ │ │ │ ├── armeabi-v7a.S │ │ │ │ │ └── x86.S │ │ │ │ ├── _set_errno.c │ │ │ │ ├── _mini_ptrace.h │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── _arm_on_x86.c │ │ │ │ ├── _mini_io.h │ │ │ │ └── _open.c │ │ │ ├── anti.h │ │ │ ├── utils │ │ │ │ ├── Utils.cpp │ │ │ │ ├── Utils.h │ │ │ │ └── mylibc.h │ │ │ ├── xposeddetector │ │ │ │ ├── hash.h │ │ │ │ ├── classloader.h │ │ │ │ ├── find_name.h │ │ │ │ ├── plt.h │ │ │ │ ├── hash.cpp │ │ │ │ ├── xposed.h │ │ │ │ ├── classloader.cpp │ │ │ │ ├── art.h │ │ │ │ └── find_name.cpp │ │ │ ├── check │ │ │ │ ├── anti_dual_app.h │ │ │ │ ├── anti_frida.h │ │ │ │ ├── anti_emulator.h │ │ │ │ ├── anti_mem_dump.h │ │ │ │ ├── anti_xposed.h │ │ │ │ ├── anti_xposed.cpp │ │ │ │ ├── anti_emulator.cpp │ │ │ │ ├── anti_dual_app.cpp │ │ │ │ ├── anti_mem_dump.cpp │ │ │ │ └── anti_frida.cpp │ │ │ ├── JNIHelper │ │ │ │ ├── core │ │ │ │ │ ├── JavaMethod.h │ │ │ │ │ ├── ErrorHandler.hpp │ │ │ │ │ ├── JavaCustomClass.cpp │ │ │ │ │ ├── JavaMethodSignature.hpp │ │ │ │ │ ├── JNIEnvironment.hpp │ │ │ │ │ ├── JavaCustomClass.hpp │ │ │ │ │ ├── JNIEnvironment.cpp │ │ │ │ │ └── ToJavaType.hpp │ │ │ │ ├── utils │ │ │ │ │ ├── JStringUtils.cpp │ │ │ │ │ ├── JStringUtils.hpp │ │ │ │ │ ├── JniGlobalRef.hpp │ │ │ │ │ ├── JavaObjectPointer.cpp │ │ │ │ │ ├── JavaObjectPointer.hpp │ │ │ │ │ └── LocalReferenceFrame.hpp │ │ │ │ ├── native │ │ │ │ │ ├── JavaNativeMethod.cpp │ │ │ │ │ └── JavaNativeMethod.hpp │ │ │ │ ├── app │ │ │ │ │ └── ActivityThread.h │ │ │ │ ├── calls │ │ │ │ │ ├── FieldCaller.h │ │ │ │ │ ├── ObjectCreation.hpp │ │ │ │ │ ├── InstanceCaller.hpp │ │ │ │ │ └── StaticCaller.hpp │ │ │ │ └── arrays │ │ │ │ │ ├── ArraySetter.hpp │ │ │ │ │ ├── ArrayAllocator.hpp │ │ │ │ │ ├── ArrayGetter.hpp │ │ │ │ │ └── ArrayBuilder.hpp │ │ │ ├── CMakeLists.txt │ │ │ └── anti.cpp │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── tg │ │ │ └── android │ │ │ └── anti │ │ │ └── NativeLib.java │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── tg │ │ │ └── android │ │ │ └── anti │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── tg │ │ └── anti │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── .gitignore ├── imgs ├── 1.png ├── 2.png ├── 3.png ├── 4.png └── 5.png ├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── README.md ├── gradlew.bat └── gradlew /app/Readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /anti/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /anti/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | .cxx -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | release -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .gradle 3 | local.properties 4 | build -------------------------------------------------------------------------------- /imgs/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/imgs/1.png -------------------------------------------------------------------------------- /imgs/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/imgs/2.png -------------------------------------------------------------------------------- /imgs/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/imgs/3.png -------------------------------------------------------------------------------- /imgs/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/imgs/4.png -------------------------------------------------------------------------------- /imgs/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/imgs/5.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "anti_Android" 2 | include ':app' 3 | include ':anti' -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUGOhost/anti_Android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/arm64-v8a/def.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSCALL_DEF 2 | #define SYSCALL_DEF 3 | 4 | #define MAX_ERRNO 4095 5 | #define __NR_SYSCALL_BASE 0 6 | 7 | #endif -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/armeabi-v7a/def.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSCALL_DEF 2 | #define SYSCALL_DEF 3 | 4 | #define MAX_ERRNO 4095 5 | #define __NR_SYSCALL_BASE 0 6 | 7 | #endif -------------------------------------------------------------------------------- /anti/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /anti/src/main/cpp/anti.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/9/4. 3 | // 4 | 5 | #ifndef ANTI_ANDROID_ANTI_H 6 | #define ANTI_ANDROID_ANTI_H 7 | #include 8 | 9 | #endif //ANTI_ANDROID_ANTI_H 10 | -------------------------------------------------------------------------------- /anti/src/main/cpp/utils/Utils.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/9/20. 3 | // 4 | 5 | #include "Utils.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/_set_errno.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "_mini_io.h" 3 | 4 | int _errno; 5 | 6 | long ___set_errno_internal(int n) { 7 | _errno = n; 8 | return -1; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/_mini_ptrace.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if defined(__cplusplus) 4 | extern "C" { 5 | #endif 6 | 7 | long _ptrace(int req, pid_t pid, void *addr, void *data); 8 | 9 | #if defined(__cplusplus) 10 | } 11 | #endif 12 | -------------------------------------------------------------------------------- /anti/src/main/cpp/xposeddetector/hash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | bool add(intptr_t hash); 11 | 12 | bool clear(); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Mar 16 17:24:14 CST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.10) 3 | project(mini_io C ASM CXX) 4 | 5 | set(CMAKE_C_VISIBILITY_PRESET hidden) 6 | add_library(mini_io STATIC 7 | _open.c 8 | _set_errno.c 9 | _arm_on_x86.c 10 | syscall/private/common.c 11 | syscall/${CMAKE_ANDROID_ARCH_ABI}.S 12 | ) 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/tg/anti/AntiApp.java: -------------------------------------------------------------------------------- 1 | package com.tg.anti; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | 6 | public class AntiApp extends Application { 7 | 8 | @Override 9 | protected void attachBaseContext(Context base) { 10 | super.attachBaseContext(base); 11 | 12 | xcrash.XCrash.init(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /anti/src/main/cpp/check/anti_dual_app.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/9/4. 3 | // 4 | 5 | #ifndef ANTI_ANDROID_ANTI_DUAL_APP_H 6 | #define ANTI_ANDROID_ANTI_DUAL_APP_H 7 | 8 | #include 9 | #include 10 | 11 | class AntiDualApp { 12 | public: 13 | std::string check(); 14 | 15 | private: 16 | std::string check_dual_app(); 17 | }; 18 | 19 | 20 | #endif //ANTI_ANDROID_ANTI_DUAL_APP_H 21 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /anti/src/main/cpp/xposeddetector/classloader.h: -------------------------------------------------------------------------------- 1 | #ifndef ANTI_ANDROID_CLASSLOADER_H 2 | #define ANTI_ANDROID_CLASSLOADER_H 3 | 4 | #include "jni.h" 5 | 6 | class classloader { 7 | public: 8 | static void checkClassLoader(C_JNIEnv *env, int sdk); 9 | 10 | private: 11 | static void checkGlobalRef(C_JNIEnv *env, jclass clazz); 12 | 13 | static void checkWeakGlobalRef(C_JNIEnv *env, jclass clazz); 14 | }; 15 | 16 | 17 | #endif //ANTI_ANDROID_CLASSLOADER_H 18 | -------------------------------------------------------------------------------- /app/src/test/java/com/tg/anti/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.tg.anti; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /anti/src/test/java/com/tg/android/anti/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.tg.android.anti; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /anti/src/main/cpp/check/anti_frida.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/9/3. 3 | // 4 | 5 | #ifndef ANTI_ANDROID_ANTI_FRIDA_H 6 | #define ANTI_ANDROID_ANTI_FRIDA_H 7 | 8 | #include 9 | 10 | class AntiFrida { 11 | public: 12 | void check(); 13 | 14 | private: 15 | uint64_t frida_find_library_base(std::string library_name, char **library_path); 16 | 17 | uint64_t frida_find_library_space_base(uint64_t base, uint32_t page_size); 18 | }; 19 | 20 | 21 | #endif //ANTI_ANDROID_ANTI_FRIDA_H 22 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | anti 3 | frida 4 | xposed 5 | dualApp 6 | emulator 7 | memDump 8 | debug 9 | root 10 | virtualApp 11 | magisk 12 | -------------------------------------------------------------------------------- /anti/src/main/cpp/check/anti_emulator.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/10/15. 3 | // 4 | 5 | #ifndef ANTI_ANDROID_ANTI_EMULATOR_H 6 | #define ANTI_ANDROID_ANTI_EMULATOR_H 7 | 8 | #include 9 | 10 | // https://bbs.pediy.com/thread-255672.htm 11 | class AntiEmulator { 12 | public: 13 | std::string check(); 14 | 15 | private: 16 | bool check_of_file(std::string file_name); 17 | 18 | bool dir(std::string dir_name); 19 | 20 | std::string check_of_prop(std::string cmd); 21 | }; 22 | 23 | 24 | #endif //ANTI_ANDROID_ANTI_EMULATOR_H 25 | -------------------------------------------------------------------------------- /anti/src/main/cpp/check/anti_mem_dump.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/10/15. 3 | // 4 | 5 | #ifndef ANTI_ANDROID_ANTI_MEM_DUMP_H 6 | #define ANTI_ANDROID_ANTI_MEM_DUMP_H 7 | 8 | #include 9 | 10 | unsigned static int gpCrash = 0xfa91b9cb; 11 | 12 | class AntiMemDump { 13 | public: 14 | static void detect_memory_dump_loop(void *args); 15 | 16 | private: 17 | inline static void detect_fileaccess_for_debugger_memorydump(); 18 | 19 | inline static int crash(int randomval); 20 | 21 | private: 22 | }; 23 | 24 | 25 | #endif //ANTI_ANDROID_ANTI_MEM_DUMP_H 26 | -------------------------------------------------------------------------------- /anti/src/main/cpp/xposeddetector/find_name.h: -------------------------------------------------------------------------------- 1 | #ifndef ANTI_ANDROID_FIND_NAME_H 2 | #define ANTI_ANDROID_FIND_NAME_H 3 | 4 | 5 | #include 6 | 7 | class find_name { 8 | public: 9 | static char *findObjectArrayName(C_JNIEnv *env, jobject clazz); 10 | 11 | static char *findStaticMapName(C_JNIEnv *env, jobject clazz); 12 | 13 | static char *findVoidStringName(C_JNIEnv *env, jclass clazz); 14 | 15 | private: 16 | static char *findField(C_JNIEnv *env, jobject clazz, int staticFlag, jclass type); 17 | 18 | }; 19 | 20 | 21 | #endif //ANTI_ANDROID_FIND_NAME_H 22 | -------------------------------------------------------------------------------- /anti/src/main/cpp/utils/Utils.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/9/20. 3 | // 4 | 5 | #ifndef ANTI_ANDROID_UTILS_H 6 | #define ANTI_ANDROID_UTILS_H 7 | 8 | #include 9 | 10 | //定义TAG之后,我们可以在LogCat通过TAG过滤出NDK打印的日志 11 | #define TAG "ANTI" 12 | // 定义info信息 13 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__) 14 | // 定义debug信息 15 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__) 16 | // 定义error信息 17 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__) 18 | 19 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG,__VA_ARGS__) 20 | 21 | #endif //ANTI_ANDROID_UTILS_H 22 | -------------------------------------------------------------------------------- /anti/src/main/cpp/check/anti_xposed.h: -------------------------------------------------------------------------------- 1 | #ifndef ANTI_ANDROID_ANTI_XPOSED_H 2 | #define ANTI_ANDROID_ANTI_XPOSED_H 3 | 4 | #include 5 | 6 | 7 | enum { 8 | // no xposed environment. 9 | NO_XPOSED, 10 | // have xposed environment but not hooked us, 11 | // or unknown xposed implementation, so hooks cannot be cleared. 12 | FOUND_XPOSED, 13 | // xposed hooks cleared. 14 | ANTIED_XPOSED, 15 | // can not clear hooks. 16 | CAN_NOT_ANTI_XPOSED, 17 | }; 18 | 19 | class AntiXposed { 20 | public: 21 | int get_xposed_status(JNIEnv *env, int sdk); 22 | 23 | public: 24 | 25 | }; 26 | 27 | 28 | #endif //ANTI_ANDROID_ANTI_XPOSED_H 29 | -------------------------------------------------------------------------------- /anti/src/main/cpp/check/anti_xposed.cpp: -------------------------------------------------------------------------------- 1 | #include "anti_xposed.h" 2 | #include 3 | #include "../xposeddetector/classloader.h" 4 | #include "Utils.h" 5 | #include "../JNIHelper/JNIHelper.hpp" 6 | #include "../xposeddetector/xposed.h" 7 | 8 | int xposed_status = NO_XPOSED; 9 | 10 | int AntiXposed::get_xposed_status(JNIEnv *env, int sdk) { 11 | jh::JNIEnvironmentGuarantee jniEnvironmentGuarantee; 12 | classloader::checkClassLoader((C_JNIEnv *) env, sdk); 13 | 14 | xposed::checkCallStack((C_JNIEnv *) env); 15 | 16 | if (xposed_status == NO_XPOSED) { 17 | LOGE("xposed_status == NO_XPOSED"); 18 | //return xposed_status; 19 | } 20 | 21 | xposed::checkCallStack((C_JNIEnv *) env); 22 | 23 | return xposed_status; 24 | } -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/private/common.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #if defined(__i386__) 14 | #define __LIBC_HIDDEN__ __attribute__((visibility("hidden"))) 15 | 16 | __attribute__((__naked__)) static void __libc_int0x80() { 17 | __asm__ volatile("int $0x80; ret"); 18 | } 19 | 20 | __LIBC_HIDDEN__ void* __libc_sysinfo = (void*)(__libc_int0x80); 21 | 22 | // TODO: lose this function and just access __libc_sysinfo directly. 23 | __LIBC_HIDDEN__ void* __kernel_syscall() { 24 | return __libc_sysinfo; 25 | } 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/_arm_on_x86.c: -------------------------------------------------------------------------------- 1 | #include "_mini_io.h" 2 | #include 3 | #include 4 | #include 5 | 6 | static bool arm_on_x86 = false; 7 | static bool checked = false; 8 | 9 | bool _arm_on_x86() { 10 | #if defined(__aarch64__) || defined(__arm__) 11 | if(checked) { 12 | return arm_on_x86; 13 | } 14 | int fd = open("/proc/self/exe", O_RDONLY); 15 | Elf32_Ehdr hdr; 16 | memset(&hdr, 0 , sizeof(hdr)); 17 | if(read(fd, &hdr, sizeof(hdr)) < 0) { 18 | arm_on_x86 = false; 19 | } else { 20 | arm_on_x86 = hdr.e_machine == EM_386 || hdr.e_machine == EM_X86_64; 21 | } 22 | close(fd); 23 | checked = true; 24 | return arm_on_x86; 25 | #elif defined(__i386__) || defined(__x86_64__) 26 | return false; 27 | #endif 28 | 29 | } 30 | -------------------------------------------------------------------------------- /anti/src/main/java/com/tg/android/anti/NativeLib.java: -------------------------------------------------------------------------------- 1 | package com.tg.android.anti; 2 | 3 | public class NativeLib { 4 | 5 | // Used to load the 'anti' library on application startup. 6 | static { 7 | System.loadLibrary("anti"); 8 | } 9 | 10 | // anti frida 11 | public static native String AntiFrida(); 12 | 13 | // anti xposed/like xposed 14 | public static native String AntiXposed(); 15 | 16 | // anti root 17 | public static native String AntiRoot(); 18 | 19 | // anti debug 20 | public static native String AntiDebug(); 21 | 22 | // anti mem dump 23 | public static native String AntiMemDump(); 24 | 25 | // anti emulator 26 | public static native String AntiEmulator(); 27 | 28 | // anti dual app 29 | public static native String AntiDualApp(); 30 | } -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/core/JavaMethod.h: -------------------------------------------------------------------------------- 1 | #ifndef ANTI_ANDROID_JAVAMETHOD_H 2 | #define ANTI_ANDROID_JAVAMETHOD_H 3 | namespace jh { 4 | template 5 | jmethodID findMethod(std::string className, std::string methodName) { 6 | JNIEnv *env = getCurrentJNIEnvironment(); 7 | jclass javaClass = FindClass(className); 8 | if (javaClass == nullptr) 9 | return nullptr; 10 | std::string methodSignature = getJavaMethodSignature(); 11 | jmethodID javaMethod = env->GetMethodID(javaClass, methodName.c_str(), 12 | methodSignature.c_str()); 13 | env->DeleteLocalRef(javaClass); 14 | 15 | return javaMethod; 16 | } 17 | } 18 | #endif //ANTI_ANDROID_JAVAMETHOD_H 19 | -------------------------------------------------------------------------------- /anti/src/main/cpp/xposeddetector/plt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "Utils.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #define PLT_CHECK_PLT_APP ((unsigned short) 0x1u) 13 | #define PLT_CHECK_PLT_ALL ((unsigned short) 0x2u) 14 | #define PLT_CHECK_NAME ((unsigned short) 0x4u) 15 | #define PLT_CHECK_SYM_ONE ((unsigned short) 0x8u) 16 | 17 | typedef struct Symbol { 18 | unsigned short check; 19 | unsigned short size; 20 | size_t total; 21 | ElfW(Addr) *symbol_plt; 22 | ElfW(Addr) *symbol_sym; 23 | const char *symbol_name; 24 | char **names; 25 | } Symbol; 26 | 27 | int dl_iterate_phdr_symbol(Symbol *symbol); 28 | 29 | void *plt_dlsym(const char *name, size_t *total); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /anti/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /anti/src/main/cpp/xposeddetector/hash.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "hash.h" 3 | 4 | static int size; 5 | static int index; 6 | static intptr_t *container; 7 | 8 | bool add(intptr_t hash) { 9 | if (hash == 0) { 10 | return clear(); 11 | } 12 | for (int i = 0; i < index; ++i) { 13 | if (container[i] == hash) { 14 | return false; 15 | } 16 | } 17 | if (index >= size) { 18 | size += 4; 19 | container = (intptr_t *) (realloc(container, size * sizeof(intptr_t))); 20 | } 21 | container[index++] = hash; 22 | return true; 23 | } 24 | 25 | bool clear() { 26 | if (container) { 27 | free(container); 28 | size = 0; 29 | index = 0; 30 | container = nullptr; 31 | return true; 32 | } else { 33 | return false; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /anti/src/androidTest/java/com/tg/anti/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.tg.anti; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.tg.anti.test", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/_mini_io.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #if defined(__cplusplus) 6 | extern "C" { 7 | #endif 8 | 9 | 10 | extern int _errno; 11 | long ___set_errno_internal(int n); 12 | int ___close(int); 13 | int __openat(int, const char *, int, int); 14 | int _open(const char *pathname, int flags, ...); 15 | int _close(int fd); 16 | ssize_t _write(int __fd, const void *__buf, size_t __count); 17 | ssize_t _read(int fd, void *buf, size_t count); 18 | off_t _lseek(int __fd, off_t __offset, int __whence); 19 | int _readlinkat(int, const char *, char *, size_t); 20 | int _nanosleep(const struct timespec *, struct timespec *); 21 | int _inotify_init1(int flags); 22 | int _inotify_add_watch(int, const char *, uint32_t); 23 | int _inotify_rm_watch(int, int); 24 | 25 | 26 | bool _arm_on_x86(); 27 | 28 | #if defined(__cplusplus) 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/tg/anti/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.tg.anti; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.tg.antiptrace", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /anti/src/main/cpp/xposeddetector/xposed.h: -------------------------------------------------------------------------------- 1 | #ifndef ANTI_ANDROID_XPOSED_H 2 | #define ANTI_ANDROID_XPOSED_H 3 | 4 | #include 5 | #include "anti_xposed.h" 6 | 7 | extern int xposed_status; 8 | 9 | class xposed { 10 | public: 11 | static void doAntiXposed(C_JNIEnv *env, jobject object, intptr_t hash); 12 | 13 | static void checkCallStack(C_JNIEnv *env); 14 | 15 | private: 16 | static jclass findLoadedClass(C_JNIEnv *env, jobject classLoader, const char *name); 17 | 18 | static jclass findXposedBridge(C_JNIEnv *env, jobject classLoader); 19 | 20 | static jclass findXposedHelper(C_JNIEnv *env, jobject classLoader); 21 | 22 | static bool disableXposedBridge(C_JNIEnv *env, jclass classXposedBridge); 23 | 24 | static jfieldID findMapField(C_JNIEnv *env, jclass classXposedBridge); 25 | 26 | static bool doClearHooksClass(C_JNIEnv *env, jclass classXposedBridge); 27 | 28 | static bool doClearHooksCommon(C_JNIEnv *env, jobject classLoader, const char *name); 29 | 30 | static bool clearHooks(C_JNIEnv *env, jobject classLoader); 31 | 32 | }; 33 | 34 | 35 | #endif //ANTI_ANDROID_XPOSED_H 36 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/utils/JStringUtils.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JStringUtils.cpp 3 | \brief Utility functions to use jstring objects. 4 | \author Denis Sorokin 5 | \date 24.01.2016 6 | */ 7 | 8 | #include "../core/JNIEnvironment.hpp" 9 | #include "../utils/JStringUtils.hpp" 10 | 11 | namespace jh { 12 | jstring createJString(const char *str) { 13 | JNIEnv *env = getCurrentJNIEnvironment(); 14 | return env->NewStringUTF(str); 15 | } 16 | 17 | jstring createJString(const std::string str) { 18 | JNIEnv *env = getCurrentJNIEnvironment(); 19 | return env->NewStringUTF(str.c_str()); 20 | } 21 | 22 | jstring createJString(const std::string &str) { 23 | JNIEnv *env = getCurrentJNIEnvironment(); 24 | return env->NewStringUTF(str.c_str()); 25 | } 26 | 27 | std::string jstringToStdString(const jstring javaString) { 28 | JNIEnv *env = getCurrentJNIEnvironment(); 29 | 30 | const char *nativeString = env->GetStringUTFChars(javaString, nullptr); 31 | std::string str(nativeString); 32 | env->ReleaseStringUTFChars(javaString, nativeString); 33 | 34 | return str; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/tg/anti/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.tg.anti; 2 | 3 | import static com.tg.android.anti.NativeLib.*; 4 | 5 | import android.app.Activity; 6 | import android.os.Bundle; 7 | import android.widget.TextView; 8 | 9 | public class MainActivity extends Activity { 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | setContentView(R.layout.activity_main); 14 | 15 | TextView frida = findViewById(R.id.frida); 16 | frida.setText(AntiFrida()); 17 | 18 | TextView xposed = findViewById(R.id.xposed); 19 | xposed.setText(AntiXposed()); 20 | 21 | TextView root = findViewById(R.id.root); 22 | root.setText(AntiRoot()); 23 | 24 | TextView debug = findViewById(R.id.debug); 25 | debug.setText(AntiDebug()); 26 | 27 | TextView memDump = findViewById(R.id.memDump); 28 | memDump.setText(AntiMemDump()); 29 | 30 | TextView emulator = findViewById(R.id.emulator); 31 | emulator.setText(AntiEmulator()); 32 | 33 | TextView dualApp = findViewById(R.id.dualApp); 34 | dualApp.setText(AntiDualApp()); 35 | } 36 | } -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/native/JavaNativeMethod.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JavaNativeMethod.cpp 3 | \brief Allocation and registration of java native methods in C++. 4 | \author Denis Sorokin 5 | \date 15.02.2016 6 | */ 7 | 8 | #include 9 | #include "../core/ErrorHandler.hpp" 10 | #include "../core/JNIEnvironment.hpp" 11 | #include "../native/JavaNativeMethod.hpp" 12 | 13 | namespace jh { 14 | bool registerJavaNativeMethods(std::string javaClassName, int methodCount, 15 | JNINativeMethod *methodDescriptions) { 16 | auto env = getCurrentJNIEnvironment(); 17 | 18 | jclass javaClass = env->FindClass(javaClassName.c_str()); 19 | if (javaClass == nullptr) { 20 | reportInternalError( 21 | "unable to find class [" + javaClassName + "] for native methods registration"); 22 | return false; 23 | } 24 | 25 | if (env->RegisterNatives(javaClass, methodDescriptions, methodCount) < 0) { 26 | reportInternalError( 27 | "unable to register native methods for class [" + javaClassName + "]"); 28 | return false; 29 | } 30 | 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/_open.c: -------------------------------------------------------------------------------- 1 | #include "_mini_io.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static inline int force_O_LARGEFILE(int flags) { 10 | #if defined(__LP64__) 11 | return flags; // No need, and aarch64's strace gets confused. 12 | #else 13 | return flags | O_LARGEFILE; 14 | #endif 15 | } 16 | 17 | #ifndef O_TMPFILE 18 | #define O_TMPFILE (020000000 | 00200000) 19 | #endif 20 | 21 | static inline bool 22 | 23 | needs_mode(int flags) { 24 | return ((flags & O_CREAT) == O_CREAT) || ((flags & O_TMPFILE) == O_TMPFILE); 25 | } 26 | 27 | int _open(const char *pathname, int flags, ...) { 28 | mode_t mode = 0; 29 | 30 | if (needs_mode(flags)) { 31 | va_list args; 32 | va_start(args, flags); 33 | mode = (mode_t) (va_arg(args, 34 | int)); 35 | va_end(args); 36 | } 37 | 38 | return __openat(AT_FDCWD, pathname, force_O_LARGEFILE(flags), mode); 39 | } 40 | 41 | int _close(int fd) { 42 | // if(_arm_on_x86()){ 43 | // return close(fd); 44 | // } 45 | int rc = ___close(fd); 46 | if (rc == -1 && _errno == EINTR) { 47 | return 0; 48 | } 49 | return rc; 50 | } 51 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/core/ErrorHandler.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file ErrorHandler.hpp 3 | \brief Describes how internal errors should be reported. 4 | \author Denis Sorokin 5 | \date 24.01.2016 6 | */ 7 | 8 | #ifndef JH_ERROR_HANDLER_HPP 9 | #define JH_ERROR_HANDLER_HPP 10 | 11 | #include 12 | #include 13 | 14 | namespace jh { 15 | /** 16 | * Reports some error that happened during JNI-related actions to user. 17 | * This method is intended to be used only by this library. 18 | * 19 | * @param errorMessage Message string describing the error. 20 | */ 21 | inline void reportInternalError(std::string errorMessage) { 22 | __android_log_write(ANDROID_LOG_ERROR, "ZFJavaHelper", 23 | ("JavaHelper internal error: '" + errorMessage + "'.").c_str()); 24 | } 25 | 26 | /** 27 | * Reports some information to user. 28 | * This method is intended to be used only by this library. 29 | * 30 | * @param message Message string that should be reported to user. 31 | */ 32 | inline void reportInternalInfo(std::string message) { 33 | __android_log_write(ANDROID_LOG_INFO, "ZFJavaHelper", 34 | ("JavaHelper message: '" + message + "'.").c_str()); 35 | } 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/utils/JStringUtils.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JStringUtils.hpp 3 | \brief Utility functions to use jstring objects. 4 | \author Denis Sorokin 5 | \date 24.01.2016 6 | */ 7 | 8 | /** 9 | * Cheat sheet: 10 | * 11 | * @code{.cpp} 12 | * 13 | * // Creating java string: 14 | * jstring js = jh::createJString("someText"); 15 | * 16 | * // Transforming java string to std::string: 17 | * std::string ss = jh::jstringToStdString(js); 18 | * 19 | * @endcode 20 | */ 21 | 22 | #ifndef JH_JSTRING_UTILS_HPP 23 | #define JH_JSTRING_UTILS_HPP 24 | 25 | #include 26 | #include 27 | 28 | namespace jh { 29 | /** 30 | * Creates a new java string from C-style string. 31 | * 32 | * @param str String to be converted. 33 | * @return Equivalent java string. 34 | */ 35 | jstring createJString(const char *str); 36 | 37 | /** 38 | * Creates a new java string from C++-style string. 39 | * 40 | * @param str String to be converted. 41 | * @return Equivalent java string. 42 | */ 43 | jstring createJString(const std::string str); 44 | 45 | /** 46 | * Creates a std::string from a java string pointer. 47 | * 48 | * @param str Java string pointer. 49 | * @return Equivalent std::string string. 50 | */ 51 | std::string jstringToStdString(const jstring str); 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/utils/JniGlobalRef.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UTDID_JNIGLOBALREF_HPP 2 | #define UTDID_JNIGLOBALREF_HPP 3 | 4 | 5 | #include "../core/JNIEnvironment.hpp" 6 | #include "../core/JavaCustomClass.hpp" 7 | 8 | namespace jh { 9 | template 10 | class JniGlobalRef { 11 | public: 12 | JniGlobalRef() : _obj(nullptr) {} 13 | 14 | JniGlobalRef(const JniGlobalRef &ref) : _obj(nullptr) { set(ref.get()); } 15 | 16 | ~JniGlobalRef() { set(nullptr); } 17 | 18 | JniType get() const { return _obj; } 19 | 20 | void set(JniType obj) { 21 | JNIEnv *env = getCurrentJNIEnvironment(); 22 | if (_obj) { 23 | if (env) { 24 | env->DeleteGlobalRef(_obj); 25 | } 26 | _obj = nullptr; 27 | } 28 | if (obj && env) { 29 | _obj = (JniType) env->NewGlobalRef(obj); 30 | } 31 | } 32 | 33 | operator JniType() const { return _obj; } 34 | 35 | void operator=(const JniType other) { set(other); } 36 | 37 | void operator=(const JniGlobalRef &ref) { set(ref.get()); } 38 | 39 | 40 | operator bool() const { 41 | return !areEqual(get(), nullptr); 42 | } 43 | 44 | private: 45 | JniType _obj; 46 | }; 47 | } 48 | 49 | #endif //UTDID_JNIGLOBALREF_HPP 50 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | } 4 | 5 | android { 6 | compileSdkVersion 31 7 | buildToolsVersion "30.0.2" 8 | 9 | defaultConfig { 10 | applicationId "com.tg.anti" 11 | minSdkVersion 19 12 | targetSdkVersion 30 13 | versionCode 1 14 | versionName "1.0" 15 | 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | ndk { 18 | abiFilters 'arm64-v8a', "armeabi-v7a", "x86", "x86_64" 19 | } 20 | } 21 | 22 | buildTypes { 23 | release { 24 | minifyEnabled false 25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_8 30 | targetCompatibility JavaVersion.VERSION_1_8 31 | } 32 | } 33 | 34 | dependencies { 35 | 36 | implementation 'androidx.appcompat:appcompat:1.2.0' 37 | implementation 'com.google.android.material:material:1.3.0' 38 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4' 39 | testImplementation 'junit:junit:4.+' 40 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 41 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 42 | 43 | implementation project(":anti") 44 | 45 | implementation 'com.iqiyi.xcrash:xcrash-android-lib:3.0.0' 46 | } -------------------------------------------------------------------------------- /anti/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.18.1) 2 | 3 | project("anti") 4 | 5 | add_subdirectory(mini_io) 6 | 7 | include_directories(mini_io 8 | JNIHelper 9 | check 10 | utils) 11 | 12 | add_library( 13 | anti 14 | 15 | SHARED 16 | 17 | anti.cpp 18 | check/anti_frida.cpp 19 | check/anti_frida.h 20 | check/anti_dual_app.cpp 21 | check/anti_dual_app.h 22 | check/anti_xposed.cpp 23 | check/anti_xposed.h 24 | check/anti_emulator.cpp 25 | check/anti_emulator.h 26 | check/anti_mem_dump.cpp 27 | check/anti_mem_dump.h 28 | 29 | JNIHelper/utils/JavaObjectPointer.cpp 30 | JNIHelper/utils/JStringUtils.cpp 31 | JNIHelper/native/JavaNativeMethod.cpp 32 | JNIHelper/core/JNIEnvironment.cpp 33 | JNIHelper/core/JavaCustomClass.cpp 34 | 35 | utils/Utils.cpp 36 | 37 | xposeddetector/art.h 38 | xposeddetector/classloader.cpp 39 | xposeddetector/classloader.h 40 | xposeddetector/find_name.cpp 41 | xposeddetector/find_name.h 42 | xposeddetector/hash.cpp 43 | xposeddetector/hash.h 44 | xposeddetector/plt.h 45 | xposeddetector/plt.c 46 | xposeddetector/xposed.cpp 47 | xposeddetector/xposed.h 48 | ) 49 | 50 | 51 | find_library( 52 | log-lib 53 | log) 54 | 55 | target_link_libraries( 56 | anti 57 | 58 | mini_io 59 | ${log-lib}) -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/app/ActivityThread.h: -------------------------------------------------------------------------------- 1 | #include "../calls/InstanceCaller.hpp" 2 | #include "../native/JavaObjectWrapper.hpp" 3 | #include "jni.h" 4 | #include "../calls/FieldCaller.h" 5 | 6 | JAVA_CLASS(JavaApplication, 7 | "android/app/Application") 8 | 9 | JAVA_CLASS(JavaContext, 10 | "android/content/Context") 11 | 12 | JAVA_CLASS(JavaApplicationInfo, 13 | "android/content/pm/ApplicationInfo") 14 | 15 | #ifndef ANTI_ANDROID_ACTIVITYTHREAD_H 16 | #define ANTI_ANDROID_ACTIVITYTHREAD_H 17 | 18 | class Application : public jh::JavaObjectWrapper { 19 | public: 20 | void linkJavaNativeMethods() override { 21 | 22 | } 23 | 24 | jobject initializeJavaObject() override { 25 | return jh::getCurrentApplication(); 26 | } 27 | 28 | jobject getContext() { 29 | //return object(); 30 | return jh::callMethod(object(), "getApplicationContext", true); 31 | } 32 | 33 | jstring getDataDir() { 34 | jobject applicationInfo = jh::callMethod(getContext(), 35 | "getApplicationInfo", 36 | true); 37 | 38 | jstring ret = jh::getFiled(applicationInfo, "dataDir", true); 39 | jh::getCurrentJNIEnvironment()->DeleteLocalRef(applicationInfo); 40 | return ret; 41 | } 42 | }; 43 | 44 | #endif //ANTI_ANDROID_ACTIVITYTHREAD_H 45 | -------------------------------------------------------------------------------- /anti/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | } 4 | 5 | android { 6 | compileSdkVersion 31 7 | 8 | defaultConfig { 9 | minSdkVersion 16 10 | targetSdkVersion 30 11 | 12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 13 | consumerProguardFiles "consumer-rules.pro" 14 | externalNativeBuild { 15 | cmake { 16 | cppFlags "-std=c++11" 17 | arguments "-DANDROID_STL=c++_static" 18 | //这里使用的地址就是上面查询到的 ninja 的地址 19 | //"-DCMAKE_MAKE_PROGRAM=/usr/bin/ninja" 20 | } 21 | } 22 | ndk { 23 | abiFilters 'arm64-v8a', "armeabi-v7a", "x86", "x86_64" 24 | } 25 | } 26 | 27 | buildTypes { 28 | release { 29 | minifyEnabled false 30 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 31 | } 32 | } 33 | externalNativeBuild { 34 | cmake { 35 | path "src/main/cpp/CMakeLists.txt" 36 | version "3.22.1" 37 | } 38 | } 39 | compileOptions { 40 | sourceCompatibility JavaVersion.VERSION_1_8 41 | targetCompatibility JavaVersion.VERSION_1_8 42 | } 43 | } 44 | 45 | dependencies { 46 | 47 | implementation 'androidx.appcompat:appcompat:1.2.0' 48 | implementation 'com.google.android.material:material:1.6.1' 49 | testImplementation 'junit:junit:4.13.2' 50 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 51 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 52 | } -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/core/JavaCustomClass.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "JavaCustomClass.hpp" 3 | #include "JNIEnvironment.hpp" 4 | #include "../utils/JniGlobalRef.hpp" 5 | #include "../calls/InstanceCaller.hpp" 6 | #include "JavaMethod.h" 7 | 8 | 9 | JAVA_CLASS(JavaClassLoader, "java/lang/ClassLoader") 10 | 11 | JAVA_CLASS(JavaClass, "java/lang/Class") 12 | 13 | namespace jh { 14 | 15 | static JniGlobalRef *gClassLoader; 16 | static jmethodID gClassLoaderFindClass; 17 | 18 | jclass FindClass(const std::string &name) { 19 | JNIEnv *env = getCurrentJNIEnvironment(); 20 | jclass javaClass = env->FindClass(name.c_str()); 21 | if (javaClass == nullptr) { 22 | env->ExceptionClear(); 23 | javaClass = static_cast(env->CallObjectMethod(gClassLoader->get(), 24 | gClassLoaderFindClass, 25 | env->NewStringUTF(name.c_str()))); 26 | } 27 | return javaClass; 28 | } 29 | 30 | void loadClassLoader() { 31 | if (gClassLoader == nullptr) { 32 | jobject classloader = jh::callMethod(getCurrentApplication(), 33 | "getClassLoader", 34 | true); 35 | gClassLoader = new JniGlobalRef(); 36 | gClassLoader->set(classloader); 37 | gClassLoaderFindClass = findMethod(JavaClassLoader::className(), 38 | "findClass"); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # anti 2 | 3 | ## Introduction 4 | 5 | Is a protect Android App anti any attacks and environments. 6 | 7 | 可能会通过检测的方式来进行anti,也有可能通过攻击手段的实现原理进行anti。 8 | 9 | ## Anti Frida 10 | 11 | 根据frida的实现细节来作出相应的anti对策。 12 | frida在hook的时候会对目标应用的libc进行获取,使用目标libc的mmap将自身的相关so注册到目标maps表中;再执行目标libc的dlopen和dlsym函数将自身so中的函数进行执行,从而实现了hook操作,详情请看: 13 | https://github.com/frida/frida-core/blob/8f6e88225b702d062ab581c905448b88384f6ab6/src/linux/frida-helper-backend-glue.c 14 | anti frida的灵感也是来自于这里。就是将mmap一个只读的libc到maps表中,这样frida 无法将继续拿到可执行的libc从而崩溃。能够有效针对https://github.com/hluwa/strongR-frida-android 此类项目的去掉特征。 15 | ![](imgs/1.png) 16 | ![](imgs/2.png) 17 | ![](imgs/3.png) 18 | 19 | `Anti Frida`只对frida attach模式攻击的对抗。 20 | 21 | ## Anti Xposed/like Xposed 22 | 思路来源: 23 | - https://blog.canyie.top/2021/05/01/anti-magisk-xposed/ 24 | - https://github.com/vvb2060/XposedDetector 25 | ## Anti Root 26 | 27 | ## Anti Debug 28 | 29 | ## Anti MemDump 30 | 思路来源:https://github.com/darvincisec/AntiDebugandMemoryDump 31 | - 使用监视相关文件 32 | 33 | 更多详细内容,参考:https://s5rxx58djb.feishu.cn/docs/doccnEenEJJas6iQPjc83M0dLed 34 | 35 | ## Anti Virtual App/Multi Run 36 | 37 | ### Anti Virtual App 38 | Virtual App 会在自己的文件系统中创建一个文件目录,通过这特点可以判断是否为Virtual App,因为正常情况下,app访问所有父目录都是不可读的。 39 | 思路来自:https://juejin.cn/post/6964673582924300296#heading-18 40 | ![](imgs/4.png) 41 | ![](imgs/5.png) 42 | 43 | ### Anti Multi Run 44 | 思路来源:https://bbs.pediy.com/thread-255212.htm 45 | 基于svc来获得app的安装目录,防止被hook(除内核层面)。 46 | 47 | ## Anti Emulator 48 | 思路来源:https://bbs.pediy.com/thread-255672.htm 49 | 50 | # Thanks 51 | - [xCrash](https://github.com/iqiyi/xCrash) 52 | - [JNIHelper](https://github.com/kvintessence/JNIHelper) 53 | - [XposedDetector](https://github.com/vvb2060/XposedDetector) 54 | - [AntiDebugandMemoryDump](https://github.com/darvincisec/AntiDebugandMemoryDump) -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/private/bionic_asm_x86_64.h: -------------------------------------------------------------------------------- 1 | /* $NetBSD: asm.h,v 1.18 2013/09/12 15:36:17 joerg Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 1990 The Regents of the University of California. 5 | * All rights reserved. 6 | * 7 | * This code is derived from software contributed to Berkeley by 8 | * William Jolitz. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. Neither the name of the University nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | * 34 | * @(#)asm.h 5.5 (Berkeley) 5/7/91 35 | */ 36 | 37 | // #pragma once 38 | 39 | #define PIC_PLT(x) x@PLT 40 | #define PIC_GOT(x) x@GOTPCREL(%rip) 41 | 42 | #define __bionic_asm_align 16 43 | 44 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/private/bionic_asm_arm64.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: asm.h,v 1.1 2004/02/01 05:09:49 drahn Exp $ */ 2 | /* $NetBSD: asm.h,v 1.4 2001/07/16 05:43:32 matt Exp $ */ 3 | 4 | /* 5 | * Copyright (c) 1990 The Regents of the University of California. 6 | * All rights reserved. 7 | * 8 | * This code is derived from software contributed to Berkeley by 9 | * William Jolitz. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. Neither the name of the University nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 | * SUCH DAMAGE. 34 | * 35 | * from: @(#)asm.h 5.5 (Berkeley) 5/7/91 36 | */ 37 | 38 | #pragma once 39 | 40 | #define __bionic_asm_align 0 41 | 42 | #undef __bionic_asm_function_type 43 | #define __bionic_asm_function_type %function 44 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/core/JavaMethodSignature.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JavaMethodSignature.hpp 3 | \brief Java method signatures deduction. 4 | \author Denis Sorokin 5 | \date 24.01.2016 6 | */ 7 | 8 | #ifndef JH_JAVA_METHOD_SIGNATURE_HPP 9 | #define JH_JAVA_METHOD_SIGNATURE_HPP 10 | 11 | #include 12 | #include "ToJavaType.hpp" 13 | 14 | namespace jh { 15 | /** 16 | * Internal Java method signature deduction for two and more classes. 17 | */ 18 | template 19 | struct Signature { 20 | static std::string string() { 21 | return ToJavaType::signature() + 22 | Signature::string(); 23 | } 24 | }; 25 | 26 | /** 27 | * Internal Java method signature deduction for one class. 28 | */ 29 | template 30 | struct Signature { 31 | static std::string string() { 32 | return ToJavaType::signature(); 33 | } 34 | }; 35 | 36 | /** 37 | * Method that returns full java method signature based on the return type 38 | * and argument types passed via template arguments. This function is used 39 | * for Java methods with more than one argument. 40 | * 41 | * @return Java method signature as a string. 42 | */ 43 | template 44 | std::string getJavaMethodSignature() { 45 | return std::string("(") 46 | + Signature::string() 47 | + std::string(")") 48 | + Signature::string(); 49 | } 50 | 51 | /** 52 | * Method that returns full java method signature based on the return type 53 | * and argument types passed via template arguments. This function is used 54 | * for Java methods without arguments. 55 | * 56 | * @return Java method signature as a string. 57 | */ 58 | template 59 | std::string getJavaMethodSignature() { 60 | return std::string("()") 61 | + Signature::string(); 62 | } 63 | } 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /anti/src/main/cpp/check/anti_emulator.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/10/15. 3 | // 4 | 5 | #include "anti_emulator.h" 6 | #include "../mini_io/_mini_io.h" 7 | #include 8 | #include 9 | #include 10 | #include "sys/system_properties.h" // 可以自己实现一遍 11 | #include "../utils/Utils.h" 12 | 13 | 14 | std::string AntiEmulator::check() { 15 | std::string result = "security"; 16 | std::vector list_of_files = 17 | { 18 | "/boot/bstmods/vboxguest.ko", 19 | "/boot/bstmods/vboxsf.ko", 20 | "/dev/qemu_pipe", 21 | "/dev/socket/qemud", 22 | "/dev/socket/windroyed-audio", 23 | "/dev/socket/windroyed-camera", 24 | "/dev/socket/windroyed-gps", 25 | "/dev/socket/windroyed-sensors", 26 | "/dev/vboxguest" 27 | }; 28 | for (auto file: list_of_files) { 29 | if (check_of_file(file) || dir(file)) { 30 | result = "checked"; 31 | } 32 | } 33 | 34 | std::vector list_of_props = { 35 | "ro.redfinger.server.enable", 36 | "androVM.vbox_dpi", 37 | "androVM.vbox_graph_mode" 38 | }; 39 | 40 | for (auto prop: list_of_props) { 41 | if (check_of_prop(prop).find("redfinger") != std::string::npos) { 42 | result = "checked"; 43 | } 44 | } 45 | 46 | LOGE("result: %s", result.c_str()); 47 | return result; 48 | } 49 | 50 | bool AntiEmulator::check_of_file(std::string file_name) { 51 | int fd = _open(file_name.c_str(), O_RDONLY); 52 | if (fd == errno || fd == -1) { 53 | return false; 54 | } 55 | return true; 56 | } 57 | 58 | bool AntiEmulator::dir(std::string dir_name) { 59 | int fd = _open(dir_name.c_str(), O_DIRECTORY); 60 | if (fd == errno || fd == -1) { 61 | return false; 62 | } 63 | return true; 64 | } 65 | 66 | std::string AntiEmulator::check_of_prop(std::string cmd) { 67 | char value[256]; 68 | std::string result; 69 | __system_property_get(cmd.c_str(), value); 70 | 71 | result = value; 72 | 73 | memset(value, 0, sizeof value); 74 | 75 | return result; 76 | } 77 | -------------------------------------------------------------------------------- /anti/src/main/cpp/check/anti_dual_app.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/9/4. 3 | // 4 | 5 | #include 6 | 7 | #include "anti_dual_app.h" 8 | #include "../JNIHelper/JNIHelper.hpp" 9 | #include "../mini_io/_mini_io.h" 10 | #include "Utils.h" 11 | #include "../JNIHelper/app/ActivityThread.h" 12 | 13 | std::string AntiDualApp::check() { 14 | 15 | return check_dual_app(); 16 | } 17 | 18 | // https://bbs.pediy.com/thread-255212.htm 19 | // 360分身大师测有问题 20 | std::string AntiDualApp::check_dual_app() { 21 | jh::JNIEnvironmentGuarantee jniEnvironmentGuarantee; 22 | 23 | std::string self_fd = "/proc/self/fd"; 24 | std::string simple_name = "wtf_jack"; 25 | std::string data_dir_path = jh::jstringToStdString(Application().getDataDir()); 26 | if (data_dir_path.empty()) { 27 | return "security"; 28 | } 29 | std::string separator = "/"; 30 | 31 | data_dir_path = data_dir_path + separator + simple_name; 32 | 33 | int flag = O_RDWR | O_CREAT | O_TRUNC; 34 | int fd = __openat(AT_FDCWD, data_dir_path.c_str(), flag, 0666); 35 | LOGE("data_dir_path: %s", data_dir_path.c_str()); 36 | 37 | if (-1 == fd) { 38 | LOGE("-1 == fd"); 39 | return "security"; 40 | } else { 41 | char fd_path[80] = {0}; 42 | sprintf(fd_path, "%s%d", (self_fd + separator).c_str(), fd); 43 | 44 | LOGE("fd_path: %s", fd_path); 45 | 46 | char buff[1024] = {0}; 47 | 48 | std::size_t len = _readlinkat(AT_FDCWD, fd_path, buff, sizeof(buff)); 49 | 50 | if (len < 0) { 51 | LOGE("len < 0"); 52 | return "security"; 53 | } 54 | 55 | buff[len] = '\0'; 56 | int count_file = 0; 57 | LOGE("buff's len : %d", strlen(buff)); 58 | LOGE("buff: %s", buff); 59 | 60 | for (int i = strlen(buff); i > 0; i--) { 61 | if (buff[i] != '/') { 62 | buff[i] = '\0'; 63 | } else { 64 | if (count_file == 0) { 65 | count_file++; 66 | } else { 67 | if (access(buff, R_OK) == 0) { 68 | 69 | return "checked"; 70 | } 71 | } 72 | } 73 | } 74 | } 75 | 76 | return "security"; 77 | } 78 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/core/JNIEnvironment.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JNIEnvironment.hpp 3 | \brief Utilities to get and use JNIEnv* pointer. 4 | \author Denis Sorokin 5 | \date 24.01.2016 6 | */ 7 | 8 | /** 9 | * Cheat sheet: 10 | * 11 | * @code{.cpp} 12 | * 13 | * // Lets assume that we have entered some scope and we are in a non-java thread: 14 | * { 15 | * 16 | * // Attaching this thread to JVM: 17 | * jh::JavaEnvironmentGuarantee javaContext(); 18 | * 19 | * // Get JNIEnv* pointer and do something with it: 20 | * auto env = jh::getCurrentJNIEnvironment(); 21 | * 22 | * // Doing something with Java code; for example, creating jstring... 23 | * ... 24 | * 25 | * // Leaving the scope; this thread will be detached from JVM: 26 | * } 27 | * 28 | * @endcode 29 | */ 30 | 31 | #ifndef JH_JAVA_ENVIRONMENT_HPP 32 | #define JH_JAVA_ENVIRONMENT_HPP 33 | 34 | #include 35 | 36 | namespace jh { 37 | 38 | /** 39 | * 初始化方法 40 | * @param vm 41 | */ 42 | void onLoad(JavaVM *vm); 43 | 44 | /** 45 | * Returns the pointer to the Java Virtual Machine (JVM). 46 | * 47 | * @return The pointer to JVM. 48 | * @warning Right now, it depends on 'jnienv.*' zframework code. 49 | * @warning Can be nullptr if called before JNI initialization. 50 | */ 51 | JavaVM *getJavaVM(); 52 | 53 | /** 54 | * Returns the JNI environment pointer for the current thread. 55 | * 56 | * @return JNIEnv pointer to the current JNI environment. 57 | * @warning Can be nullptr if called in non-java or unattached thread. 58 | */ 59 | JNIEnv *getCurrentJNIEnvironment(); 60 | 61 | jobject getCurrentApplication(); 62 | 63 | /** 64 | * Utility class that ensures that JNI environment pointer exists while the object 65 | * of this class is alive. Right now, it attaches the current thread to the JVM if 66 | * it is not attached already (and detaches if it is needed after destruction). 67 | * 68 | * @warning Right now, user can't use non-default Java objects in non-Java thread. 69 | */ 70 | class JNIEnvironmentGuarantee { 71 | public: 72 | JNIEnvironmentGuarantee(); 73 | 74 | ~JNIEnvironmentGuarantee(); 75 | 76 | private: 77 | bool m_threadShouldBeDetached; 78 | }; 79 | } 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/private/bionic_asm_x86.h: -------------------------------------------------------------------------------- 1 | /* $NetBSD: asm.h,v 1.40 2011/06/16 13:16:20 joerg Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 1990 The Regents of the University of California. 5 | * All rights reserved. 6 | * 7 | * This code is derived from software contributed to Berkeley by 8 | * William Jolitz. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. Neither the name of the University nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | * 34 | * @(#)asm.h 5.5 (Berkeley) 5/7/91 35 | */ 36 | 37 | #pragma once 38 | 39 | #define PIC_PROLOGUE \ 40 | pushl %ebx; \ 41 | call 666f; \ 42 | 666: \ 43 | popl %ebx; \ 44 | addl $_GLOBAL_OFFSET_TABLE_+[.-666b], %ebx 45 | #define PIC_EPILOGUE \ 46 | popl %ebx 47 | #define PIC_PLT(x) x@PLT 48 | #define PIC_GOT(x) x@GOT(%ebx) 49 | #define PIC_GOTOFF(x) x@GOTOFF(%ebx) 50 | 51 | #define __bionic_asm_align 16 52 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/private/bionic_asm_arm.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: asm.h,v 1.1 2004/02/01 05:09:49 drahn Exp $ */ 2 | /* $NetBSD: asm.h,v 1.4 2001/07/16 05:43:32 matt Exp $ */ 3 | 4 | /* 5 | * Copyright (c) 1990 The Regents of the University of California. 6 | * All rights reserved. 7 | * 8 | * This code is derived from software contributed to Berkeley by 9 | * William Jolitz. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. Neither the name of the University nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 | * SUCH DAMAGE. 34 | * 35 | * from: @(#)asm.h 5.5 (Berkeley) 5/7/91 36 | */ 37 | 38 | #pragma once 39 | 40 | #define __bionic_asm_align 0 41 | 42 | #undef __bionic_asm_custom_entry 43 | #undef __bionic_asm_custom_end 44 | #define __bionic_asm_custom_entry(f) .fnstart 45 | #define __bionic_asm_custom_end(f) .fnend 46 | 47 | #undef __bionic_asm_function_type 48 | #define __bionic_asm_function_type #function 49 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/calls/FieldCaller.h: -------------------------------------------------------------------------------- 1 | #include "jni.h" 2 | #include "string.h" 3 | 4 | #ifndef ANTI_ANDROID_FIELDCALLER_H 5 | #define ANTI_ANDROID_FIELDCALLER_H 6 | namespace jh { 7 | /** 8 | * Class that can call methods which return java objects. 9 | */ 10 | template 11 | struct FiledCaller { 12 | static jobject 13 | call(JNIEnv *env, jobject instance, jfieldID javaMethod, bool autoClearException) { 14 | jobject result = env->GetObjectField(instance, javaMethod); 15 | 16 | return result; 17 | } 18 | }; 19 | 20 | /** 21 | * Calls a method of some Java object instance. Programmer should explicitly 22 | * specify the return type and argument types via template arguments. 23 | * 24 | * @param instance Java object (jobject) 25 | * @param methodName Method name as string. 26 | * @param arguments List of arguments to the java method call. 27 | * @return Some value of ReturnType type returned by the specified method. 28 | */ 29 | template 30 | typename ToJavaType::Type 31 | getFiled(jobject instance, std::string fieldName, bool autoClearException) { 32 | using RealReturnType = typename ToJavaType::Type; 33 | if (instance == nullptr) 34 | return ToJavaType::initValue(); 35 | JNIEnv *env = getCurrentJNIEnvironment(); 36 | 37 | jclass javaClass = env->GetObjectClass(instance); 38 | if (javaClass == nullptr) { 39 | reportInternalError("class for java object instance not found"); 40 | return ToJavaType::initValue(); 41 | } 42 | 43 | jfieldID javaMethod = env->GetFieldID(javaClass, fieldName.c_str(), 44 | ToJavaType::signature().c_str()); 45 | if (javaMethod == nullptr) { 46 | reportInternalError("filed [" + fieldName + "] for java object instance not found"); 47 | return ToJavaType::initValue(); 48 | } 49 | env->DeleteLocalRef(javaClass); 50 | return static_cast(FiledCaller::CallReturnType>::call( 51 | env, instance, javaMethod, autoClearException)); 52 | } 53 | } 54 | #endif //ANTI_ANDROID_FIELDCALLER_H 55 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/utils/JavaObjectPointer.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JavaObjectPointer.cpp 3 | \brief RAII class to store jobject reference as a global reference. 4 | \author Denis Sorokin 5 | \date 28.01.2016 6 | */ 7 | 8 | #include "../core/JNIEnvironment.hpp" 9 | #include "../utils/JavaObjectPointer.hpp" 10 | 11 | namespace jh { 12 | JavaObjectPointer::JavaObjectPointer() 13 | : m_jobjectGlobalReference(nullptr) { 14 | // nothing to do here 15 | } 16 | 17 | JavaObjectPointer::JavaObjectPointer(jobject object) 18 | : m_jobjectGlobalReference(nullptr) { 19 | reset(object); 20 | } 21 | 22 | JavaObjectPointer::JavaObjectPointer(const JavaObjectPointer &other) 23 | : m_jobjectGlobalReference(nullptr) { 24 | reset(other); 25 | } 26 | 27 | JavaObjectPointer::~JavaObjectPointer() { 28 | release(); 29 | } 30 | 31 | JavaObjectPointer &JavaObjectPointer::operator=(const JavaObjectPointer &other) { 32 | if (&other == this) 33 | return *this; 34 | 35 | reset(other.get()); 36 | 37 | return *this; 38 | } 39 | 40 | JavaObjectPointer &JavaObjectPointer::operator=(JavaObjectPointer &&other) { 41 | if (&other == this) 42 | return *this; 43 | 44 | reset(other.get()); 45 | other.release(); 46 | 47 | return *this; 48 | } 49 | 50 | JavaObjectPointer &JavaObjectPointer::operator=(const jobject other) { 51 | reset(other); 52 | 53 | return *this; 54 | } 55 | 56 | void JavaObjectPointer::reset(jobject object) { 57 | JNIEnv *env = getCurrentJNIEnvironment(); 58 | 59 | if (object) { 60 | object = env->NewGlobalRef(object); 61 | } 62 | 63 | if (m_jobjectGlobalReference) { 64 | env->DeleteGlobalRef(m_jobjectGlobalReference); 65 | } 66 | 67 | m_jobjectGlobalReference = object; 68 | } 69 | 70 | void JavaObjectPointer::release() { 71 | reset(nullptr); 72 | } 73 | 74 | jobject JavaObjectPointer::get() const { 75 | return m_jobjectGlobalReference; 76 | } 77 | 78 | JavaObjectPointer::operator jobject() const { 79 | return get(); 80 | } 81 | 82 | JavaObjectPointer::operator bool() const { 83 | return !areEqual(get(), nullptr); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/arrays/ArraySetter.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file ArraySetter.hpp 3 | \brief Internal implementation of setting elements inside java arrays. 4 | \author Denis Sorokin 5 | \date 22.02.2016 6 | */ 7 | 8 | #ifndef JH_ARRAY_SETTER_HPP 9 | #define JH_ARRAY_SETTER_HPP 10 | 11 | #include 12 | 13 | namespace jh { 14 | /** 15 | * Stub implementations for setting elements of java arrays. 16 | */ 17 | template 18 | struct JavaArraySetter; 19 | 20 | /** 21 | * Implementations for setting elements of java boolean arrays. 22 | */ 23 | template<> 24 | struct JavaArraySetter { 25 | static void set(JNIEnv *env, jbooleanArray array, jsize size, jboolean *elements) { 26 | env->SetBooleanArrayRegion(array, 0, size, elements); 27 | } 28 | }; 29 | 30 | /** 31 | * Implementations for setting elements of java int arrays. 32 | */ 33 | template<> 34 | struct JavaArraySetter { 35 | static void set(JNIEnv *env, jintArray array, jsize size, jint *elements) { 36 | env->SetIntArrayRegion(array, 0, size, elements); 37 | } 38 | }; 39 | 40 | /** 41 | * Implementations for setting elements of java long arrays. 42 | */ 43 | template<> 44 | struct JavaArraySetter { 45 | static void set(JNIEnv *env, jlongArray array, jsize size, jlong *elements) { 46 | env->SetLongArrayRegion(array, 0, size, elements); 47 | } 48 | }; 49 | 50 | /** 51 | * Implementations for setting elements of java float arrays. 52 | */ 53 | template<> 54 | struct JavaArraySetter { 55 | static void set(JNIEnv *env, jfloatArray array, jsize size, jfloat *elements) { 56 | env->SetFloatArrayRegion(array, 0, size, elements); 57 | } 58 | }; 59 | 60 | /** 61 | * Implementations for setting elements of java double arrays. 62 | */ 63 | template<> 64 | struct JavaArraySetter { 65 | static void set(JNIEnv *env, jdoubleArray array, jsize size, jdouble *elements) { 66 | env->SetDoubleArrayRegion(array, 0, size, elements); 67 | } 68 | }; 69 | 70 | /** 71 | * Implementations for setting elements of java object arrays. 72 | */ 73 | template<> 74 | struct JavaArraySetter { 75 | static void set(JNIEnv *env, jobjectArray array, jsize size, jobject *elements) { 76 | for (int i = 0; i < size; ++i) { 77 | env->SetObjectArrayElement(array, i, elements[i]); 78 | } 79 | } 80 | }; 81 | } 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/core/JavaCustomClass.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JavaCustomClass.hpp 3 | \brief Allows user to declare custom java classes and deduce method signatures for them. 4 | \author Denis Sorokin 5 | \date 24.01.2016 6 | */ 7 | 8 | /** 9 | * Cheat sheet: 10 | * 11 | * @code{.cpp} 12 | * 13 | * // Declare custom Java class (named Example): 14 | * JH_JAVA_CUSTOM_CLASS(Example, "com/class/path/Example"); 15 | * 16 | * // Get the Java custom class name: 17 | * std::string className = Example::className(); 18 | * 19 | * // Call some static method of this class: 20 | * int result = jh::callStaticMethod("methodName"); 21 | * 22 | * // Explicitly create the object of this class: 23 | * jobject exampleObject = jh::createNewObject(); 24 | * 25 | * // Call some method that returns the object of this class: 26 | * jobject exampleObject2 = jh::callStaticMethod("methodName"); 27 | * 28 | * // Pass the object of this class as a parameter: 29 | * jh::callMethod(someOtherObject, "methodName", exampleObject); 30 | * 31 | * @endcode 32 | */ 33 | 34 | #ifndef JH_JAVA_CUSTOM_CLASS_HPP 35 | #define JH_JAVA_CUSTOM_CLASS_HPP 36 | 37 | #include 38 | #include 39 | 40 | namespace jh { 41 | jclass FindClass(const std::string &name); 42 | 43 | void loadClassLoader(); 44 | } 45 | /** 46 | * This macro magic tells the library about the existance of some android class. 47 | * This allows to perform java method signature deduction and some other stuff to happen. 48 | * After declaring this macro programmer can use the declared class in the JNI calls. 49 | * 50 | * All methods that should return the instance of custom Java class would return 51 | * the pointer to Java object (aka jobject). The programmer should carefully track 52 | * the types of Java objects pointers by himself. 53 | */ 54 | #define JAVA_CLASS(CLASS_NAME_TOKEN, CLASS_PATH_STRING) \ 55 | struct CLASS_NAME_TOKEN \ 56 | { \ 57 | static std::string className() \ 58 | { \ 59 | return CLASS_PATH_STRING; \ 60 | } \ 61 | static std::string signature() \ 62 | { \ 63 | return "L" CLASS_PATH_STRING ";"; \ 64 | } \ 65 | }; 66 | #endif 67 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/arm64-v8a.S: -------------------------------------------------------------------------------- 1 | /* Generated by gensyscalls.py. Do not edit. */ 2 | 3 | #include "private/bionic_asm.h" 4 | 5 | ENTRY_PRIVATE(___close) 6 | mov x8, __NR_close 7 | svc #0 8 | 9 | cmn x0, #(MAX_ERRNO + 1) 10 | cneg x0, x0, hi 11 | b.hi ___set_errno_internal 12 | 13 | ret 14 | END(___close) 15 | 16 | ENTRY_PRIVATE(_lseek) 17 | mov x8, __NR_lseek 18 | svc #0 19 | 20 | cmn x0, #(MAX_ERRNO + 1) 21 | cneg x0, x0, hi 22 | b.hi ___set_errno_internal 23 | 24 | ret 25 | END(_lseek) 26 | 27 | ENTRY_PRIVATE(__openat) 28 | mov x8, __NR_openat 29 | svc #0 30 | 31 | cmn x0, #(MAX_ERRNO + 1) 32 | cneg x0, x0, hi 33 | b.hi ___set_errno_internal 34 | 35 | ret 36 | END(__openat) 37 | 38 | ENTRY_PRIVATE(_read) 39 | mov x8, __NR_read 40 | svc #0 41 | 42 | cmn x0, #(MAX_ERRNO + 1) 43 | cneg x0, x0, hi 44 | b.hi ___set_errno_internal 45 | 46 | ret 47 | END(_read) 48 | 49 | ENTRY_PRIVATE(_write) 50 | mov x8, __NR_write 51 | svc #0 52 | 53 | cmn x0, #(MAX_ERRNO + 1) 54 | cneg x0, x0, hi 55 | b.hi ___set_errno_internal 56 | 57 | ret 58 | END(_write) 59 | 60 | ENTRY_PRIVATE(_ptrace) 61 | mov x8, __NR_ptrace 62 | svc #0 63 | 64 | cmn x0, #(MAX_ERRNO + 1) 65 | cneg x0, x0, hi 66 | b.hi ___set_errno_internal 67 | 68 | ret 69 | END(_ptrace) 70 | 71 | 72 | ENTRY_PRIVATE(_readlinkat) 73 | mov x8, __NR_readlinkat 74 | svc #0 75 | 76 | cmn x0, #(MAX_ERRNO + 1) 77 | cneg x0, x0, hi 78 | b.hi ___set_errno_internal 79 | 80 | ret 81 | END(_readlinkat) 82 | 83 | ENTRY_PRIVATE(_nanosleep) 84 | mov x8, __NR_nanosleep 85 | svc #0 86 | 87 | cmn x0, #(MAX_ERRNO + 1) 88 | cneg x0, x0, hi 89 | b.hi ___set_errno_internal 90 | 91 | ret 92 | END(_nanosleep) 93 | 94 | ENTRY_PRIVATE(_inotify_init1) 95 | mov x8, __NR_inotify_init1 96 | svc #0 97 | 98 | cmn x0, #(MAX_ERRNO + 1) 99 | cneg x0, x0, hi 100 | b.hi ___set_errno_internal 101 | 102 | ret 103 | END(_inotify_init1) 104 | 105 | ENTRY_PRIVATE(_inotify_add_watch) 106 | mov x8, __NR_inotify_add_watch 107 | svc #0 108 | 109 | cmn x0, #(MAX_ERRNO + 1) 110 | cneg x0, x0, hi 111 | b.hi ___set_errno_internal 112 | 113 | ret 114 | END(_inotify_add_watch) 115 | 116 | ENTRY_PRIVATE(_inotify_rm_watch) 117 | mov x8, __NR_inotify_rm_watch 118 | svc #0 119 | 120 | cmn x0, #(MAX_ERRNO + 1) 121 | cneg x0, x0, hi 122 | b.hi ___set_errno_internal 123 | 124 | ret 125 | END(_inotify_rm_watch) -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/arrays/ArrayAllocator.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file ArrayAllocator.hpp 3 | \brief Internal implementations to create different java arrays. 4 | \author Denis Sorokin 5 | \date 22.02.2016 6 | */ 7 | 8 | #ifndef JH_ARRAY_ALLOCATOR_HPP 9 | #define JH_ARRAY_ALLOCATOR_HPP 10 | 11 | #include 12 | #include "../core/ErrorHandler.hpp" 13 | 14 | namespace jh { 15 | /** 16 | * Stub implementation of java array creation. 17 | */ 18 | template 19 | struct JavaArrayAllocator; 20 | 21 | /** 22 | * Implementation of java boolean array creation. 23 | */ 24 | template 25 | struct JavaArrayAllocator { 26 | static jbooleanArray create(JNIEnv *env, jsize size) { 27 | return env->NewBooleanArray(size); 28 | } 29 | }; 30 | 31 | /** 32 | * Implementation of java int array creation. 33 | */ 34 | template 35 | struct JavaArrayAllocator { 36 | static jintArray create(JNIEnv *env, jsize size) { 37 | return env->NewIntArray(size); 38 | } 39 | }; 40 | 41 | /** 42 | * Implementation of java long array creation. 43 | */ 44 | template 45 | struct JavaArrayAllocator { 46 | static jlongArray create(JNIEnv *env, jsize size) { 47 | return env->NewLongArray(size); 48 | } 49 | }; 50 | 51 | /** 52 | * Implementation of java float array creation. 53 | */ 54 | template 55 | struct JavaArrayAllocator { 56 | static jfloatArray create(JNIEnv *env, jsize size) { 57 | return env->NewFloatArray(size); 58 | } 59 | }; 60 | 61 | /** 62 | * Implementation of java double array creation. 63 | */ 64 | template 65 | struct JavaArrayAllocator { 66 | static jdoubleArray create(JNIEnv *env, jsize size) { 67 | return env->NewDoubleArray(size); 68 | } 69 | }; 70 | 71 | /** 72 | * Implementation of java object array creation. 73 | * 74 | * @param ElementType Type of java object in the array. 75 | */ 76 | template 77 | struct JavaArrayAllocator { 78 | static jobjectArray create(JNIEnv *env, jsize size) { 79 | std::string className = ToJavaType::className(); 80 | 81 | jclass javaClass = env->FindClass(className.c_str()); 82 | if (javaClass == nullptr) { 83 | reportInternalError("class not found [" + className + "]"); 84 | return nullptr; 85 | } 86 | 87 | return env->NewObjectArray(size, javaClass, nullptr); 88 | } 89 | }; 90 | } 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/private/bionic_asm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _PRIVATE_BIONIC_ASM_H_ 30 | #define _PRIVATE_BIONIC_ASM_H_ 31 | 32 | #include /* For system call numbers. */ 33 | 34 | #define MAX_ERRNO 4095 /* For recognizing system call error returns. */ 35 | 36 | #define __bionic_asm_custom_entry(f) 37 | #define __bionic_asm_custom_end(f) 38 | #define __bionic_asm_function_type @function 39 | 40 | #if defined(__aarch64__) 41 | #include "bionic_asm_arm64.h" 42 | #elif defined(__arm__) 43 | #include "bionic_asm_arm.h" 44 | #elif defined(__i386__) 45 | #include "bionic_asm_x86.h" 46 | #elif defined(__x86_64__) 47 | #include "bionic_asm_x86_64.h" 48 | #endif 49 | 50 | #define ENTRY_NO_DWARF(f) \ 51 | .text; \ 52 | .globl f; \ 53 | .balign __bionic_asm_align; \ 54 | .type f, __bionic_asm_function_type; \ 55 | f: \ 56 | __bionic_asm_custom_entry(f); \ 57 | 58 | #define ENTRY(f) \ 59 | ENTRY_NO_DWARF(f) \ 60 | .cfi_startproc \ 61 | 62 | #define END_NO_DWARF(f) \ 63 | .size f, .-f; \ 64 | __bionic_asm_custom_end(f) \ 65 | 66 | #define END(f) \ 67 | .cfi_endproc; \ 68 | END_NO_DWARF(f) \ 69 | 70 | /* Like ENTRY, but with hidden visibility. */ 71 | #define ENTRY_PRIVATE(f) \ 72 | ENTRY(f); \ 73 | .hidden f \ 74 | 75 | /* Like ENTRY_NO_DWARF, but with hidden visibility. */ 76 | #define ENTRY_PRIVATE_NO_DWARF(f) \ 77 | ENTRY_NO_DWARF(f); \ 78 | .hidden f \ 79 | 80 | #define __BIONIC_WEAK_ASM_FOR_NATIVE_BRIDGE(f) \ 81 | .weak f; \ 82 | 83 | #define ALIAS_SYMBOL(alias, original) \ 84 | .globl alias; \ 85 | .equ alias, original 86 | 87 | 88 | 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/core/JNIEnvironment.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JNIEnvironment.cpp 3 | \brief Utilities to get and use JNIEnv* pointer. 4 | \author Denis Sorokin 5 | \date 24.01.2016 6 | */ 7 | 8 | #include 9 | //#include "../../zframework/core/_android/jnienv.h" 10 | #include "../../anti.h" 11 | #include "../core/JNIEnvironment.hpp" 12 | #include "../core/ErrorHandler.hpp" 13 | #include "../calls/StaticCaller.hpp" 14 | #include "../calls/InstanceCaller.hpp" 15 | #include "../utils/JniGlobalRef.hpp" 16 | 17 | 18 | JAVA_CLASS(JavaActivityThread, "android/app/ActivityThread") 19 | 20 | JAVA_CLASS(JavaApplication, "android/app/Application") 21 | 22 | namespace jh { 23 | static JniGlobalRef *globalActivityThread; 24 | static JniGlobalRef *globalApplication; 25 | 26 | static JavaVM *jvm; 27 | 28 | void onLoad(JavaVM *vm) { 29 | jvm = vm; 30 | if (globalActivityThread == nullptr) 31 | globalActivityThread = new JniGlobalRef(); 32 | if (globalApplication == nullptr) 33 | globalApplication = new JniGlobalRef(); 34 | jobject activityThread = jh::callStaticMethod( 35 | "currentActivityThread"); 36 | globalActivityThread->set(activityThread); 37 | jobject application = jh::callMethod(activityThread, "getApplication", 38 | true); 39 | globalApplication->set(application); 40 | loadClassLoader(); 41 | 42 | } 43 | 44 | JavaVM *getJavaVM() { 45 | return jvm; 46 | } 47 | 48 | jobject getCurrentApplication() { 49 | return globalApplication->get(); 50 | } 51 | 52 | JNIEnv *getCurrentJNIEnvironment() { 53 | JNIEnv *env = nullptr; 54 | JavaVM *javaVM = getJavaVM(); 55 | 56 | javaVM->GetEnv((void **) &env, JNI_VERSION_1_6); 57 | 58 | if (env == nullptr) { 59 | reportInternalError("jni environment not found"); 60 | } 61 | 62 | return env; 63 | } 64 | 65 | JNIEnvironmentGuarantee::JNIEnvironmentGuarantee() 66 | : m_threadShouldBeDetached(false) { 67 | JNIEnv *env = nullptr; 68 | JavaVM *javaVM = getJavaVM(); 69 | 70 | int getEnvStatus = javaVM->GetEnv((void **) &env, JNI_VERSION_1_6); 71 | 72 | if (getEnvStatus == JNI_EDETACHED) { 73 | if (javaVM->AttachCurrentThread(&env, nullptr) != 0) { 74 | reportInternalError("couldn't attach current thread to java VM"); 75 | } else { 76 | m_threadShouldBeDetached = true; 77 | // no classes besides the system ones! 78 | // TODO : do something with this 79 | } 80 | } 81 | 82 | if (env == nullptr) { 83 | reportInternalError("couldn't get jni environment for current thread"); 84 | } 85 | } 86 | 87 | JNIEnvironmentGuarantee::~JNIEnvironmentGuarantee() { 88 | if (m_threadShouldBeDetached) { 89 | getJavaVM()->DetachCurrentThread(); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/x86_64.S: -------------------------------------------------------------------------------- 1 | /* Generated by gensyscalls.py. Do not edit. */ 2 | 3 | #include "private/bionic_asm.h" 4 | 5 | ENTRY_PRIVATE(___close) 6 | movl $__NR_close, %eax 7 | syscall 8 | cmpq $-MAX_ERRNO, %rax 9 | jb 1f 10 | negl %eax 11 | movl %eax, %edi 12 | call ___set_errno_internal 13 | 1: 14 | ret 15 | END(___close) 16 | 17 | ENTRY_PRIVATE(_lseek) 18 | movl $__NR_lseek, %eax 19 | syscall 20 | cmpq $-MAX_ERRNO, %rax 21 | jb 1f 22 | negl %eax 23 | movl %eax, %edi 24 | call ___set_errno_internal 25 | 1: 26 | ret 27 | END(_lseek) 28 | 29 | ENTRY_PRIVATE(__openat) 30 | movq %rcx, %r10 31 | movl $__NR_openat, %eax 32 | syscall 33 | cmpq $-MAX_ERRNO, %rax 34 | jb 1f 35 | negl %eax 36 | movl %eax, %edi 37 | call ___set_errno_internal 38 | 1: 39 | ret 40 | END(__openat) 41 | 42 | ENTRY_PRIVATE(_read) 43 | movl $__NR_read, %eax 44 | syscall 45 | cmpq $-MAX_ERRNO, %rax 46 | jb 1f 47 | negl %eax 48 | movl %eax, %edi 49 | call ___set_errno_internal 50 | 1: 51 | ret 52 | END(_read) 53 | 54 | ENTRY_PRIVATE(_write) 55 | movl $__NR_write, %eax 56 | syscall 57 | cmpq $-MAX_ERRNO, %rax 58 | jb 1f 59 | negl %eax 60 | movl %eax, %edi 61 | call ___set_errno_internal 62 | 1: 63 | ret 64 | END(_write) 65 | 66 | 67 | ENTRY_PRIVATE(_ptrace) 68 | movl $__NR_ptrace, %eax 69 | syscall 70 | cmpq $-MAX_ERRNO, %rax 71 | jb 1f 72 | negl %eax 73 | movl %eax, %edi 74 | call ___set_errno_internal 75 | 1: 76 | ret 77 | END(_ptrace) 78 | 79 | ENTRY_PRIVATE(_readlinkat) 80 | movq %rcx, %r10 81 | movl $__NR_readlinkat, %eax 82 | syscall 83 | cmpq $-MAX_ERRNO, %rax 84 | jb 1f 85 | negl %eax 86 | movl %eax, %edi 87 | call ___set_errno_internal 88 | 1: 89 | ret 90 | END(_readlinkat) 91 | 92 | ENTRY_PRIVATE(_nanosleep) 93 | movl $__NR_nanosleep, %eax 94 | syscall 95 | cmpq $-MAX_ERRNO, %rax 96 | jb 1f 97 | negl %eax 98 | movl %eax, %edi 99 | call ___set_errno_internal 100 | 1: 101 | ret 102 | END(_nanosleep) 103 | 104 | ENTRY_PRIVATE(_inotify_init1) 105 | movl $__NR_inotify_init1, %eax 106 | syscall 107 | cmpq $-MAX_ERRNO, %rax 108 | jb 1f 109 | negl %eax 110 | movl %eax, %edi 111 | call ___set_errno_internal 112 | 1: 113 | ret 114 | END(_inotify_init1) 115 | 116 | ENTRY_PRIVATE(_inotify_add_watch) 117 | movl $__NR_inotify_add_watch, %eax 118 | syscall 119 | cmpq $-MAX_ERRNO, %rax 120 | jb 1f 121 | negl %eax 122 | movl %eax, %edi 123 | call ___set_errno_internal 124 | 1: 125 | ret 126 | END(_inotify_add_watch) 127 | 128 | ENTRY_PRIVATE(_inotify_rm_watch) 129 | movl $__NR_inotify_rm_watch, %eax 130 | syscall 131 | cmpq $-MAX_ERRNO, %rax 132 | jb 1f 133 | negl %eax 134 | movl %eax, %edi 135 | call ___set_errno_internal 136 | 1: 137 | ret 138 | END(inotify_rm_watch) -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/calls/ObjectCreation.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file ObjectCreation.hpp 3 | \brief Creation of new java objects from C++ code. 4 | \author Denis Sorokin 5 | \date 24.01.2016 6 | */ 7 | 8 | /** 9 | * Cheat sheet: 10 | * 11 | * @code{.cpp} 12 | * 13 | * // Lets declare custom Java class: 14 | * JH_JAVA_CUSTOM_CLASS(Example, "com/class/path/Example"); 15 | * JH_JAVA_CUSTOM_CLASS(Parameter, "com/class/path/Parameter"); 16 | * 17 | * // Create an object via default constructor (old style / new style): 18 | * jobject first = jh::createNewObject<>(Parameter::className()); 19 | * jobject first_v2 = jh::createNewObject(); 20 | * 21 | * // Create an object via constructor with two arguments (old style / new style): 22 | * jobject second = jh::createNewObject(Example::className(), first, 100); 23 | * jobject second_v2 = jh::createNewObject(first, 100); 24 | * 25 | * @endcode 26 | */ 27 | 28 | #ifndef JH_OBJECT_CREATION_HPP 29 | #define JH_OBJECT_CREATION_HPP 30 | 31 | #include 32 | #include 33 | #include "../core/ToJavaType.hpp" 34 | #include "../core/ErrorHandler.hpp" 35 | #include "../core/JNIEnvironment.hpp" 36 | #include "../core/JavaMethodSignature.hpp" 37 | 38 | namespace jh { 39 | /** 40 | * Allows to create Java objects via their constructors. Constructor argument 41 | * types should be explicitly specified via template arguments. 42 | * 43 | * @param className Java class name as a string. 44 | * @param arguments List of arguments for the constructor. 45 | * @return Create Java object pointer (aka jobject). 46 | */ 47 | template 48 | jobject 49 | createNewObject(std::string className, typename ToJavaType::Type ... arguments) { 50 | JNIEnv *env = getCurrentJNIEnvironment(); 51 | 52 | std::string methodSignature = getJavaMethodSignature(); 53 | 54 | jclass javaClass = env->FindClass(className.c_str()); 55 | if (javaClass == nullptr) { 56 | reportInternalError("class not found [" + className + "]"); 57 | return nullptr; 58 | } 59 | 60 | jmethodID javaConstructor = env->GetMethodID(javaClass, "", methodSignature.c_str()); 61 | if (javaConstructor == nullptr) { 62 | reportInternalError( 63 | "constructor for class [" + className + "] not found, tried signature [" + 64 | methodSignature + "]"); 65 | return nullptr; 66 | } 67 | 68 | jobject result = env->NewObject(javaClass, javaConstructor, arguments...); 69 | 70 | env->DeleteLocalRef(javaClass); 71 | 72 | return result; 73 | } 74 | 75 | /** 76 | * New style of java object creation, where object class is specified 77 | * in the template arguments. 78 | * 79 | * @param arguments List of arguments for the constructor. 80 | * @return Create Java object pointer (aka jobject). 81 | */ 82 | template 83 | jobject createNewObject(typename ToJavaType::Type ... arguments) { 84 | return createNewObject(NewObjectType::className(), arguments...); 85 | } 86 | } 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /anti/src/main/cpp/anti.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "check/anti_frida.h" 6 | #include "check/anti_dual_app.h" 7 | #include "check/anti_xposed.h" 8 | #include "JNIHelper/JNIHelper.hpp" 9 | #include "xposeddetector/xposed.h" 10 | #include "check/anti_mem_dump.h" 11 | #include "check/anti_emulator.h" 12 | 13 | 14 | #define JNI_CLASS_NAME "com/tg/android/anti/NativeLib" 15 | 16 | static jstring anti_frida(JNIEnv *env, jclass clazz) { 17 | jh::JNIEnvironmentGuarantee jniEnvironmentGuarantee; 18 | AntiFrida antiFrida; 19 | antiFrida.check(); 20 | 21 | return jh::createJString("anti frida..."); 22 | } 23 | 24 | static jstring anti_L_xposed(JNIEnv *env, jclass clazz) { 25 | jh::JNIEnvironmentGuarantee jniEnvironmentGuarantee; 26 | AntiXposed antiXposed; 27 | if (antiXposed.get_xposed_status(env, android_get_device_api_level()) == NO_XPOSED) { 28 | return jh::createJString("security"); 29 | } else if (xposed_status == FOUND_XPOSED) { 30 | return jh::createJString("FOUND_XPOSED"); 31 | } else if (xposed_status == ANTIED_XPOSED) { 32 | return jh::createJString("ANTIED_XPOSED"); 33 | } else if (xposed_status == CAN_NOT_ANTI_XPOSED) { 34 | return jh::createJString("CAN_NOT_ANTI_XPOSED"); 35 | } 36 | 37 | } 38 | 39 | static jstring anti_root(JNIEnv *env, jclass clazz) { 40 | return jh::createJString("security"); 41 | } 42 | 43 | static jstring anti_debug(JNIEnv *env, jclass clazz) { 44 | return jh::createJString("security"); 45 | } 46 | 47 | static jstring anti_mem_dump(JNIEnv *env, jclass clazz) { 48 | 49 | std::thread t(AntiMemDump::detect_memory_dump_loop, nullptr); 50 | t.detach(); 51 | 52 | return jh::createJString("anti MemDump..."); 53 | } 54 | 55 | static jstring anti_emulator(JNIEnv *env, jclass clazz) { 56 | AntiEmulator antiEmulator; 57 | 58 | return jh::createJString(antiEmulator.check()); 59 | } 60 | 61 | static jstring anti_dual_app(JNIEnv *env, jclass clazz) { 62 | jh::JNIEnvironmentGuarantee jniEnvironmentGuarantee; 63 | AntiDualApp antiDualApp; 64 | 65 | return jh::createJString(antiDualApp.check()); 66 | } 67 | 68 | 69 | JNIEXPORT jint 70 | 71 | JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { 72 | 73 | jh::onLoad(vm); 74 | 75 | (void) reserved; 76 | 77 | if (__predict_false(nullptr == vm)) return JNI_ERR; 78 | 79 | JNIEnv *env; 80 | if (__predict_false(JNI_OK != vm->GetEnv((void **) &env, JNI_VERSION_1_6))) return JNI_ERR; 81 | if (__predict_false(nullptr == env)) return JNI_ERR; 82 | 83 | jclass cls; 84 | if (__predict_false(nullptr == (cls = env->FindClass(JNI_CLASS_NAME)))) return JNI_ERR; 85 | 86 | JNINativeMethod m[] = 87 | { 88 | {"AntiFrida", "()Ljava/lang/String;", (void *) anti_frida}, 89 | {"AntiXposed", "()Ljava/lang/String;", (void *) anti_L_xposed}, 90 | {"AntiRoot", "()Ljava/lang/String;", (void *) anti_root}, 91 | {"AntiDebug", "()Ljava/lang/String;", (void *) anti_debug}, 92 | {"AntiMemDump", "()Ljava/lang/String;", (void *) anti_mem_dump}, 93 | {"AntiEmulator", "()Ljava/lang/String;", (void *) anti_emulator}, 94 | {"AntiDualApp", "()Ljava/lang/String;", (void *) anti_dual_app}, 95 | }; 96 | 97 | if (__predict_false(0 != env->RegisterNatives(cls, m, sizeof(m) / sizeof(m[0])))) 98 | return JNI_ERR; 99 | 100 | 101 | return JNI_VERSION_1_6; 102 | } -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/armeabi-v7a.S: -------------------------------------------------------------------------------- 1 | /* Generated by gensyscalls.py. Do not edit. */ 2 | 3 | #include "private/bionic_asm.h" 4 | ENTRY_PRIVATE(___close) 5 | mov ip, r7 6 | .cfi_register r7, ip 7 | ldr r7, =__NR_close 8 | swi #0 9 | mov r7, ip 10 | .cfi_restore r7 11 | cmn r0, #(MAX_ERRNO + 1) 12 | bxls lr 13 | neg r0, r0 14 | b ___set_errno_internal 15 | END(___close) 16 | 17 | ENTRY_PRIVATE(_lseek) 18 | mov ip, r7 19 | .cfi_register r7, ip 20 | ldr r7, =__NR_lseek 21 | swi #0 22 | mov r7, ip 23 | .cfi_restore r7 24 | cmn r0, #(MAX_ERRNO + 1) 25 | bxls lr 26 | neg r0, r0 27 | b ___set_errno_internal 28 | END(_lseek) 29 | 30 | ENTRY_PRIVATE(__openat) 31 | mov ip, r7 32 | .cfi_register r7, ip 33 | ldr r7, =__NR_openat 34 | swi #0 35 | mov r7, ip 36 | .cfi_restore r7 37 | cmn r0, #(MAX_ERRNO + 1) 38 | bxls lr 39 | neg r0, r0 40 | b ___set_errno_internal 41 | END(__openat) 42 | 43 | ENTRY_PRIVATE(_read) 44 | mov ip, r7 45 | .cfi_register r7, ip 46 | ldr r7, =__NR_read 47 | swi #0 48 | mov r7, ip 49 | .cfi_restore r7 50 | cmn r0, #(MAX_ERRNO + 1) 51 | bxls lr 52 | neg r0, r0 53 | b ___set_errno_internal 54 | END(_read) 55 | 56 | ENTRY_PRIVATE(_write) 57 | mov ip, r7 58 | .cfi_register r7, ip 59 | ldr r7, =__NR_write 60 | swi #0 61 | mov r7, ip 62 | .cfi_restore r7 63 | cmn r0, #(MAX_ERRNO + 1) 64 | bxls lr 65 | neg r0, r0 66 | b ___set_errno_internal 67 | END(_write) 68 | 69 | ENTRY_PRIVATE(_ptrace) 70 | mov ip, r7 71 | .cfi_register r7, ip 72 | ldr r7, =__NR_ptrace 73 | swi #0 74 | mov r7, ip 75 | .cfi_restore r7 76 | cmn r0, #(MAX_ERRNO + 1) 77 | bxls lr 78 | neg r0, r0 79 | b ___set_errno_internal 80 | END(_write) 81 | 82 | 83 | ENTRY_PRIVATE(_readlinkat) 84 | mov ip, r7 85 | .cfi_register r7, ip 86 | ldr r7, =__NR_readlinkat 87 | swi #0 88 | mov r7, ip 89 | .cfi_restore r7 90 | cmn r0, #(MAX_ERRNO + 1) 91 | bxls lr 92 | neg r0, r0 93 | b ___set_errno_internal 94 | END(_readlinkat) 95 | 96 | ENTRY_PRIVATE(_nanosleep) 97 | mov ip, r7 98 | .cfi_register r7, ip 99 | ldr r7, =__NR_nanosleep 100 | swi #0 101 | mov r7, ip 102 | .cfi_restore r7 103 | cmn r0, #(MAX_ERRNO + 1) 104 | bxls lr 105 | neg r0, r0 106 | b ___set_errno_internal 107 | END(_nanosleep) 108 | 109 | ENTRY_PRIVATE(_inotify_init1) 110 | mov ip, r7 111 | .cfi_register r7, ip 112 | ldr r7, =__NR_inotify_init1 113 | swi #0 114 | mov r7, ip 115 | .cfi_restore r7 116 | cmn r0, #(MAX_ERRNO + 1) 117 | bxls lr 118 | neg r0, r0 119 | b ___set_errno_internal 120 | END(_inotify_init1) 121 | 122 | ENTRY_PRIVATE(_inotify_add_watch) 123 | mov ip, r7 124 | .cfi_register r7, ip 125 | ldr r7, =__NR_inotify_add_watch 126 | swi #0 127 | mov r7, ip 128 | .cfi_restore r7 129 | cmn r0, #(MAX_ERRNO + 1) 130 | bxls lr 131 | neg r0, r0 132 | b ___set_errno_internal 133 | END(_inotify_add_watch) 134 | 135 | ENTRY_PRIVATE(_inotify_rm_watch) 136 | mov ip, r7 137 | .cfi_register r7, ip 138 | ldr r7, =__NR_inotify_rm_watch 139 | swi #0 140 | mov r7, ip 141 | .cfi_restore r7 142 | cmn r0, #(MAX_ERRNO + 1) 143 | bxls lr 144 | neg r0, r0 145 | b ___set_errno_internal 146 | END(_inotify_rm_watch) -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/utils/JavaObjectPointer.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JavaObjectPointer.hpp 3 | \brief RAII class to store jobject reference as a global reference. 4 | \author Denis Sorokin 5 | \date 28.01.2016 6 | */ 7 | 8 | /** 9 | * Cheat sheet: 10 | * 11 | * @code{.cpp} 12 | * 13 | * // Declare two Java object pointers: 14 | * jh::JavaObjectPointer obj; 15 | * jh::JavaObjectPointer obj2; 16 | * 17 | * // Declare some special Java class: 18 | * JH_JAVA_CUSTOM_CLASS(Example, "com/class/path/Example"); 19 | * 20 | * // Can check if pointer holds any jobject: 21 | * if (!obj) 22 | * log("pointer is empty!"); 23 | * 24 | * // Can be assigned from jobject: 25 | * obj = jh::createNewObject(); 26 | * 27 | * // Can be assigned from other JavaObjectPointer: 28 | * obj2 = obj; 29 | * 30 | * // Can be compared: 31 | * if (obj == obj2) 32 | * log("they are the same object"); 33 | * 34 | * // Can be used as an argument in Java calls: 35 | * jh::callStaticMethod("someMethodName", obj); 36 | * 37 | * @endcode 38 | */ 39 | 40 | #ifndef JH_JAVA_OBJECT_POINTER_HPP 41 | #define JH_JAVA_OBJECT_POINTER_HPP 42 | 43 | #include 44 | #include "../core/JNIEnvironment.hpp" 45 | 46 | namespace jh { 47 | /** 48 | * Java object (aka jobject) RAII wrapper that holds jobject as a global Java 49 | * reference. Can be assigned from jobject, casted to jobject and so on. 50 | */ 51 | class JavaObjectPointer { 52 | public: 53 | JavaObjectPointer(); 54 | 55 | JavaObjectPointer(jobject object); 56 | 57 | JavaObjectPointer(const JavaObjectPointer &other); 58 | 59 | ~JavaObjectPointer(); 60 | 61 | JavaObjectPointer &operator=(const jobject other); 62 | 63 | JavaObjectPointer &operator=(const JavaObjectPointer &other); 64 | 65 | JavaObjectPointer &operator=(JavaObjectPointer &&other); 66 | 67 | void release(); 68 | 69 | void reset(jobject object); 70 | 71 | jobject get() const; 72 | 73 | operator jobject() const; 74 | 75 | operator bool() const; 76 | 77 | private: 78 | jobject m_jobjectGlobalReference; 79 | }; 80 | 81 | /** 82 | * Checks if two Java objects (aka jobject) are the same object. 83 | * 84 | * @param lhs One object. 85 | * @param rhs Another object. 86 | * @return True if they are the same object, or false otherwise. 87 | */ 88 | inline bool areEqual(const jobject lhs, const jobject rhs) { 89 | JNIEnv *env = getCurrentJNIEnvironment(); 90 | return env->IsSameObject(lhs, rhs); 91 | } 92 | 93 | /** 94 | * Checks if two Java object wrappers point to the same object. 95 | * 96 | * @param lhs One Java object wrapper. 97 | * @param rhs Another Java object wrapper. 98 | * @return True if both wrappers point to the same object, or false otherwise. 99 | */ 100 | inline bool operator==(const JavaObjectPointer &lhs, const JavaObjectPointer &rhs) { 101 | return areEqual(lhs, rhs); 102 | } 103 | 104 | /** 105 | * Checks if Java object wrapper points to the other Java object. 106 | * 107 | * @param lhs Java object (aka jobject). 108 | * @param rhs Java object wrapper. 109 | * @return True if Java object wrapper points to the other Java object, or false otherwise. 110 | */ 111 | inline bool operator==(const jobject lhs, const JavaObjectPointer &rhs) { 112 | return areEqual(lhs, rhs); 113 | } 114 | 115 | /** 116 | * Checks if Java object wrapper points to the other Java object. 117 | * 118 | * @param lhs Java object wrapper. 119 | * @param rhs Java object (aka jobject). 120 | * @return True if Java object wrapper points to the other Java object, or false otherwise. 121 | */ 122 | inline bool operator==(const JavaObjectPointer &lhs, const jobject rhs) { 123 | return areEqual(lhs, rhs); 124 | } 125 | } 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /anti/src/main/cpp/check/anti_mem_dump.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/10/15. 3 | // 4 | 5 | #include "anti_mem_dump.h" 6 | #include "../JNIHelper/JNIHelper.hpp" 7 | #include "sys/inotify.h" 8 | #include 9 | #include 10 | #include 11 | #include "thread" 12 | 13 | #include "../mini_io/_mini_io.h" 14 | #include "../utils/mylibc.h" 15 | 16 | #define MAX_WATCHERS 100 17 | #define MAX_LENGTH 256 18 | #define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) 19 | #define EVENT_SIZE ( sizeof (struct inotify_event) ) 20 | 21 | static const std::string PROC_SELF_STATUS = "/proc/self/status"; 22 | static const std::string PROC_SELF_PAGEMAP = "/proc/self/pagemap"; 23 | static const std::string PROC_SELF_MEM = "/proc/self/mem"; 24 | static const std::string PROC_MAPS = "/proc/self/maps"; 25 | static const std::string PROC_TASK = "/proc/self/task"; 26 | static const std::string PROC_TASK_MEM = "/proc/self/task/%s/mem"; 27 | static const std::string PROC_TASK_PAGEMAP = "/proc/self/task/%s/pagemap"; 28 | 29 | 30 | void AntiMemDump::detect_memory_dump_loop(void* args) { 31 | struct timespec timereq; 32 | timereq.tv_sec = 1; 33 | timereq.tv_nsec = 0; 34 | 35 | while (1) { 36 | detect_fileaccess_for_debugger_memorydump(); 37 | _nanosleep(&timereq, nullptr); 38 | //std::this_thread::sleep_for(std::chrono::milliseconds(10)); 39 | } 40 | } 41 | 42 | 43 | __attribute__((always_inline)) 44 | inline 45 | void AntiMemDump::detect_fileaccess_for_debugger_memorydump() { 46 | int length, i = 0; 47 | int fd; 48 | int wd[MAX_WATCHERS] = {0,}; 49 | int read_length = 0; 50 | char buffer[EVENT_BUF_LEN]; 51 | fd = _inotify_init1(0); 52 | 53 | 54 | if (fd > 0) { 55 | 56 | wd[i++] = _inotify_add_watch(fd, PROC_SELF_PAGEMAP.c_str(), IN_ACCESS | IN_OPEN); 57 | wd[i++] = _inotify_add_watch(fd, PROC_SELF_MEM.c_str(), IN_ACCESS | IN_OPEN); 58 | wd[i++] = _inotify_add_watch(fd, PROC_MAPS.c_str(), IN_ACCESS | IN_OPEN); 59 | 60 | DIR *dir = opendir(PROC_TASK.c_str()); 61 | 62 | if (dir != NULL) { 63 | struct dirent *entry = NULL; 64 | while ((entry = readdir(dir)) != NULL) { 65 | char memPath[MAX_LENGTH] = ""; 66 | char pagemapPath[MAX_LENGTH] = ""; 67 | 68 | if (0 == my_strcmp(entry->d_name, ".") || 0 == my_strcmp(entry->d_name, "..")) { 69 | continue; 70 | } 71 | snprintf(memPath, sizeof(memPath), PROC_SELF_MEM.c_str(), entry->d_name); 72 | snprintf(pagemapPath, sizeof(pagemapPath), PROC_TASK_PAGEMAP.c_str(), 73 | entry->d_name); 74 | wd[i++] = _inotify_add_watch(fd, memPath, IN_ACCESS | IN_OPEN); 75 | wd[i++] = _inotify_add_watch(fd, pagemapPath, IN_ACCESS | IN_OPEN); 76 | } 77 | 78 | closedir(dir); 79 | } 80 | 81 | length = read(fd, buffer, EVENT_BUF_LEN); 82 | 83 | if (length > 0) { 84 | while (read_length < length) { 85 | struct inotify_event *event = (struct inotify_event *) buffer + read_length; 86 | 87 | if (event->mask & IN_ACCESS) { 88 | crash(0x3d5f); 89 | } else if (event->mask * IN_OPEN) { 90 | crash(0x9a3b); 91 | } 92 | 93 | read_length += EVENT_SIZE + event->len; 94 | } 95 | } 96 | 97 | for (int j = 0; j < i; j++) { 98 | if (wd[j] != 0) { 99 | _inotify_rm_watch(fd, wd[j]); 100 | } 101 | } 102 | close(fd); 103 | } else { 104 | 105 | } 106 | } 107 | 108 | __attribute__((always_inline)) 109 | inline 110 | int AntiMemDump::crash(int randomval) { 111 | volatile unsigned int *p = &gpCrash; 112 | p += randomval; 113 | p += *p + randomval; 114 | 115 | p = 0; 116 | p += *p; 117 | 118 | return *p; 119 | } 120 | -------------------------------------------------------------------------------- /anti/src/main/cpp/utils/mylibc.h: -------------------------------------------------------------------------------- 1 | #ifndef DETECTDEBUGGER_MYLIBC_H 2 | #define DETECTDEBUGGER_MYLIBC_H 3 | 4 | /* 5 | * These functions are copied from glibc, android libc, apple libc open source code. 6 | * This is to avoid easy bypass through libc functions 7 | */ 8 | 9 | __attribute__((always_inline)) 10 | static inline size_t 11 | my_strlcpy(char *dst, const char *src, size_t siz) { 12 | char *d = dst; 13 | const char *s = src; 14 | size_t n = siz; 15 | /* Copy as many bytes as will fit */ 16 | if (n != 0) { 17 | while (--n != 0) { 18 | if ((*d++ = *s++) == '\0') 19 | break; 20 | } 21 | } 22 | /* Not enough room in dst, add NUL and traverse rest of src */ 23 | if (n == 0) { 24 | if (siz != 0) 25 | *d = '\0'; /* NUL-terminate dst */ 26 | while (*s++); 27 | } 28 | return (s - src - 1); /* count does not include NUL */ 29 | } 30 | 31 | __attribute__((always_inline)) 32 | static inline 33 | size_t my_strlen(const char *s) { 34 | size_t len = 0; 35 | while (*s++) len++; 36 | return len; 37 | } 38 | 39 | __attribute__((always_inline)) 40 | static inline int 41 | my_strncmp(const char *s1, const char *s2, size_t n) { 42 | if (n == 0) 43 | return (0); 44 | do { 45 | if (*s1 != *s2++) 46 | return (*(unsigned char *) s1 - *(unsigned char *) --s2); 47 | if (*s1++ == 0) 48 | break; 49 | } while (--n != 0); 50 | return (0); 51 | } 52 | 53 | __attribute__((always_inline)) 54 | static inline char * 55 | my_strstr(const char *s, const char *find) { 56 | char c, sc; 57 | size_t len; 58 | 59 | if ((c = *find++) != '\0') { 60 | len = my_strlen(find); 61 | do { 62 | do { 63 | if ((sc = *s++) == '\0') 64 | return (NULL); 65 | } while (sc != c); 66 | } while (my_strncmp(s, find, len) != 0); 67 | s--; 68 | } 69 | return ((char *) s); 70 | } 71 | 72 | __attribute__((always_inline)) 73 | static inline 74 | void *my_memset(void *dst, int c, size_t n) { 75 | char *q = (char *) dst; 76 | char *end = q + n; 77 | for (;;) { 78 | if (q >= end) break; 79 | *q++ = (char) c; 80 | if (q >= end) break; 81 | *q++ = (char) c; 82 | if (q >= end) break; 83 | *q++ = (char) c; 84 | if (q >= end) break; 85 | *q++ = (char) c; 86 | } 87 | return dst; 88 | } 89 | 90 | __attribute__((always_inline)) 91 | static inline int 92 | my_strcmp(const char *s1, const char *s2) { 93 | while (*s1 == *s2++) 94 | if (*s1++ == 0) 95 | return (0); 96 | return (*(unsigned char *) s1 - *(unsigned char *) --s2); 97 | } 98 | 99 | __attribute__((always_inline)) 100 | static inline int my_atoi(const char *s) { 101 | int n = 0, neg = 0; 102 | while (isspace(*s)) s++; 103 | switch (*s) { 104 | case '-': 105 | neg = 1; 106 | case '+': 107 | s++; 108 | } 109 | /* Compute n as a negative number to avoid overflow on INT_MIN */ 110 | while (isdigit(*s)) 111 | n = 10 * n - (*s++ - '0'); 112 | return neg ? n : -n; 113 | } 114 | 115 | __attribute__((always_inline)) 116 | char * 117 | my_strtok_r(char *s, const char *delim, char **last) { 118 | char *spanp; 119 | int c, sc; 120 | char *tok; 121 | if (s == NULL && (s = *last) == NULL) 122 | return (NULL); 123 | /* 124 | * Skip (span) leading delimiters (s += strspn(s, delim), sort of). 125 | */ 126 | cont: 127 | c = *s++; 128 | for (spanp = (char *) delim; (sc = *spanp++) != 0;) { 129 | if (c == sc) 130 | goto cont; 131 | } 132 | if (c == 0) { /* no non-delimiter characters */ 133 | *last = NULL; 134 | return (NULL); 135 | } 136 | tok = s - 1; 137 | /* 138 | * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). 139 | * Note that delim must have one NUL; we stop if we see that, too. 140 | */ 141 | for (;;) { 142 | c = *s++; 143 | spanp = (char *) delim; 144 | do { 145 | if ((sc = *spanp++) == c) { 146 | if (c == 0) 147 | s = NULL; 148 | else 149 | s[-1] = 0; 150 | *last = s; 151 | return (tok); 152 | } 153 | } while (sc != 0); 154 | } 155 | /* NOTREACHED */ 156 | } 157 | 158 | 159 | #endif //DETECTDEBUGGER_MYLIBC_H -------------------------------------------------------------------------------- /anti/src/main/cpp/xposeddetector/classloader.cpp: -------------------------------------------------------------------------------- 1 | #include "classloader.h" 2 | #include "../JNIHelper/JNIHelper.hpp" 3 | #include "art.h" 4 | #include "plt.h" 5 | #include "xposed.h" 6 | #include "hash.h" 7 | #include "Utils.h" 8 | 9 | jobject newLocalRef(JNIEnv *env, void *object) { 10 | static jobject (*NewLocalRef)(JNIEnv *, void *) = nullptr; 11 | if (object == nullptr) { 12 | return nullptr; 13 | } 14 | if (NewLocalRef == nullptr) { 15 | NewLocalRef = (jobject (*)(JNIEnv *, void *)) plt_dlsym( 16 | "_ZN3art9JNIEnvExt11NewLocalRefEPNS_6mirror6ObjectE", nullptr); 17 | //LOGD("NewLocalRef: %p", NewLocalRef); 18 | } 19 | if (NewLocalRef != nullptr) { 20 | return NewLocalRef(env, object); 21 | } else { 22 | return nullptr; 23 | } 24 | } 25 | 26 | void deleteLocalRef(JNIEnv *env, jobject object) { 27 | static void (*DeleteLocalRef)(JNIEnv *, jobject) = nullptr; 28 | if (DeleteLocalRef == nullptr) { 29 | DeleteLocalRef = (void (*)(JNIEnv *, jobject)) plt_dlsym( 30 | "_ZN3art9JNIEnvExt14DeleteLocalRefEP8_jobject", nullptr); 31 | //LOGD("DeleteLocalRef: %p", DeleteLocalRef); 32 | } 33 | if (DeleteLocalRef != nullptr) { 34 | DeleteLocalRef(env, object); 35 | } 36 | } 37 | 38 | class ClassLoaderVisitor : public art::SingleRootVisitor { 39 | public: 40 | ClassLoaderVisitor(C_JNIEnv *env, jclass classLoader) : env_(env), classLoader_(classLoader) { 41 | 42 | } 43 | 44 | void VisitRoot(art::mirror::Object *root, const art::RootInfo &info ATTRIBUTE_UNUSED) final { 45 | LOGE("in VisitRoot"); 46 | jobject object = newLocalRef((JNIEnv *) env_, (jobject) root); 47 | if (object != nullptr) { 48 | LOGE("in VisitRoot object != nullptr"); 49 | if ((*env_)->IsInstanceOf((JNIEnv *) env_, object, classLoader_)) { 50 | xposed::doAntiXposed(env_, object, (intptr_t) root); 51 | } 52 | deleteLocalRef((JNIEnv *) env_, object); 53 | } 54 | } 55 | 56 | private: 57 | C_JNIEnv *env_; 58 | jclass classLoader_; 59 | }; 60 | 61 | void classloader::checkGlobalRef(C_JNIEnv *env, jclass clazz) { 62 | auto VisitRoots = (void (*)(void *, void *)) plt_dlsym( 63 | "_ZN3art9JavaVMExt10VisitRootsEPNS_11RootVisitorE", nullptr); 64 | 65 | if (VisitRoots == nullptr) { 66 | return; 67 | } 68 | JavaVM *jvm; 69 | (*env)->GetJavaVM((JNIEnv *) env, &jvm); 70 | ClassLoaderVisitor visitor(env, clazz); 71 | VisitRoots(jvm, &visitor); 72 | } 73 | 74 | class WeakClassLoaderVisitor : public art::IsMarkedVisitor { 75 | public: 76 | WeakClassLoaderVisitor(C_JNIEnv *env, jclass classLoader) : env_(env), 77 | classLoader_(classLoader) { 78 | } 79 | 80 | art::mirror::Object *IsMarked(art::mirror::Object *obj) override { 81 | LOGE("in IsMarked"); 82 | jobject object = newLocalRef((JNIEnv *) env_, (jobject) obj); 83 | if (object != nullptr) { 84 | LOGE("in IsMarked object != nullptr"); 85 | if ((*env_)->IsInstanceOf((JNIEnv *) env_, object, classLoader_)) { 86 | xposed::doAntiXposed(env_, object, (intptr_t) obj); 87 | } 88 | deleteLocalRef((JNIEnv *) env_, object); 89 | } 90 | return obj; 91 | } 92 | 93 | private: 94 | C_JNIEnv *env_; 95 | jclass classLoader_; 96 | }; 97 | 98 | void classloader::checkWeakGlobalRef(C_JNIEnv *env, jclass clazz) { 99 | auto SweepJniWeakGlobals = (void (*)(void *, void *)) plt_dlsym( 100 | "_ZN3art9JavaVMExt19SweepJniWeakGlobalsEPNS_15IsMarkedVisitorE", nullptr); 101 | if (SweepJniWeakGlobals == nullptr) { 102 | return; 103 | } 104 | JavaVM *jvm; 105 | (*env)->GetJavaVM((JNIEnv *) env, &jvm); 106 | WeakClassLoaderVisitor visitor(env, clazz); 107 | SweepJniWeakGlobals(jvm, &visitor); 108 | } 109 | 110 | void classloader::checkClassLoader(C_JNIEnv *env, int sdk) { 111 | if (sdk < 21) { 112 | return; 113 | } 114 | 115 | jclass clazz = (*env)->FindClass((JNIEnv *) env, "dalvik/system/BaseDexClassLoader"); 116 | if ((*env)->ExceptionCheck((JNIEnv *) env)) { 117 | (*env)->ExceptionClear((JNIEnv *) env); 118 | } 119 | 120 | if (clazz == nullptr) { 121 | return; 122 | } 123 | 124 | checkGlobalRef(env, clazz); 125 | checkWeakGlobalRef(env, clazz); 126 | 127 | clear(); 128 | (*env)->DeleteLocalRef((JNIEnv *) env, clazz); 129 | 130 | } -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/arrays/ArrayGetter.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file ArrayGetter.hpp 3 | \brief Internal implementation of getting elements from java arrays. 4 | \author Denis Sorokin 5 | \date 22.02.2016 6 | */ 7 | 8 | #ifndef JH_ARRAY_GETTER_HPP 9 | #define JH_ARRAY_GETTER_HPP 10 | 11 | #include 12 | #include 13 | 14 | namespace jh { 15 | /** 16 | * Stub implementations for getting elements from java arrays. 17 | */ 18 | template 19 | struct JavaArrayGetter; 20 | 21 | /** 22 | * Implementations for getting elements from java boolean arrays. 23 | */ 24 | template<> 25 | struct JavaArrayGetter { 26 | static std::vector get(JNIEnv *env, jbooleanArray array) { 27 | jint size = env->GetArrayLength(array); 28 | jboolean *elements = env->GetBooleanArrayElements(array, nullptr); 29 | 30 | std::vector result(static_cast(size)); 31 | for (int i = 0; i < size; ++i) { 32 | result[i] = elements[i]; 33 | } 34 | 35 | env->ReleaseBooleanArrayElements(array, elements, JNI_ABORT); 36 | 37 | return std::move(result); 38 | } 39 | }; 40 | 41 | /** 42 | * Implementations for getting elements from java int arrays. 43 | */ 44 | template<> 45 | struct JavaArrayGetter { 46 | static std::vector get(JNIEnv *env, jintArray array) { 47 | jint size = env->GetArrayLength(array); 48 | jint *elements = env->GetIntArrayElements(array, nullptr); 49 | 50 | std::vector result(static_cast(size)); 51 | for (int i = 0; i < size; ++i) { 52 | result[i] = elements[i]; 53 | } 54 | 55 | env->ReleaseIntArrayElements(array, elements, JNI_ABORT); 56 | 57 | return std::move(result); 58 | } 59 | }; 60 | 61 | /** 62 | * Implementations for getting elements from java long arrays. 63 | */ 64 | template<> 65 | struct JavaArrayGetter { 66 | static std::vector get(JNIEnv *env, jlongArray array) { 67 | jint size = env->GetArrayLength(array); 68 | jlong *elements = env->GetLongArrayElements(array, nullptr); 69 | 70 | std::vector result(static_cast(size)); 71 | for (int i = 0; i < size; ++i) { 72 | result[i] = elements[i]; 73 | } 74 | 75 | env->ReleaseLongArrayElements(array, elements, JNI_ABORT); 76 | 77 | return std::move(result); 78 | } 79 | }; 80 | 81 | /** 82 | * Implementations for getting elements from java float arrays. 83 | */ 84 | template<> 85 | struct JavaArrayGetter { 86 | static std::vector get(JNIEnv *env, jfloatArray array) { 87 | jint size = env->GetArrayLength(array); 88 | jfloat *elements = env->GetFloatArrayElements(array, nullptr); 89 | 90 | std::vector result(static_cast(size)); 91 | for (int i = 0; i < size; ++i) { 92 | result[i] = elements[i]; 93 | } 94 | 95 | env->ReleaseFloatArrayElements(array, elements, JNI_ABORT); 96 | 97 | return std::move(result); 98 | } 99 | }; 100 | 101 | /** 102 | * Implementations for getting elements from java double arrays. 103 | */ 104 | template<> 105 | struct JavaArrayGetter { 106 | static std::vector get(JNIEnv *env, jdoubleArray array) { 107 | jint size = env->GetArrayLength(array); 108 | jdouble *elements = env->GetDoubleArrayElements(array, nullptr); 109 | 110 | std::vector result(static_cast(size)); 111 | for (int i = 0; i < size; ++i) { 112 | result[i] = elements[i]; 113 | } 114 | 115 | env->ReleaseDoubleArrayElements(array, elements, JNI_ABORT); 116 | 117 | return std::move(result); 118 | } 119 | }; 120 | 121 | /** 122 | * Implementations for getting elements from java object arrays. 123 | */ 124 | template<> 125 | struct JavaArrayGetter { 126 | static std::vector get(JNIEnv *env, jobjectArray array) { 127 | jint size = env->GetArrayLength(array); 128 | 129 | std::vector result(static_cast(size)); 130 | for (int i = 0; i < size; ++i) { 131 | result[i] = env->GetObjectArrayElement(array, i); 132 | } 133 | 134 | return std::move(result); 135 | } 136 | }; 137 | } 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/utils/LocalReferenceFrame.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file LocalReferenceFrame.hpp 3 | \brief Class to clear local java references. 4 | \author Denis Sorokin 5 | \date 21.02.2016 6 | */ 7 | 8 | /** 9 | * Cheat sheet: 10 | * 11 | * @code{.cpp} 12 | * 13 | * // String s1 is created BEFORE the local frame creation: 14 | * jstring s1 = jh::createJString("s1"); 15 | * 16 | * // Local frame creation: 17 | * jh::LocalReferenceFrame frame; 18 | * 19 | * // String s2 is created AFTER the local frame creation: 20 | * jstring s2 = jh::createJString("s2"); 21 | * 22 | * // Both strings are valid now; lets pop the frame: 23 | * frame.pop(); 24 | * 25 | * // String s1 is fine now, but string s2 is dead; you shouldn't use it! 26 | * // Lets recreate the frame and string s2: 27 | * frame.push(); 28 | * s2 = jh::createJString("s2"); 29 | * 30 | * // Both strings are again alive. 31 | * // Now lets pop the frame, but leave the string s2 alive: 32 | * frame.pop(&s2); 33 | * 34 | * // Both strings are still alive! 35 | * log(jh::jstringToStdString(s1) + jh::jstringToStdString(s2)); 36 | * 37 | * @endcode 38 | */ 39 | 40 | #ifndef JH_LOCAL_REFERENCE_FRAME_HPP 41 | #define JH_LOCAL_REFERENCE_FRAME_HPP 42 | 43 | #include 44 | #include "../core/JNIEnvironment.hpp" 45 | 46 | namespace jh { 47 | /** 48 | * Class that can automatically clear all created local java references. 49 | */ 50 | class LocalReferenceFrame { 51 | public: 52 | /** 53 | * Creates local frame with a capacity of 'frameSize' references. Default is 16. 54 | */ 55 | LocalReferenceFrame(int frameSize = 16) 56 | : m_frameSize(frameSize), m_framesCount(0) { 57 | push(); 58 | } 59 | 60 | /** 61 | * Pops all the created local frames. 62 | */ 63 | ~LocalReferenceFrame() { 64 | while (pop()); 65 | } 66 | 67 | /** 68 | * Pushes yet another local frame. The next pop() call will free only 69 | * the references created after this call and before the pop() call. 70 | * 71 | * @return True if new frame was sucessfully created and false otherwise. 72 | */ 73 | bool push() { 74 | JNIEnv *env = getCurrentJNIEnvironment(); 75 | 76 | if (env->PushLocalFrame(m_frameSize) == 0) { 77 | ++m_framesCount; 78 | return true; 79 | } 80 | 81 | return false; 82 | } 83 | 84 | /** 85 | * Pops the local frame if there is any and clears all local references 86 | * that were created after the previous push() call (or the object creation) 87 | * and before this moment. If there is no active local frame does nothing. 88 | * 89 | * @return True if there was an active local frame and it was poped. False otherwise. 90 | */ 91 | bool pop() { 92 | return pop < jobject > (nullptr); 93 | } 94 | 95 | /** 96 | * Pops the local frame if there is any and clears all local references 97 | * that were created after the previous push() call (or the object creation) 98 | * and before this moment. If there is no active local frame does nothing. 99 | * 100 | * This method also preserves one local reference from the active local frame 101 | * and updates it's pointer so it remains valid. 102 | * 103 | * @param jobjectToKeep A pointer to the jobject pointer that should be preserved after local frame destruction. 104 | * @return True if there was an active local frame and it was poped. False otherwise. 105 | */ 106 | template 107 | bool pop(JObjectCastable *jobjectToKeep) { 108 | if (m_framesCount) { 109 | JNIEnv *env = getCurrentJNIEnvironment(); 110 | 111 | if (jobjectToKeep) { 112 | *jobjectToKeep = static_cast(env->PopLocalFrame( 113 | *jobjectToKeep)); 114 | } else { 115 | env->PopLocalFrame(nullptr); 116 | } 117 | 118 | --m_framesCount; 119 | 120 | return true; 121 | } 122 | 123 | return false; 124 | } 125 | 126 | private: 127 | /** 128 | * The size of created frames. 129 | */ 130 | int m_frameSize; 131 | 132 | /** 133 | * The number of active local frames. 134 | */ 135 | int m_framesCount; 136 | 137 | /** 138 | * Local frame should not be copied. 139 | */ 140 | LocalReferenceFrame(const LocalReferenceFrame &) = delete; 141 | 142 | void operator=(const LocalReferenceFrame &) = delete; 143 | }; 144 | } 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /anti/src/main/cpp/check/anti_frida.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by tg on 2022/9/3. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "anti_frida.h" 12 | #include "../mini_io/_mini_io.h" 13 | 14 | 15 | void AntiFrida::check() { 16 | char *libc_path = nullptr; 17 | int page_size = getpagesize(); 18 | uint64_t start = frida_find_library_base("libc", &libc_path); 19 | 20 | if (start != 0 && nullptr != libc_path && strlen(libc_path) > 0) { 21 | uint64_t base = frida_find_library_space_base(start, page_size); 22 | 23 | if (base != 0) { 24 | int fd = _open(libc_path, O_RDONLY); 25 | 26 | if (fd > 0) { 27 | void *p = mmap((void *) base, page_size, PROT_READ, MAP_PRIVATE, fd, 0); 28 | close(fd); 29 | 30 | if (p != MAP_FAILED) { 31 | uint64_t start2 = frida_find_library_base("libc", nullptr); 32 | } else { 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | bool str_has_prefix(const char *str1, const char *str2) { 40 | const char *x = strstr(str1, str2); 41 | return x == str1; 42 | } 43 | 44 | // copy from https://github.com/frida/frida-core/blob/836d254614d836e39d17418e3b864c8b5862bf9b/src/linux/frida-helper-backend-glue.c#L3014 45 | uint64_t AntiFrida::frida_find_library_base(std::string library_name, char **library_path) { 46 | uint64_t result = 0; 47 | std::string maps_path = "/proc/self/maps"; 48 | const std::size_t line_size = 1024 + PATH_MAX; 49 | char *line, *path; 50 | 51 | if (nullptr != library_path) { 52 | *library_path = nullptr; 53 | } 54 | 55 | FILE *fp = fopen(maps_path.c_str(), "r"); 56 | 57 | line = static_cast(malloc(line_size)); 58 | path = static_cast(malloc(PATH_MAX)); 59 | 60 | while (result == 0 && fgets(line, line_size, fp) != nullptr) { 61 | uint64_t start; 62 | int n = 0; 63 | 64 | path[0] = 0; 65 | n = sscanf(line, "%" 66 | PRIx64 67 | "-%*x %*s %*x %*s %*s %s", &start, path); 68 | 69 | if (n != 2) { 70 | continue; 71 | } 72 | 73 | if (n == 1) { 74 | continue; 75 | } 76 | 77 | if (path[0] == '[') { 78 | continue; 79 | } 80 | 81 | if (strcmp(path, library_name.c_str()) == 0) { 82 | result = start; 83 | if (library_path != nullptr) { 84 | *library_path = strdup(path); 85 | } 86 | } else { 87 | char *p = strrchr(path, '/'); 88 | if (p != nullptr) { 89 | p++; 90 | if (str_has_prefix(p, library_name.c_str()) && strstr(p, ".so")) { 91 | char next_char = p[library_name.size()]; 92 | if (next_char == '-' || next_char == '.') { 93 | result = start; 94 | if (library_path != nullptr) { 95 | *library_path = strdup(path); 96 | } 97 | } 98 | } 99 | } 100 | } 101 | } 102 | 103 | free(path); 104 | path = nullptr; 105 | free(line); 106 | line = nullptr; 107 | 108 | fclose(fp); 109 | fp = nullptr; 110 | 111 | return result; 112 | } 113 | 114 | uint64_t AntiFrida::frida_find_library_space_base(uint64_t base, uint32_t page_size) { 115 | std::string map_path = "/proc/self/maps"; 116 | const std::size_t line_size = 1024 + 1024; 117 | char *line; 118 | 119 | FILE *fp = fopen(map_path.c_str(), "r"); 120 | 121 | line = static_cast(malloc(line_size)); 122 | 123 | uint64_t last_end = 0; 124 | 125 | while (fgets(line, line_size, fp) != nullptr) { 126 | uint64_t start, end; 127 | int n = 0; 128 | 129 | n = sscanf(line, "%" 130 | PRIx64 131 | "-%" 132 | PRIx64 133 | "", &start, &end); 134 | 135 | if (n != 2) { 136 | continue; 137 | } 138 | 139 | if (last_end == 0 && start == base) { 140 | last_end = start - page_size; 141 | continue; 142 | } 143 | 144 | if (last_end == 0) { 145 | last_end = end; 146 | continue; 147 | } 148 | 149 | if (start >= base) { 150 | last_end = 0; 151 | break; 152 | } 153 | 154 | if (start - page_size < last_end) { 155 | last_end = end; 156 | continue; 157 | } 158 | 159 | break; 160 | } 161 | 162 | free(line); 163 | line = nullptr; 164 | 165 | fclose(fp); 166 | fp = nullptr; 167 | 168 | return last_end; 169 | } 170 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/calls/InstanceCaller.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file InstanceCaller.hpp 3 | \brief A utility to call java methods of a specific objects. 4 | \author Denis Sorokin 5 | \date 24.01.2016 6 | */ 7 | 8 | /** 9 | * Cheat sheet: 10 | * 11 | * @code{.cpp} 12 | * 13 | * // Lets assume that we already have some Java object 14 | * jobject someObject = ...; 15 | * 16 | * // Calling void method without arguments: 17 | * jh::callMethod(someObject, "voidMethodName"); 18 | * 19 | * // Calling int method with two arguments: 20 | * int sum = jh::callMethod(someObject, "sumMethod", 4, 5); 21 | * 22 | * // Calling factory method that returns some custom Java object: 23 | * JH_JAVA_CUSTOM_CLASS(Example, "com/class/path/Example"); 24 | * jobject newObject = jh::callMethod(someObject, "factoryMethodName", 3.1415); 25 | * 26 | * @endcode 27 | */ 28 | 29 | #ifndef JH_INSTANCE_CALLER_HPP 30 | #define JH_INSTANCE_CALLER_HPP 31 | 32 | #include 33 | #include 34 | #include "../core/ErrorHandler.hpp" 35 | #include "../core/JNIEnvironment.hpp" 36 | #include "../core/JavaMethodSignature.hpp" 37 | 38 | namespace jh { 39 | /** 40 | * Class that can call methods which return java objects. 41 | */ 42 | template 43 | struct InstanceCaller { 44 | static jobject 45 | call(JNIEnv *env, jobject instance, jmethodID javaMethod, ArgumentTypes ... arguments) { 46 | return env->CallObjectMethod(instance, javaMethod, arguments...); 47 | } 48 | }; 49 | 50 | /** 51 | * Class that can call methods which doesn't return anything. 52 | */ 53 | template 54 | struct InstanceCaller { 55 | static void 56 | call(JNIEnv *env, jobject instance, jmethodID javaMethod, ArgumentTypes ... arguments) { 57 | env->CallVoidMethod(instance, javaMethod, arguments...); 58 | } 59 | }; 60 | 61 | /** 62 | * Class that can call methods which return jboolean values. 63 | */ 64 | template 65 | struct InstanceCaller { 66 | static jboolean 67 | call(JNIEnv *env, jobject instance, jmethodID javaMethod, ArgumentTypes ... arguments) { 68 | return env->CallBooleanMethod(instance, javaMethod, arguments...); 69 | } 70 | }; 71 | 72 | /** 73 | * Class that can call methods which return jint values. 74 | */ 75 | template 76 | struct InstanceCaller { 77 | static jint 78 | call(JNIEnv *env, jobject instance, jmethodID javaMethod, ArgumentTypes ... arguments) { 79 | return env->CallIntMethod(instance, javaMethod, arguments...); 80 | } 81 | }; 82 | 83 | /** 84 | * Class that can call methods which return jlong values. 85 | */ 86 | template 87 | struct InstanceCaller { 88 | static jlong 89 | call(JNIEnv *env, jobject instance, jmethodID javaMethod, ArgumentTypes ... arguments) { 90 | return env->CallLongMethod(instance, javaMethod, arguments...); 91 | } 92 | }; 93 | 94 | /** 95 | * Class that can call methods which return jfloat values. 96 | */ 97 | template 98 | struct InstanceCaller { 99 | static jfloat 100 | call(JNIEnv *env, jobject instance, jmethodID javaMethod, ArgumentTypes ... arguments) { 101 | return env->CallFloatMethod(instance, javaMethod, arguments...); 102 | } 103 | }; 104 | 105 | /** 106 | * Class that can call methods which return jdouble values. 107 | */ 108 | template 109 | struct InstanceCaller { 110 | static jdouble 111 | call(JNIEnv *env, jobject instance, jmethodID javaMethod, ArgumentTypes ... arguments) { 112 | return env->CallDoubleMethod(instance, javaMethod, arguments...); 113 | } 114 | }; 115 | 116 | /** 117 | * Calls a method of some Java object instance. Programmer should explicitly 118 | * specify the return type and argument types via template arguments. 119 | * 120 | * @param instance Java object (jobject) 121 | * @param methodName Method name as string. 122 | * @param arguments List of arguments to the java method call. 123 | * @return Some value of ReturnType type returned by the specified method. 124 | */ 125 | template 126 | typename ToJavaType::Type 127 | callMethod(jobject instance, std::string methodName, bool autoClearException, 128 | typename ToJavaType::Type ... arguments) { 129 | using RealReturnType = typename ToJavaType::Type; 130 | if (instance == nullptr) 131 | return RealReturnType(); 132 | JNIEnv *env = getCurrentJNIEnvironment(); 133 | 134 | std::string methodSignature = getJavaMethodSignature(); 135 | 136 | jclass javaClass = env->GetObjectClass(instance); 137 | if (javaClass == nullptr) { 138 | reportInternalError("class for java object instance not found"); 139 | return RealReturnType(); 140 | } 141 | 142 | jmethodID javaMethod = env->GetMethodID(javaClass, methodName.c_str(), 143 | methodSignature.c_str()); 144 | if (javaMethod == nullptr) { 145 | reportInternalError("method [" + methodName + 146 | "] for java object instance not found, tried signature [" + 147 | methodSignature + "]"); 148 | return RealReturnType(); 149 | } 150 | 151 | return static_cast(InstanceCaller::CallReturnType, typename ToJavaType::Type ...>::call( 152 | env, instance, javaMethod, arguments...)); 153 | } 154 | } 155 | 156 | #endif 157 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 31 | 32 | 33 | 34 | 35 | 43 | 44 | 52 | 53 | 54 | 55 | 56 | 64 | 65 | 73 | 74 | 75 | 76 | 77 | 85 | 86 | 94 | 95 | 96 | 97 | 98 | 106 | 107 | 115 | 116 | 117 | 118 | 119 | 120 | 128 | 129 | 137 | 138 | 139 | 140 | 141 | 149 | 150 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /anti/src/main/cpp/xposeddetector/art.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifndef NDEBUG 6 | #define ALWAYS_INLINE 7 | #else 8 | #define ALWAYS_INLINE __attribute__ ((always_inline)) 9 | #endif 10 | 11 | #define DCHECK(...) 12 | 13 | #define OVERRIDE override 14 | 15 | #define ATTRIBUTE_UNUSED __attribute__((__unused__)) 16 | 17 | #define REQUIRES_SHARED(...) 18 | 19 | #define MANAGED PACKED(4) 20 | #define PACKED(x) __attribute__ ((__aligned__(x), __packed__)) 21 | 22 | namespace art { 23 | 24 | namespace mirror { 25 | 26 | class Object { 27 | 28 | }; 29 | 30 | template 31 | class ObjPtr { 32 | 33 | public: 34 | MirrorType *Ptr() const { 35 | return nullptr; 36 | } 37 | 38 | }; 39 | 40 | template 41 | class PtrCompression { 42 | public: 43 | // Compress reference to its bit representation. 44 | static uint32_t Compress(MirrorType *mirror_ptr) { 45 | uintptr_t as_bits = reinterpret_cast(mirror_ptr); 46 | return static_cast(kPoisonReferences ? -as_bits : as_bits); 47 | } 48 | 49 | // Uncompress an encoded reference from its bit representation. 50 | static MirrorType *Decompress(uint32_t ref) { 51 | uintptr_t as_bits = kPoisonReferences ? -ref : ref; 52 | return reinterpret_cast(as_bits); 53 | } 54 | 55 | // Convert an ObjPtr to a compressed reference. 56 | static uint32_t Compress(ObjPtr ptr) REQUIRES_SHARED(Locks::mutator_lock_) { 57 | return Compress(ptr.Ptr()); 58 | } 59 | }; 60 | 61 | 62 | // Value type representing a reference to a mirror::Object of type MirrorType. 63 | template 64 | class MANAGED ObjectReference { 65 | private: 66 | using Compression = PtrCompression; 67 | 68 | public: 69 | MirrorType *AsMirrorPtr() const { 70 | return Compression::Decompress(reference_); 71 | } 72 | 73 | void Assign(MirrorType *other) { 74 | reference_ = Compression::Compress(other); 75 | } 76 | 77 | void Assign(ObjPtr ptr) REQUIRES_SHARED(Locks::mutator_lock_); 78 | 79 | void Clear() { 80 | reference_ = 0; 81 | DCHECK(IsNull()); 82 | } 83 | 84 | bool IsNull() const { 85 | return reference_ == 0; 86 | } 87 | 88 | uint32_t AsVRegValue() const { 89 | return reference_; 90 | } 91 | 92 | static ObjectReference 93 | FromMirrorPtr(MirrorType *mirror_ptr) 94 | REQUIRES_SHARED(Locks::mutator_lock_) { 95 | return ObjectReference(mirror_ptr); 96 | } 97 | 98 | protected: 99 | explicit ObjectReference(MirrorType *mirror_ptr) REQUIRES_SHARED(Locks::mutator_lock_) 100 | : reference_(Compression::Compress(mirror_ptr)) { 101 | } 102 | 103 | // The encoded reference to a mirror::Object. 104 | uint32_t reference_; 105 | }; 106 | 107 | // Standard compressed reference used in the runtime. Used for StackReference and GC roots. 108 | template 109 | class MANAGED CompressedReference : public mirror::ObjectReference { 110 | public: 111 | CompressedReference() REQUIRES_SHARED(Locks::mutator_lock_) 112 | : mirror::ObjectReference(nullptr) {} 113 | 114 | static CompressedReference FromMirrorPtr(MirrorType *p) 115 | REQUIRES_SHARED(Locks::mutator_lock_) { 116 | return CompressedReference(p); 117 | } 118 | 119 | private: 120 | explicit CompressedReference(MirrorType *p) REQUIRES_SHARED(Locks::mutator_lock_) 121 | : mirror::ObjectReference(p) {} 122 | }; 123 | } 124 | 125 | class RootInfo { 126 | 127 | }; 128 | 129 | class RootVisitor { 130 | public: 131 | virtual ~RootVisitor() {} 132 | 133 | // Single root version, not overridable. 134 | ALWAYS_INLINE void VisitRoot(mirror::Object **root, const RootInfo &info) 135 | REQUIRES_SHARED(Locks::mutator_lock_) { 136 | VisitRoots(&root, 1, info); 137 | } 138 | 139 | // Single root version, not overridable. 140 | ALWAYS_INLINE void VisitRootIfNonNull(mirror::Object **root, const RootInfo &info) 141 | REQUIRES_SHARED(Locks::mutator_lock_) { 142 | if (*root != nullptr) { 143 | VisitRoot(root, info); 144 | } 145 | } 146 | 147 | virtual void VisitRoots(mirror::Object ***roots, size_t count, const RootInfo &info) 148 | REQUIRES_SHARED(Locks::mutator_lock_) = 0; 149 | 150 | virtual void VisitRoots(mirror::CompressedReference **roots, size_t count, 151 | const RootInfo &info) 152 | REQUIRES_SHARED(Locks::mutator_lock_) = 0; 153 | }; 154 | 155 | // Only visits roots one at a time, doesn't handle updating roots. Used when performance isn't 156 | // critical. 157 | class SingleRootVisitor : public RootVisitor { 158 | private: 159 | void VisitRoots(mirror::Object ***roots, size_t count, const RootInfo &info) OVERRIDE 160 | REQUIRES_SHARED(Locks::mutator_lock_) { 161 | for (size_t i = 0; i < count; ++i) { 162 | VisitRoot(*roots[i], info); 163 | } 164 | } 165 | 166 | void VisitRoots(mirror::CompressedReference **roots, size_t count, 167 | const RootInfo &info) OVERRIDE 168 | REQUIRES_SHARED(Locks::mutator_lock_) { 169 | for (size_t i = 0; i < count; ++i) { 170 | VisitRoot(roots[i]->AsMirrorPtr(), info); 171 | } 172 | } 173 | 174 | virtual void VisitRoot(mirror::Object *root, const RootInfo &info) = 0; 175 | }; 176 | 177 | class IsMarkedVisitor { 178 | public: 179 | virtual ~IsMarkedVisitor() {} 180 | 181 | // Return null if an object is not marked, otherwise returns the new address of that object. 182 | // May return the same address as the input if the object did not move. 183 | virtual mirror::Object *IsMarked(mirror::Object *obj) = 0; 184 | }; 185 | 186 | } 187 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/arrays/ArrayBuilder.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JavaArrays.hpp 3 | \brief Creation of java arrays. 4 | \author Denis Sorokin 5 | \date 22.02.2016 6 | */ 7 | 8 | /** 9 | * Cheat sheet: 10 | * 11 | * @code{.cpp} 12 | * 13 | * // Define custom java class: 14 | * JH_JAVA_CUSTOM_CLASS(JavaExample, "com/some/path/Example"); 15 | * 16 | * // Create int array: 17 | * std::vector v({10, 15, 20}); 18 | * jintArray intArray = jh::JavaArrayBuilder() 19 | * .add(5) // value 20 | * .add({25, 30}) // initializer_list 21 | * .add(v.begin(), v.end()) // iterators 22 | * .build()); 23 | * 24 | * // Create jstring array: 25 | * jobjectArray stringArray = jh::JavaArrayBuilder() 26 | * .add(jh::createJString("someString")) 27 | * .build(); 28 | * 29 | * // Create custom java object array: 30 | * jobjectArray exampleArray = jh::JavaArrayBuilder() 31 | * .add(jh::createNewObject()) 32 | * .build(); 33 | * 34 | * // Parse java int array: 35 | * auto stdIntVector = jh::jarrayToVector(intArray); 36 | * for (auto i : stdIntVector) { 37 | * cout << i << endl; 38 | * } 39 | * 40 | * // Passing java array to java code: 41 | * jh::callMethod>(exampleObject, "someMethod", exampleArray); 42 | * 43 | * // Getting java array from java code: 44 | * jobjectArray someArray = jh::callStaticMethod>("otherMethod"); 45 | * 46 | * @endcode 47 | */ 48 | 49 | #ifndef JH_JAVA_ARRAYS_HPP 50 | #define JH_JAVA_ARRAYS_HPP 51 | 52 | #include 53 | #include 54 | #include "../core/ToJavaType.hpp" 55 | #include "../core/JNIEnvironment.hpp" 56 | #include "../arrays/ArrayAllocator.hpp" 57 | #include "../arrays/ArrayGetter.hpp" 58 | #include "../arrays/ArraySetter.hpp" 59 | 60 | namespace jh { 61 | /** 62 | * Transforms and returns the java array data as an std::vector object. 63 | * 64 | * @param JavaArrayType Type of jarray. Can be jintArray, jobjectArray, etc. 65 | * @param array The pointer to the specified array type instance. 66 | * 67 | * @return std::vector with the cope of all elements from the java array. 68 | */ 69 | template 70 | std::vector::ElementType> 71 | jarrayToVector(JavaArrayType array) { 72 | auto env = getCurrentJNIEnvironment(); 73 | return std::move(JavaArrayGetter::get(env, array)); 74 | } 75 | 76 | /** 77 | * Template prototype for java array builder. 78 | * 79 | * @param JavaArrayType Type of java array. Can be jfloatArray, jobjectArray, etc. 80 | * @param ElementType Type of the elements inside this array. 81 | */ 82 | template 83 | class JavaBaseArrayBuilder { 84 | /** 85 | * Type of all elements that can be added to this builder. 86 | */ 87 | using ArgumentType = typename ToJavaType::CallReturnType; 88 | 89 | public: 90 | /** 91 | * Default constructor. Array has no elements. 92 | */ 93 | JavaBaseArrayBuilder() = default; 94 | 95 | /** 96 | * Almost the same as the default constructor, but it allocates the space for 'size' elements. 97 | * 98 | * @param size Number of elements in the future array. 99 | */ 100 | JavaBaseArrayBuilder(std::size_t size) : m_elements(size) {}; 101 | 102 | /** 103 | * Adds one element to the array. 104 | * 105 | * @param value Value of the new element. 106 | */ 107 | JavaBaseArrayBuilder &add(ArgumentType value) { 108 | m_elements.push_back(value); 109 | return *this; 110 | } 111 | 112 | /** 113 | * Adds several elements to the array from the initializer list. 114 | * 115 | * @param container Initializer list with several values. 116 | */ 117 | JavaBaseArrayBuilder & 118 | add(std::initializer_list container) { 119 | for (auto element: container) 120 | m_elements.push_back(element); 121 | 122 | return *this; 123 | } 124 | 125 | /** 126 | * Adds several elements to the array from one iterator to another. 127 | * 128 | * @param b Iterator to the first element. 129 | * @param e Iterator to the last element. 130 | * @param p Hacky way to pass only correct iterators to this method. 131 | */ 132 | template 133 | JavaBaseArrayBuilder & 134 | add(Iterator b, Iterator e, typename Iterator::iterator_category *p = 0) { 135 | for (auto it = b; it != e; ++it) 136 | m_elements.push_back(*it); 137 | 138 | return *this; 139 | } 140 | 141 | /** 142 | * Constructs new java array and returns it. 143 | * 144 | * @return New java array with the stored elements. 145 | */ 146 | JavaArrayType build() { 147 | JNIEnv *env = getCurrentJNIEnvironment(); 148 | JavaArrayType array = JavaArrayAllocator::create(env, 149 | m_elements.size()); 150 | JavaArraySetter::set(env, array, m_elements.size(), &m_elements[0]); 151 | return array; 152 | } 153 | 154 | protected: 155 | /** 156 | * Container for elements that should be in the created hava array. 157 | */ 158 | std::vector m_elements; 159 | }; 160 | 161 | /** 162 | * Java array builder for the java objects (default & custom). 163 | */ 164 | template 165 | class JavaArrayBuilder : public JavaBaseArrayBuilder { 166 | }; 167 | 168 | /** 169 | * Java array builder for the boolean array. 170 | */ 171 | template<> 172 | class JavaArrayBuilder : public JavaBaseArrayBuilder { 173 | }; 174 | 175 | /** 176 | * Java array builder for the int array. 177 | */ 178 | template<> 179 | class JavaArrayBuilder : public JavaBaseArrayBuilder { 180 | }; 181 | 182 | /** 183 | * Java array builder for the long array. 184 | */ 185 | template<> 186 | class JavaArrayBuilder : public JavaBaseArrayBuilder { 187 | }; 188 | 189 | /** 190 | * Java array builder for the float array. 191 | */ 192 | template<> 193 | class JavaArrayBuilder : public JavaBaseArrayBuilder { 194 | }; 195 | 196 | /** 197 | * Java array builder for the double array. 198 | */ 199 | template<> 200 | class JavaArrayBuilder : public JavaBaseArrayBuilder { 201 | }; 202 | } 203 | 204 | #endif 205 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/core/ToJavaType.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file ToJavaType.hpp 3 | \brief Internal type deduction. 4 | \author Denis Sorokin 5 | \date 21.02.2016 6 | */ 7 | 8 | #ifndef JH_TO_JAVA_TYPE_HPP 9 | #define JH_TO_JAVA_TYPE_HPP 10 | 11 | #include 12 | #include 13 | 14 | namespace jh { 15 | /** 16 | * Structure that provides some information about internal types. 17 | * 18 | * @param Type The corresponding JNI type of the 'T' object. 19 | * @param Type The corresponding JNI type of the 'T' object which is returned by JNI calls. 20 | * @param signature The signature of 'T' type. 21 | * @param className The class name (path?) of 'T' type, if it is some default/custom java type. 22 | */ 23 | template 24 | struct ToJavaType { 25 | using Type = jobject; 26 | using CallReturnType = jobject; 27 | 28 | static std::string signature() { 29 | return T::signature(); 30 | } 31 | 32 | static jobject initValue() { 33 | return nullptr; 34 | } 35 | 36 | static std::string className() { 37 | return T::className(); 38 | } 39 | }; 40 | 41 | /** 42 | * Structure that provides some information about void type. 43 | */ 44 | template<> 45 | struct ToJavaType { 46 | using Type = void; 47 | using CallReturnType = void; 48 | 49 | static jobject initValue() { 50 | return nullptr; 51 | } 52 | 53 | static std::string signature() { 54 | return "V"; 55 | } 56 | }; 57 | 58 | /** 59 | * Structure that provides some information about bool type. 60 | */ 61 | template<> 62 | struct ToJavaType { 63 | using Type = jboolean; 64 | using CallReturnType = jboolean; 65 | 66 | static bool initValue() { 67 | return false; 68 | } 69 | 70 | static std::string signature() { 71 | return "Z"; 72 | } 73 | }; 74 | 75 | /** 76 | * Structure that provides some information about int type. 77 | */ 78 | template<> 79 | struct ToJavaType { 80 | using Type = jint; 81 | using CallReturnType = jint; 82 | 83 | static int initValue() { 84 | return 0; 85 | } 86 | 87 | static std::string signature() { 88 | return "I"; 89 | } 90 | }; 91 | 92 | /** 93 | * Structure that provides some information about long type. 94 | */ 95 | template<> 96 | struct ToJavaType { 97 | using Type = jlong; 98 | using CallReturnType = jlong; 99 | 100 | static long initValue() { 101 | return 0; 102 | } 103 | 104 | static std::string signature() { 105 | return "J"; 106 | } 107 | }; 108 | 109 | /** 110 | * Structure that provides some information about float type. 111 | */ 112 | template<> 113 | struct ToJavaType { 114 | using Type = jfloat; 115 | using CallReturnType = jfloat; 116 | 117 | static float initValue() { 118 | return 0; 119 | } 120 | 121 | static std::string signature() { 122 | return "F"; 123 | } 124 | }; 125 | 126 | /** 127 | * Structure that provides some information about double type. 128 | */ 129 | template<> 130 | struct ToJavaType { 131 | using Type = jdouble; 132 | using CallReturnType = jdouble; 133 | 134 | static double initValue() { 135 | return 0; 136 | } 137 | 138 | static std::string signature() { 139 | return "D"; 140 | } 141 | }; 142 | 143 | /** 144 | * Structure that describes a type that can be casted to jobject. 145 | */ 146 | template 147 | struct JPointerLike { 148 | using Type = JavaType; 149 | using CallReturnType = jobject; 150 | }; 151 | 152 | /** 153 | * Structure that provides some information about jobject type. 154 | */ 155 | template<> 156 | struct ToJavaType : public JPointerLike { 157 | static std::string className() { 158 | return "java/lang/Object"; 159 | } 160 | 161 | static std::string signature() { 162 | return "L" + className() + ";"; 163 | } 164 | }; 165 | 166 | /** 167 | * Structure that provides some information about jstring type. 168 | */ 169 | template<> 170 | struct ToJavaType : public JPointerLike { 171 | static jstring initValue() { 172 | return nullptr; 173 | } 174 | 175 | static std::string className() { 176 | return "java/lang/String"; 177 | } 178 | 179 | static std::string signature() { 180 | return "L" + className() + ";"; 181 | } 182 | }; 183 | 184 | /** 185 | * Structure that describes the types of java arrays. 186 | * 187 | * @param ElementType The corresponding JNI type of the elements inside this array. 188 | */ 189 | template 190 | struct JavaArray { 191 | using ElementType = JavaElementType; 192 | 193 | static std::string signature() { 194 | return "[" + ToJavaType::signature(); 195 | } 196 | }; 197 | 198 | /** 199 | * Structure that describes the types of custom java arrays. 200 | */ 201 | template 202 | struct ToJavaType> : public JavaArray { 203 | using Type = jobjectArray; 204 | using CallReturnType = jobjectArray; 205 | }; 206 | 207 | /** 208 | * Structure that provides some information about jbooleanArray type. 209 | */ 210 | template<> 211 | struct ToJavaType 212 | : public JavaArray, public JPointerLike { 213 | }; 214 | 215 | /** 216 | * Structure that provides some information about jintArray type. 217 | */ 218 | template<> 219 | struct ToJavaType : public JavaArray, public JPointerLike { 220 | }; 221 | 222 | /** 223 | * Structure that provides some information about jlongArray type. 224 | */ 225 | template<> 226 | struct ToJavaType : public JavaArray, public JPointerLike { 227 | }; 228 | 229 | /** 230 | * Structure that provides some information about jfloatArray type. 231 | */ 232 | template<> 233 | struct ToJavaType : public JavaArray, public JPointerLike { 234 | }; 235 | 236 | /** 237 | * Structure that provides some information about jdoubleArray type. 238 | */ 239 | template<> 240 | struct ToJavaType : public JavaArray, public JPointerLike { 241 | }; 242 | 243 | /** 244 | * Structure that provides some information about jobjectArray type. 245 | */ 246 | template<> 247 | struct ToJavaType : public JavaArray, public JPointerLike { 248 | }; 249 | } 250 | 251 | #endif 252 | -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/calls/StaticCaller.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file StaticCaller.hpp 3 | \brief Static java methods calls. 4 | \author Denis Sorokin 5 | \date 24.01.2016 6 | */ 7 | 8 | /** 9 | * Cheat sheet: 10 | * 11 | * @code{.cpp} 12 | * 13 | * // Declaring some custom Java class: 14 | * JH_JAVA_CUSTOM_CLASS(Example, "com/class/path/Example"); 15 | * 16 | * // Calling void static method without arguments (old style / new style): 17 | * jh::callStaticMethod(Example::className(), "voidMethodName"); 18 | * jh::callStaticMethod("voidMethodName"); 19 | * 20 | * // Calling int static method with two arguments (old style / new style): 21 | * int sum = jh::callStaticMethod(Example::className(), "sumMethod", 4, 5); 22 | * int sum = jh::callStaticMethod("sumMethod", 4, 5); 23 | * 24 | * // Calling static factory method that returns some custom Java object (old style / new style): 25 | * jobject newObject = jh::callStaticMethod(Example::className(), "factoryMethodName", 3.1415); 26 | * jobject newObject = jh::callStaticMethod("factoryMethodName", 3.1415); 27 | * 28 | * @endcode 29 | */ 30 | 31 | #ifndef JH_STATIC_CALLER_HPP 32 | #define JH_STATIC_CALLER_HPP 33 | 34 | #include 35 | #include 36 | #include "../core/ToJavaType.hpp" 37 | #include "../core/ErrorHandler.hpp" 38 | #include "../core/JNIEnvironment.hpp" 39 | #include "../core/JavaMethodSignature.hpp" 40 | 41 | namespace jh { 42 | /** 43 | * Class that can call static methods which return java objects. 44 | */ 45 | template 46 | struct StaticCaller { 47 | static jobject 48 | call(JNIEnv *env, jclass javaClass, jmethodID javaMethod, ArgumentTypes ... arguments) { 49 | return env->CallStaticObjectMethod(javaClass, javaMethod, arguments...); 50 | } 51 | }; 52 | 53 | /** 54 | * Class that can call static methods which doesn't return anything. 55 | */ 56 | template 57 | struct StaticCaller { 58 | static void 59 | call(JNIEnv *env, jclass javaClass, jmethodID javaMethod, ArgumentTypes ... arguments) { 60 | env->CallStaticVoidMethod(javaClass, javaMethod, arguments...); 61 | } 62 | }; 63 | 64 | /** 65 | * Class that can call static methods which return jboolean values. 66 | */ 67 | template 68 | struct StaticCaller { 69 | static jboolean 70 | call(JNIEnv *env, jclass javaClass, jmethodID javaMethod, ArgumentTypes ... arguments) { 71 | return env->CallStaticBooleanMethod(javaClass, javaMethod, arguments...); 72 | } 73 | }; 74 | 75 | /** 76 | * Class that can call static methods which return jint values. 77 | */ 78 | template 79 | struct StaticCaller { 80 | static jint 81 | call(JNIEnv *env, jclass javaClass, jmethodID javaMethod, ArgumentTypes ... arguments) { 82 | return env->CallStaticIntMethod(javaClass, javaMethod, arguments...); 83 | } 84 | }; 85 | 86 | /** 87 | * Class that can call static methods which return jlong values. 88 | */ 89 | template 90 | struct StaticCaller { 91 | static jlong 92 | call(JNIEnv *env, jclass javaClass, jmethodID javaMethod, ArgumentTypes ... arguments) { 93 | return env->CallStaticLongMethod(javaClass, javaMethod, arguments...); 94 | } 95 | }; 96 | 97 | /** 98 | * Class that can call static methods which return jfloat values. 99 | */ 100 | template 101 | struct StaticCaller { 102 | static jfloat 103 | call(JNIEnv *env, jclass javaClass, jmethodID javaMethod, ArgumentTypes ... arguments) { 104 | return env->CallStaticFloatMethod(javaClass, javaMethod, arguments...); 105 | } 106 | }; 107 | 108 | /** 109 | * Class that can call static methods which return jdouble values. 110 | */ 111 | template 112 | struct StaticCaller { 113 | static jdouble 114 | call(JNIEnv *env, jclass javaClass, jmethodID javaMethod, ArgumentTypes ... arguments) { 115 | return env->CallStaticDoubleMethod(javaClass, javaMethod, arguments...); 116 | } 117 | }; 118 | 119 | /** 120 | * Calls a static method of some Java class. Programmer should explicitly 121 | * specify the return type and argument types via template arguments. 122 | * 123 | * @param className Java class name as string. 124 | * @param methodName Method name as string. 125 | * @param arguments List of arguments to the java method call. 126 | * @return Some value of ReturnType type returned by the specified static method. 127 | */ 128 | template 129 | typename ToJavaType::Type 130 | callStaticMethod(std::string className, std::string methodName, 131 | typename ToJavaType::Type ... arguments) { 132 | using RealReturnType = typename ToJavaType::Type; 133 | 134 | JNIEnv *env = getCurrentJNIEnvironment(); 135 | 136 | std::string methodSignature = getJavaMethodSignature(); 137 | 138 | jclass javaClass = env->FindClass(className.c_str()); 139 | if (javaClass == nullptr) { 140 | reportInternalError("class not found [" + className + "]"); 141 | return RealReturnType(); 142 | } 143 | 144 | jmethodID javaMethod = env->GetStaticMethodID(javaClass, methodName.c_str(), 145 | methodSignature.c_str()); 146 | if (javaMethod == nullptr) { 147 | reportInternalError("method [" + methodName + "] for class [" + className + 148 | "] not found, tried signature [" + methodSignature + "]"); 149 | return RealReturnType(); 150 | } 151 | 152 | return static_cast(StaticCaller::CallReturnType, typename ToJavaType::Type ...>::call( 153 | env, javaClass, javaMethod, arguments...)); 154 | } 155 | 156 | /** 157 | * New style of calling static methods, where java class is specified 158 | * via template argument. 159 | * 160 | * @param methodName Method name as string. 161 | * @param arguments List of arguments to the java method call. 162 | * @return Some value of ReturnType type returned by the specified static method. 163 | */ 164 | template 165 | typename ToJavaType::Type callStaticMethod(std::string methodName, 166 | typename ToJavaType::Type ... arguments) { 167 | return callStaticMethod(JavaClassType::className(), 168 | methodName, arguments...); 169 | } 170 | } 171 | 172 | #endif 173 | -------------------------------------------------------------------------------- /anti/src/main/cpp/xposeddetector/find_name.cpp: -------------------------------------------------------------------------------- 1 | #include "find_name.h" 2 | #include 3 | 4 | 5 | #define NATIVE 0x00000100 6 | #define STATIC 0x00000008 7 | 8 | char *find_name::findField(C_JNIEnv *env, jobject clazz, int staticFlag, jclass type) { 9 | char *name = nullptr; 10 | jclass classClass = (*env)->FindClass((JNIEnv *) env, "java/lang/Class"); 11 | jmethodID getDeclaredFields = (*env)->GetMethodID((JNIEnv *) env, classClass, 12 | "getDeclaredFields", 13 | "()[Ljava/lang/reflect/Field;"); 14 | jclass classField = (*env)->FindClass((JNIEnv *) env, "java/lang/reflect/Field"); 15 | jmethodID getModifiers = (*env)->GetMethodID((JNIEnv *) env, classField, "getModifiers", "()I"); 16 | jmethodID getType = (*env)->GetMethodID((JNIEnv *) env, classField, "getType", 17 | "()Ljava/lang/Class;"); 18 | jmethodID getName = (*env)->GetMethodID((JNIEnv *) env, classField, "getName", 19 | "()Ljava/lang/String;"); 20 | auto fields = (jobjectArray) (*env)->CallObjectMethod((JNIEnv *) env, clazz, getDeclaredFields); 21 | int length = (*env)->GetArrayLength((JNIEnv *) env, fields); 22 | for (int i = 0; i < length; ++i) { 23 | jobject field = (*env)->GetObjectArrayElement((JNIEnv *) env, fields, i); 24 | int modifier = (*env)->CallIntMethod((JNIEnv *) env, field, getModifiers); 25 | if ((modifier & STATIC) == staticFlag 26 | && (*env)->IsSameObject((JNIEnv *) env, type, 27 | (*env)->CallObjectMethod((JNIEnv *) env, field, getType))) { 28 | auto fieldString = (jstring) (*env)->CallObjectMethod((JNIEnv *) env, field, getName); 29 | const char *fieldName = (*env)->GetStringUTFChars((JNIEnv *) env, fieldString, nullptr); 30 | name = strdup(fieldName); 31 | (*env)->ReleaseStringUTFChars((JNIEnv *) env, fieldString, fieldName); 32 | (*env)->DeleteLocalRef((JNIEnv *) env, fieldString); 33 | } 34 | (*env)->DeleteLocalRef((JNIEnv *) env, field); 35 | if (name != nullptr) { 36 | break; 37 | } 38 | } 39 | 40 | (*env)->DeleteLocalRef((JNIEnv *) env, fields); 41 | (*env)->DeleteLocalRef((JNIEnv *) env, classField); 42 | (*env)->DeleteLocalRef((JNIEnv *) env, classClass); 43 | return name; 44 | } 45 | 46 | char *find_name::findObjectArrayName(C_JNIEnv *env, jobject clazz) { 47 | jclass classObjectArray = (*env)->FindClass((JNIEnv *) env, "[Ljava/lang/Object;"); 48 | char *name = findField(env, clazz, 0, classObjectArray); 49 | (*env)->DeleteLocalRef((JNIEnv *) env, classObjectArray); 50 | return name; 51 | } 52 | 53 | char *find_name::findStaticMapName(C_JNIEnv *env, jobject clazz) { 54 | jclass classMap = (*env)->FindClass((JNIEnv *) env, "java/util/Map"); 55 | char *name = findField(env, clazz, STATIC, classMap); 56 | (*env)->DeleteLocalRef((JNIEnv *) env, classMap); 57 | return name; 58 | } 59 | 60 | char *find_name::findVoidStringName(C_JNIEnv *env, jclass clazz) { 61 | char *name = nullptr; 62 | jclass classClass = (*env)->FindClass((JNIEnv *) env, "java/lang/Class"); 63 | jmethodID getDeclaredMethods = (*env)->GetMethodID((JNIEnv *) env, classClass, 64 | "getDeclaredMethods", 65 | "()[Ljava/lang/reflect/Method;"); 66 | jclass classMethod = (*env)->FindClass((JNIEnv *) env, "java/lang/reflect/Method"); 67 | jmethodID getModifiers = (*env)->GetMethodID((JNIEnv *) env, classMethod, "getModifiers", 68 | "()I"); 69 | jmethodID getParameterTypes = (*env)->GetMethodID((JNIEnv *) env, classMethod, 70 | "getParameterTypes", "()[Ljava/lang/Class;"); 71 | jmethodID getReturnType = (*env)->GetMethodID((JNIEnv *) env, classMethod, "getReturnType", 72 | "()Ljava/lang/Class;"); 73 | jmethodID getName = (*env)->GetMethodID((JNIEnv *) env, classMethod, "getName", 74 | "()Ljava/lang/String;"); 75 | jclass classString = (*env)->FindClass((JNIEnv *) env, "java/lang/String"); 76 | auto methods = (jobjectArray) (*env)->CallObjectMethod((JNIEnv *) env, clazz, 77 | getDeclaredMethods); 78 | int length = (*env)->GetArrayLength((JNIEnv *) env, methods); 79 | for (int i = 0; i < length; ++i) { 80 | jobject method = (*env)->GetObjectArrayElement((JNIEnv *) env, methods, i); 81 | int modifier = (*env)->CallIntMethod((JNIEnv *) env, method, getModifiers); 82 | if ((modifier & (NATIVE | STATIC)) == STATIC 83 | && (*env)->GetArrayLength((JNIEnv *) env, 84 | (jarray) (*env)->CallObjectMethod((JNIEnv *) env, method, 85 | getParameterTypes)) == 0 86 | && (*env)->IsSameObject((JNIEnv *) env, classString, 87 | (*env)->CallObjectMethod((JNIEnv *) env, method, 88 | getReturnType))) { 89 | auto methodString = (jstring) (*env)->CallObjectMethod((JNIEnv *) env, method, getName); 90 | const char *methodName = (*env)->GetStringUTFChars((JNIEnv *) env, methodString, 91 | nullptr); 92 | jmethodID methodMethod = (*env)->GetStaticMethodID((JNIEnv *) env, clazz, methodName, 93 | "()Ljava/lang/String;"); 94 | auto bridgeString = (jstring) (*env)->CallStaticObjectMethod((JNIEnv *) env, clazz, 95 | methodMethod); 96 | if ((*env)->ExceptionCheck((JNIEnv *) env)) { 97 | (*env)->ExceptionClear((JNIEnv *) env); 98 | } 99 | if (bridgeString != nullptr) { 100 | const char *bridgeName = (*env)->GetStringUTFChars((JNIEnv *) env, bridgeString, 101 | nullptr); 102 | if (*bridgeName == 'L') { 103 | name = strdup(bridgeName + 1); 104 | } else { 105 | name = strdup(bridgeName); 106 | } 107 | (*env)->ReleaseStringUTFChars((JNIEnv *) env, bridgeString, bridgeName); 108 | (*env)->DeleteLocalRef((JNIEnv *) env, bridgeString); 109 | } 110 | (*env)->ReleaseStringUTFChars((JNIEnv *) env, methodString, methodName); 111 | (*env)->DeleteLocalRef((JNIEnv *) env, methodString); 112 | } 113 | (*env)->DeleteLocalRef((JNIEnv *) env, method); 114 | if (name != nullptr) { 115 | char *x = name; 116 | while (*x != ';' && *x != '\0') { 117 | x++; 118 | } 119 | *x = '\0'; 120 | break; 121 | } 122 | } 123 | 124 | (*env)->DeleteLocalRef((JNIEnv *) env, methods); 125 | (*env)->DeleteLocalRef((JNIEnv *) env, classString); 126 | (*env)->DeleteLocalRef((JNIEnv *) env, classMethod); 127 | (*env)->DeleteLocalRef((JNIEnv *) env, classClass); 128 | return name; 129 | } -------------------------------------------------------------------------------- /anti/src/main/cpp/JNIHelper/native/JavaNativeMethod.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | \file JavaNativeMethod.hpp 3 | \brief Allocation and registration of java native methods in C++. 4 | \author Denis Sorokin 5 | \date 15.02.2016 6 | */ 7 | 8 | /** 9 | * Cheat sheet: 10 | * 11 | * @code{.cpp} 12 | * 13 | * // Lets assume we have some global function: 14 | * void testObjectWrapperAndStaticNativeMethodsEnd() { ... } 15 | * 16 | * // Let's register it as a static native function (old style / new style): 17 | * jh::registerStaticNativeMethod(Example::className(), "staticNativeMethod", &testObjectWrapperAndStaticNativeMethodsEnd); 18 | * jh::registerStaticNativeMethod("staticNativeMethod", &testObjectWrapperAndStaticNativeMethodsEnd); 19 | * 20 | * @endcode 21 | */ 22 | 23 | #ifndef JH_JAVA_NATIVE_METHOD_HPP 24 | #define JH_JAVA_NATIVE_METHOD_HPP 25 | 26 | #include 27 | #include "../core/ErrorHandler.hpp" 28 | #include "../core/JavaMethodSignature.hpp" 29 | 30 | namespace jh { 31 | /** 32 | * Registers local functions as java native methods. 33 | * 34 | * @param javaClassName Name of the java class. 35 | * @param methodCount Total number of methods that should be registered by this call. 36 | * @param methodDescriptions Pointer to an array of java native method descriptions. 37 | * 38 | * @return True if methods were successfully registered or false otherwise. 39 | * 40 | * @warning Java native methods should be registered only after JNI initialization, i.e. dont use this method while doing some static-level stuff. 41 | * @warning Don't call native methods from java until they are 100% registered in C++. There will be a crash if they aren't. 42 | */ 43 | bool registerJavaNativeMethods(std::string javaClassName, int methodCount, 44 | JNINativeMethod *methodDescriptions); 45 | 46 | /** 47 | * Registers some function or static method as a java native static method. 48 | * 49 | * @param javaClassName Name of the java class that has this native method. 50 | * @param methodName Name of the native method. 51 | * @param methodPointer Pointer to the local function or static method that will be called as java native method. 52 | * 53 | * @warning Java native methods should be registered only after JNI initialization, i.e. dont use this method while doing some static-level stuff. 54 | * @warning Don't call native methods from java until they are 100% registered in C++. There will be a crash if they aren't. 55 | */ 56 | template 57 | bool registerStaticNativeMethod(std::string javaClassName, std::string methodName, 58 | ReturnType (*methodPointer)(ArgumentTypes...)) { 59 | std::string signature = getJavaMethodSignature(); 60 | 61 | JNINativeMethod method[1] = { 62 | methodName.c_str(), 63 | signature.c_str(), 64 | (void *) methodPointer 65 | }; 66 | 67 | return registerJavaNativeMethods(javaClassName, 1, method); 68 | } 69 | 70 | /** 71 | * Registers some function or static method as a java native static method. 72 | * Java class here is passed as a template argument, so there is no need 73 | * for an explicit java class name parameter. 74 | * 75 | * @param methodName Name of the native method. 76 | * @param methodPointer Pointer to the local function or static method that will be called as java native method. 77 | * 78 | * @warning Java native methods should be registered only after JNI initialization, i.e. dont use this method while doing some static-level stuff. 79 | * @warning Don't call native methods from java until they are 100% registered in C++. There will be a crash if they aren't. 80 | */ 81 | template 82 | bool registerStaticNativeMethod(std::string methodName, 83 | ReturnType (*methodPointer)(ArgumentTypes...)) { 84 | return registerStaticNativeMethod(JavaClassType::className(), 85 | methodName, methodPointer); 86 | } 87 | 88 | /** 89 | * This class provides an static method that should be registered as java native method. 90 | * It should not be used by the programmer itself, but by the JavaObjectWrapper class. 91 | * 92 | * @param id Dirty hack to distinguish two native methods with equal signatures. Should be unique for every native method per CppClass type. 93 | * @param CppClass C++ class that wraps the functionality of some Java class. 94 | * @param ReturnType The return type of java native method. 95 | * @param Arguments The types of arguments of java native method. 96 | * 97 | * @warning One should not forget to set the callback by method 'setCallback(...)' if using this class. 98 | * @warning Each combination of template parameters should correspond to ONLY ONE native method. 99 | * @warning Native methods that were implemented by this class should NOT be called inside the java object constructor. 100 | */ 101 | template 102 | class JavaNativeMethod { 103 | /** 104 | * The type of the class method that will be called as native method. 105 | */ 106 | using MethodImplementationPointer = ReturnType(CppClass::*)(Arguments...); 107 | 108 | /** 109 | * Java object wrapper should freely access native method. 110 | */ 111 | template 112 | friend 113 | class JavaObjectWrapper; 114 | 115 | private: 116 | /** 117 | * Native method pointer is stored here. 118 | */ 119 | static MethodImplementationPointer s_callback; 120 | 121 | /** 122 | * Sets the native method pointer. Should be called once (no less, no more) per native method. 123 | */ 124 | static void setCallback(MethodImplementationPointer callback) { 125 | if (s_callback) { 126 | reportInternalError( 127 | "redefining callback for java class [" + CppClass::JavaClass::className() + 128 | "]"); 129 | } 130 | 131 | s_callback = callback; 132 | } 133 | 134 | /** 135 | * Static method that is used to link java native method and local instance method. 136 | */ 137 | static ReturnType rawNativeMethod(JNIEnv *, jobject javaObject, Arguments ... args) { 138 | return CppClass::template callCppObjectMethod(javaObject, 139 | [=](CppClass *wrapperInstance) -> ReturnType { 140 | return (wrapperInstance->* 141 | s_callback)( 142 | args...); 143 | }); 144 | } 145 | }; 146 | 147 | template 148 | typename JavaNativeMethod::MethodImplementationPointer JavaNativeMethod::s_callback( 149 | nullptr); 150 | } 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /anti/src/main/cpp/mini_io/syscall/x86.S: -------------------------------------------------------------------------------- 1 | /* Generated by gensyscalls.py. Do not edit. */ 2 | 3 | #include "private/bionic_asm.h" 4 | 5 | ENTRY_PRIVATE(___close) 6 | pushl %ebx 7 | .cfi_def_cfa_offset 8 8 | .cfi_rel_offset ebx, 0 9 | 10 | call __kernel_syscall 11 | pushl %eax 12 | .cfi_adjust_cfa_offset 4 13 | .cfi_rel_offset eax, 0 14 | 15 | mov 12(%esp), %ebx 16 | movl $__NR_close, %eax 17 | call *(%esp) 18 | addl $4, %esp 19 | 20 | cmpl $-MAX_ERRNO, %eax 21 | jb 1f 22 | negl %eax 23 | pushl %eax 24 | call ___set_errno_internal 25 | addl $4, %esp 26 | 1: 27 | popl %ebx 28 | ret 29 | END(___close) 30 | 31 | ENTRY_PRIVATE(_lseek) 32 | pushl %ebx 33 | .cfi_def_cfa_offset 8 34 | .cfi_rel_offset ebx, 0 35 | pushl %ecx 36 | .cfi_adjust_cfa_offset 4 37 | .cfi_rel_offset ecx, 0 38 | pushl %edx 39 | .cfi_adjust_cfa_offset 4 40 | .cfi_rel_offset edx, 0 41 | 42 | call __kernel_syscall 43 | pushl %eax 44 | .cfi_adjust_cfa_offset 4 45 | .cfi_rel_offset eax, 0 46 | 47 | mov 20(%esp), %ebx 48 | mov 24(%esp), %ecx 49 | mov 28(%esp), %edx 50 | movl $__NR_lseek, %eax 51 | call *(%esp) 52 | addl $4, %esp 53 | 54 | cmpl $-MAX_ERRNO, %eax 55 | jb 1f 56 | negl %eax 57 | pushl %eax 58 | call ___set_errno_internal 59 | addl $4, %esp 60 | 1: 61 | popl %edx 62 | popl %ecx 63 | popl %ebx 64 | ret 65 | END(_lseek) 66 | 67 | ENTRY_PRIVATE(__openat) 68 | pushl %ebx 69 | .cfi_def_cfa_offset 8 70 | .cfi_rel_offset ebx, 0 71 | pushl %ecx 72 | .cfi_adjust_cfa_offset 4 73 | .cfi_rel_offset ecx, 0 74 | pushl %edx 75 | .cfi_adjust_cfa_offset 4 76 | .cfi_rel_offset edx, 0 77 | pushl %esi 78 | .cfi_adjust_cfa_offset 4 79 | .cfi_rel_offset esi, 0 80 | 81 | call __kernel_syscall 82 | pushl %eax 83 | .cfi_adjust_cfa_offset 4 84 | .cfi_rel_offset eax, 0 85 | 86 | mov 24(%esp), %ebx 87 | mov 28(%esp), %ecx 88 | mov 32(%esp), %edx 89 | mov 36(%esp), %esi 90 | movl $__NR_openat, %eax 91 | call *(%esp) 92 | addl $4, %esp 93 | 94 | cmpl $-MAX_ERRNO, %eax 95 | jb 1f 96 | negl %eax 97 | pushl %eax 98 | call ___set_errno_internal 99 | addl $4, %esp 100 | 1: 101 | popl %esi 102 | popl %edx 103 | popl %ecx 104 | popl %ebx 105 | ret 106 | END(__openat) 107 | 108 | ENTRY_PRIVATE(_read) 109 | pushl %ebx 110 | .cfi_def_cfa_offset 8 111 | .cfi_rel_offset ebx, 0 112 | pushl %ecx 113 | .cfi_adjust_cfa_offset 4 114 | .cfi_rel_offset ecx, 0 115 | pushl %edx 116 | .cfi_adjust_cfa_offset 4 117 | .cfi_rel_offset edx, 0 118 | 119 | call __kernel_syscall 120 | pushl %eax 121 | .cfi_adjust_cfa_offset 4 122 | .cfi_rel_offset eax, 0 123 | 124 | mov 20(%esp), %ebx 125 | mov 24(%esp), %ecx 126 | mov 28(%esp), %edx 127 | movl $__NR_read, %eax 128 | call *(%esp) 129 | addl $4, %esp 130 | 131 | cmpl $-MAX_ERRNO, %eax 132 | jb 1f 133 | negl %eax 134 | pushl %eax 135 | call ___set_errno_internal 136 | addl $4, %esp 137 | 1: 138 | popl %edx 139 | popl %ecx 140 | popl %ebx 141 | ret 142 | END(_read) 143 | 144 | ENTRY_PRIVATE(_write) 145 | pushl %ebx 146 | .cfi_def_cfa_offset 8 147 | .cfi_rel_offset ebx, 0 148 | pushl %ecx 149 | .cfi_adjust_cfa_offset 4 150 | .cfi_rel_offset ecx, 0 151 | pushl %edx 152 | .cfi_adjust_cfa_offset 4 153 | .cfi_rel_offset edx, 0 154 | 155 | call __kernel_syscall 156 | pushl %eax 157 | .cfi_adjust_cfa_offset 4 158 | .cfi_rel_offset eax, 0 159 | 160 | mov 20(%esp), %ebx 161 | mov 24(%esp), %ecx 162 | mov 28(%esp), %edx 163 | movl $__NR_write, %eax 164 | call *(%esp) 165 | addl $4, %esp 166 | 167 | cmpl $-MAX_ERRNO, %eax 168 | jb 1f 169 | negl %eax 170 | pushl %eax 171 | call ___set_errno_internal 172 | addl $4, %esp 173 | 1: 174 | popl %edx 175 | popl %ecx 176 | popl %ebx 177 | ret 178 | END(_write) 179 | 180 | ENTRY_PRIVATE(_ptrace) 181 | pushl %ebx 182 | .cfi_def_cfa_offset 8 183 | .cfi_rel_offset ebx, 0 184 | pushl %ecx 185 | .cfi_adjust_cfa_offset 4 186 | .cfi_rel_offset ecx, 0 187 | pushl %edx 188 | .cfi_adjust_cfa_offset 4 189 | .cfi_rel_offset edx, 0 190 | 191 | call __kernel_syscall 192 | pushl %eax 193 | .cfi_adjust_cfa_offset 4 194 | .cfi_rel_offset eax, 0 195 | 196 | mov 20(%esp), %ebx 197 | mov 24(%esp), %ecx 198 | mov 28(%esp), %edx 199 | movl $__NR_ptrace, %eax 200 | call *(%esp) 201 | addl $4, %esp 202 | 203 | cmpl $-MAX_ERRNO, %eax 204 | jb 1f 205 | negl %eax 206 | pushl %eax 207 | call ___set_errno_internal 208 | addl $4, %esp 209 | 1: 210 | popl %edx 211 | popl %ecx 212 | popl %ebx 213 | ret 214 | END(_ptrace) 215 | 216 | ENTRY_PRIVATE(_readlinkat) 217 | pushl %ebx 218 | .cfi_def_cfa_offset 8 219 | .cfi_rel_offset ebx, 0 220 | pushl %ecx 221 | .cfi_adjust_cfa_offset 4 222 | .cfi_rel_offset ecx, 0 223 | pushl %edx 224 | .cfi_adjust_cfa_offset 4 225 | .cfi_rel_offset edx, 0 226 | pushl %esi 227 | .cfi_adjust_cfa_offset 4 228 | .cfi_rel_offset esi, 0 229 | 230 | call __kernel_syscall 231 | pushl %eax 232 | .cfi_adjust_cfa_offset 4 233 | .cfi_rel_offset eax, 0 234 | 235 | mov 24(%esp), %ebx 236 | mov 28(%esp), %ecx 237 | mov 32(%esp), %edx 238 | mov 36(%esp), %esi 239 | movl $__NR_readlinkat, %eax 240 | call *(%esp) 241 | addl $4, %esp 242 | 243 | cmpl $-MAX_ERRNO, %eax 244 | jb 1f 245 | negl %eax 246 | pushl %eax 247 | call ___set_errno_internal 248 | addl $4, %esp 249 | 1: 250 | popl %esi 251 | popl %edx 252 | popl %ecx 253 | popl %ebx 254 | ret 255 | END(_readlinkat) 256 | 257 | ENTRY_PRIVATE(_nanosleep) 258 | pushl %ebx 259 | .cfi_def_cfa_offset 8 260 | .cfi_rel_offset ebx, 0 261 | pushl %ecx 262 | .cfi_adjust_cfa_offset 4 263 | .cfi_rel_offset ecx, 0 264 | 265 | call __kernel_syscall 266 | pushl %eax 267 | .cfi_adjust_cfa_offset 4 268 | .cfi_rel_offset eax, 0 269 | 270 | mov 16(%esp), %ebx 271 | mov 20(%esp), %ecx 272 | movl $__NR_nanosleep, %eax 273 | call *(%esp) 274 | addl $4, %esp 275 | 276 | cmpl $-MAX_ERRNO, %eax 277 | jb 1f 278 | negl %eax 279 | pushl %eax 280 | call ___set_errno_internal 281 | addl $4, %esp 282 | 1: 283 | popl %ecx 284 | popl %ebx 285 | ret 286 | END(_nanosleep) 287 | 288 | ENTRY_PRIVATE(_inotify_init1) 289 | pushl %ebx 290 | .cfi_def_cfa_offset 8 291 | .cfi_rel_offset ebx, 0 292 | 293 | call __kernel_syscall 294 | pushl %eax 295 | .cfi_adjust_cfa_offset 4 296 | .cfi_rel_offset eax, 0 297 | 298 | mov 12(%esp), %ebx 299 | movl $__NR_inotify_init1, %eax 300 | call *(%esp) 301 | addl $4, %esp 302 | 303 | cmpl $-MAX_ERRNO, %eax 304 | jb 1f 305 | negl %eax 306 | pushl %eax 307 | call ___set_errno_internal 308 | addl $4, %esp 309 | 1: 310 | popl %ebx 311 | ret 312 | END(_inotify_init1) 313 | 314 | ENTRY_PRIVATE(_inotify_add_watch) 315 | pushl %ebx 316 | .cfi_def_cfa_offset 8 317 | .cfi_rel_offset ebx, 0 318 | pushl %ecx 319 | .cfi_adjust_cfa_offset 4 320 | .cfi_rel_offset ecx, 0 321 | pushl %edx 322 | .cfi_adjust_cfa_offset 4 323 | .cfi_rel_offset edx, 0 324 | 325 | call __kernel_syscall 326 | pushl %eax 327 | .cfi_adjust_cfa_offset 4 328 | .cfi_rel_offset eax, 0 329 | 330 | mov 20(%esp), %ebx 331 | mov 24(%esp), %ecx 332 | mov 28(%esp), %edx 333 | movl $__NR_inotify_add_watch, %eax 334 | call *(%esp) 335 | addl $4, %esp 336 | 337 | cmpl $-MAX_ERRNO, %eax 338 | jb 1f 339 | negl %eax 340 | pushl %eax 341 | call ___set_errno_internal 342 | addl $4, %esp 343 | 1: 344 | popl %edx 345 | popl %ecx 346 | popl %ebx 347 | ret 348 | END(_inotify_add_watch) 349 | 350 | ENTRY_PRIVATE(_inotify_rm_watch) 351 | pushl %ebx 352 | .cfi_def_cfa_offset 8 353 | .cfi_rel_offset ebx, 0 354 | pushl %ecx 355 | .cfi_adjust_cfa_offset 4 356 | .cfi_rel_offset ecx, 0 357 | 358 | call __kernel_syscall 359 | pushl %eax 360 | .cfi_adjust_cfa_offset 4 361 | .cfi_rel_offset eax, 0 362 | 363 | mov 16(%esp), %ebx 364 | mov 20(%esp), %ecx 365 | movl $__NR_inotify_rm_watch, %eax 366 | call *(%esp) 367 | addl $4, %esp 368 | 369 | cmpl $-MAX_ERRNO, %eax 370 | jb 1f 371 | negl %eax 372 | pushl %eax 373 | call ___set_errno_internal 374 | addl $4, %esp 375 | 1: 376 | popl %ecx 377 | popl %ebx 378 | ret 379 | END(_inotify_rm_watch) 380 | --------------------------------------------------------------------------------