├── 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 | 
16 | 
17 | 
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 | 
41 | 
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