├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── arm64-v8a │ │ └── libxhook.so │ └── armeabi-v7a │ │ └── libxhook.so ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── checknativehook │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── cpp │ │ ├── CMakeLists.txt │ │ ├── got.cpp │ │ ├── got.h │ │ ├── log.h │ │ ├── native-lib.cpp │ │ ├── test.c │ │ ├── test.h │ │ ├── util.cpp │ │ ├── util.h │ │ └── xhook.h │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── checknativehook │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── 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 │ │ ├── values-night │ │ └── themes.xml │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── example │ └── checknativehook │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | local.properties 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 检测got hook(使用xhook测试) 2 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | } 4 | 5 | android { 6 | compileSdkVersion 30 7 | buildToolsVersion "30.0.3" 8 | 9 | defaultConfig { 10 | applicationId "com.example.checknativehook" 11 | minSdkVersion 16 12 | targetSdkVersion 30 13 | versionCode 1 14 | versionName "1.0" 15 | 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | externalNativeBuild { 18 | cmake { 19 | arguments "-DANDROID_ARM_MODE=arm" 20 | arguments '-DANDROID_TOOLCHAIN=clang' 21 | arguments "-DANDROID_STL=c++_static" 22 | cppFlags "-std=c++11" 23 | } 24 | } 25 | ndk { 26 | abiFilters 'armeabi-v7a', 'arm64-v8a' 27 | //abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a' 28 | } 29 | } 30 | 31 | buildTypes { 32 | release { 33 | minifyEnabled false 34 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 35 | } 36 | } 37 | externalNativeBuild { 38 | cmake { 39 | path "src/main/cpp/CMakeLists.txt" 40 | // version "3.10.2" 41 | } 42 | } 43 | compileOptions { 44 | sourceCompatibility JavaVersion.VERSION_1_8 45 | targetCompatibility JavaVersion.VERSION_1_8 46 | } 47 | } 48 | 49 | dependencies { 50 | 51 | implementation 'androidx.appcompat:appcompat:1.3.1' 52 | implementation 'com.google.android.material:material:1.4.0' 53 | implementation 'androidx.constraintlayout:constraintlayout:2.1.0' 54 | testImplementation 'junit:junit:4.+' 55 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 56 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 57 | } -------------------------------------------------------------------------------- /app/libs/arm64-v8a/libxhook.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SliverBullet5563/CheckGotHook/10d988429f5212d21afc16bcc1b46c0d3cc96eeb/app/libs/arm64-v8a/libxhook.so -------------------------------------------------------------------------------- /app/libs/armeabi-v7a/libxhook.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SliverBullet5563/CheckGotHook/10d988429f5212d21afc16bcc1b46c0d3cc96eeb/app/libs/armeabi-v7a/libxhook.so -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/checknativehook/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.checknativehook; 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.example.checknativehook", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about using CMake with Android Studio, read the 2 | # documentation: https://d.android.com/studio/projects/add-native-code.html 3 | 4 | # Sets the minimum version of CMake required to build the native library. 5 | 6 | cmake_minimum_required(VERSION 3.10.2) 7 | 8 | # Declares and names the project. 9 | 10 | project("checknativehook") 11 | # Creates and names a library, sets it as either STATIC 12 | # or SHARED, and provides the relative paths to its source code. 13 | # You can define multiple libraries, and CMake builds them for you. 14 | # Gradle automatically packages shared libraries with your APK. 15 | #include_directories("D:\\android-ndk-r16b\\sysroot\\usr\\include") 16 | add_definitions(-fvisibility=hidden) 17 | 18 | add_library(xhook SHARED IMPORTED) 19 | set_target_properties(xhook 20 | PROPERTIES IMPORTED_LOCATION 21 | ${CMAKE_SOURCE_DIR}/../../../libs/${ANDROID_ABI}/libxhook.so) 22 | 23 | add_library( # Sets the name of the library. 24 | native-lib 25 | 26 | # Sets the library as a shared library. 27 | SHARED 28 | 29 | # Provides a relative path to your source file(s). 30 | native-lib.cpp test.c util.cpp got.cpp) 31 | 32 | # Searches for a specified prebuilt library and stores the path as a 33 | # variable. Because CMake includes system libraries in the search path by 34 | # default, you only need to specify the name of the public NDK library 35 | # you want to add. CMake verifies that the library exists before 36 | # completing its build. 37 | 38 | find_library( # Sets the name of the path variable. 39 | log-lib 40 | 41 | # Specifies the name of the NDK library that 42 | # you want CMake to locate. 43 | log ) 44 | 45 | # Specifies libraries CMake should link to your target library. You 46 | # can link multiple libraries, such as libraries you define in this 47 | # build script, prebuilt third-party libraries, or system libraries. 48 | 49 | target_link_libraries( # Specifies the target library. 50 | native-lib 51 | xhook 52 | # Links the target library to the log library 53 | # included in the NDK. 54 | ${log-lib} ) -------------------------------------------------------------------------------- /app/src/main/cpp/got.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Administrator on 2021/9/7. 3 | // 4 | 5 | #include "got.h" 6 | 7 | namespace GOTCheck{ 8 | 9 | 10 | GOT::GOT(u32 head,u32 end): head(head),end(end) { 11 | 12 | } 13 | 14 | GOT::~GOT() { 15 | 16 | } 17 | 18 | bool GOT::checkHook() { 19 | 20 | return false; 21 | } 22 | 23 | uaddr GOT::getgotitem(uaddr lib_addr,int idx) const { 24 | uaddr got_addr = lib_addr + head; 25 | uaddr cur_addr = 0; 26 | #ifdef __arm__ 27 | cur_addr = got_addr + 4 * idx; 28 | #elif __aarch64__ 29 | cur_addr = got_addr + 8 * idx; 30 | #endif 31 | return cur_addr; 32 | } 33 | 34 | uaddr GOT::getsymaddr(uaddr libAddr, const char* symname) { 35 | // 查找符号地址 36 | uaddr item_addr = 0; 37 | u32 item_hash = 0; 38 | ElfW(Ehdr) *ehdr; 39 | ElfW(Phdr) *phdr; 40 | // check 41 | if(0 == libAddr){ 42 | LOGD("getsymaddr(),fail.\n"); 43 | return 0; 44 | } 45 | 46 | ehdr = (ElfW(Ehdr) *)libAddr; //ELF文件头 47 | phdr = (ElfW(Phdr)*)(libAddr + ehdr->e_phoff); //ELF程序头表 48 | 49 | ElfW(Dyn) *p_dynamic = NULL; 50 | // 查找PT_DYNAMIC 51 | for (u32 k = 0; k < ehdr->e_phnum; ++k) { 52 | if(PT_DYNAMIC==phdr->p_type) { 53 | p_dynamic = (ElfW(Dyn)*)(phdr->p_vaddr + libAddr); 54 | break; 55 | } 56 | ++phdr; 57 | }//for 58 | if( p_dynamic == NULL ){ 59 | LOGD("getItemAddr() NULL==p_dynamic ,fail.\n"); 60 | return false; 61 | } 62 | 63 | ElfW(Dyn)* d = NULL; 64 | ElfW(Sym)* p_symtab = NULL; 65 | 66 | uaddr gnu_hash = 0; 67 | size_t gnu_nbucket_ = NULL; 68 | u32* gnu_bucket_ = NULL; 69 | u32 gnu_maskwords_ = NULL; 70 | u32* gnu_chain_ = NULL; 71 | ElfW(Addr)* gnu_bloom_filter_ = NULL; 72 | 73 | char* strtab = NULL; 74 | u64 strz = 0; 75 | 76 | 77 | u32 hash = 0; 78 | u32* p_bucket = NULL; 79 | u32* p_chain = NULL; 80 | u32 nbucket = 0; 81 | 82 | // linker.cpp -> prelink_image() 83 | for(d = p_dynamic; DT_NULL != d->d_tag; ++d) { 84 | if(d->d_tag == DT_SYMTAB) { 85 | p_symtab = (ElfW(Sym)*)(d->d_un.d_ptr + libAddr); 86 | } 87 | 88 | if(d->d_tag == DT_HASH) { 89 | hash = (u32)(d->d_un.d_ptr + libAddr); 90 | nbucket = *((u32*)hash); 91 | p_bucket = (u32*)(hash+8); 92 | p_chain = (u32*)(hash + 4 * (2 + nbucket)); 93 | } 94 | 95 | if (d->d_tag == DT_GNU_HASH) { 96 | gnu_hash = (d->d_un.d_ptr + libAddr); 97 | gnu_nbucket_ = reinterpret_cast(gnu_hash)[0]; 98 | // skip symndx 99 | gnu_maskwords_ = reinterpret_cast(gnu_hash)[2]; 100 | gnu_bloom_filter_ = reinterpret_cast(gnu_hash + 16); 101 | gnu_bucket_ = reinterpret_cast(gnu_bloom_filter_ + gnu_maskwords_); 102 | 103 | // amend chain for symndx = header[1] 104 | gnu_chain_ = gnu_bucket_ + gnu_nbucket_ - reinterpret_cast(gnu_hash)[1]; 105 | } 106 | if(d->d_tag == DT_STRTAB) { 107 | strtab = (char*)(d->d_un.d_ptr + libAddr); 108 | } 109 | if(d->d_tag == DT_STRSZ) { 110 | strz = (u64)(d->d_un.d_val); 111 | } 112 | }//for 113 | if( NULL==p_symtab || NULL==strtab || 0==strz ){ 114 | LOGD("getItemAddr,fail.\n"); 115 | return false; 116 | } 117 | 118 | //gnu hash 段 arm64下so没有hash段,使用gnu hash 119 | if (gnu_hash != 0){ 120 | item_hash = dl_gnu_hash(symname); 121 | u32 n = gnu_bucket_[item_hash % gnu_nbucket_]; 122 | do { 123 | ElfW(Sym)* s = p_symtab + n; 124 | 125 | if(dl_gnu_hash(strtab + s->st_name) == item_hash){ 126 | item_addr = libAddr + s->st_value; 127 | break; 128 | } 129 | } while ((gnu_chain_[n++] & 1) == 0); 130 | } else { //hash段,armv7下有so没有gnu hash段,使用hash 131 | item_hash = elfhash(symname); 132 | int mod = (item_hash % nbucket); 133 | for(int i = p_bucket[mod]; i != 0; i = p_chain[i]) { 134 | if(elfhash(strtab + (p_symtab + i)->st_name) == item_hash) { 135 | item_addr = libAddr + (p_symtab + i)->st_value; 136 | break; 137 | } 138 | }//for 139 | } 140 | 141 | // 清理内存 142 | ehdr = NULL; 143 | phdr = NULL; 144 | p_dynamic = NULL; 145 | d = NULL; 146 | p_symtab = NULL; 147 | strtab = NULL; 148 | strz = 0; 149 | return item_addr; 150 | } 151 | } -------------------------------------------------------------------------------- /app/src/main/cpp/got.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Administrator on 2021/9/7. 3 | // 4 | #ifndef CHECKNATIVEHOOK_GOT_H 5 | #define CHECKNATIVEHOOK_GOT_H 6 | 7 | #include 8 | #include "util.h" 9 | 10 | 11 | using namespace std; 12 | namespace GOTCheck{ 13 | 14 | class GOT 15 | { 16 | public: 17 | GOT(u32 head,u32 end); 18 | ~GOT(); 19 | bool checkHook(); 20 | 21 | public: 22 | uaddr getgotitem(uaddr lib_addr, int idx) const; // 返回运行时idx项got地址里的地址内容 23 | uaddr getsymaddr(uaddr libAddr, const char* symname); // 返回运行时依赖库函数地址 24 | private: 25 | u32 head; // GOT表起始偏移(预设) 26 | u32 end; // GOT表结束偏移(预设) 27 | }; 28 | } 29 | #endif //CHECKNATIVEHOOK_GOT_H 30 | -------------------------------------------------------------------------------- /app/src/main/cpp/log.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Administrator on 2021/9/10. 3 | // 4 | 5 | #ifndef CHECKNATIVEHOOK_LOG_H 6 | #define CHECKNATIVEHOOK_LOG_H 7 | 8 | #include 9 | #define LOG_TAG "CheckHook_TAG" 10 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) 11 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 12 | 13 | #endif //CHECKNATIVEHOOK_LOG_H 14 | -------------------------------------------------------------------------------- /app/src/main/cpp/native-lib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "test.h" 5 | #include "got.h" 6 | #include "xhook.h" 7 | #include 8 | 9 | using namespace GOTCheck; 10 | 11 | void* (*oldmalloc)(size_t __byte_count); 12 | extern "C" JNIEXPORT jstring JNICALL 13 | Java_com_example_checknativehook_MainActivity_stringFromJNI( 14 | JNIEnv* env, 15 | jobject /* this */,jboolean startGotHook) { 16 | std::string hello = "Hello from C++"; 17 | 18 | //开启GOT Hook 19 | if (startGotHook){ 20 | xhook_register(".*/libnative-lib\\.so$", "malloc", (void *)(my_malloc), (void**)(&oldmalloc)); 21 | xhook_refresh(1); 22 | } 23 | 24 | uaddr lib_Addr = getLibAddr("libnative-lib.so"); 25 | LOGD("libnative_addr = 0x%lx", lib_Addr); 26 | //计算libc中malloc内存的地址 27 | uaddr libc_Addr = getLibAddr("libc.so"); 28 | LOGD("libc_addr = 0x%lx", libc_Addr); 29 | 30 | 31 | //预设got起始地址,导入表函数位置 32 | u32 head = 0; 33 | u32 end = 0; 34 | int idx = 0; 35 | #ifdef __arm__ 36 | head = 0x76F94; 37 | idx = 194; 38 | #elif __aarch64__ 39 | head = 0xC8010; //got起始地址 40 | idx = 82; //malloc项 41 | #endif 42 | 43 | GOT* got = new GOT(head, end); 44 | // 返回运行时got地址里的地址内容 45 | uaddr item_addr = got->getgotitem(lib_Addr, idx); 46 | LOGD("item_addr = 0x%lx",item_addr); 47 | LOGD("item_addr pointer content = 0x%lx",*(uaddr *)item_addr); 48 | //返回运行时依赖库函数地址 49 | uaddr malloc_addr = got->getsymaddr(libc_Addr,"malloc"); 50 | 51 | LOGD("libc malloc_addr = 0x%lx",malloc_addr); 52 | 53 | //比较got表里的地址,和实际导入函数的地址是否相同 54 | if (*(uaddr *)item_addr != malloc_addr){ 55 | LOGE("检测到libc.so malloc 被GOT hook!被hook的地址 0x%lx",*(uaddr *)item_addr); 56 | hello.append(" 检测到GOT hook, hook地址为 "); 57 | stringstream ss1; 58 | ss1 << *(uaddr *)item_addr; 59 | hello.append(ss1.str()); 60 | } else{ 61 | hello.append(" 对malloc 未检测到GOT hook"); 62 | } 63 | 64 | 65 | say_hello(); 66 | delete got; 67 | return env->NewStringUTF(hello.c_str()); 68 | } -------------------------------------------------------------------------------- /app/src/main/cpp/test.c: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Administrator on 2021/9/7. 3 | // 4 | #include "test.h" 5 | void* (*oldmalloc)(size_t __byte_count); 6 | void *my_malloc(size_t size) 7 | { 8 | LOGE("%zu bytes memory are allocated by libnative-lib.so\n", size); 9 | return oldmalloc(size); 10 | } 11 | 12 | void say_hello() 13 | { 14 | char *buf = malloc(512); 15 | if(NULL != buf) 16 | { 17 | snprintf(buf, 1024, "%s", "hello\n"); 18 | LOGD("say_hello %s", buf); 19 | } 20 | } -------------------------------------------------------------------------------- /app/src/main/cpp/test.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Administrator on 2021/9/7. 3 | // 4 | #pragma once 5 | #ifndef CHECKNATIVEHOOK_TEST_H 6 | #define CHECKNATIVEHOOK_TEST_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "log.h" 13 | 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | void *my_malloc(size_t size); 20 | void say_hello(); 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | #endif //CHECKNATIVEHOOK_TEST_H 26 | -------------------------------------------------------------------------------- /app/src/main/cpp/util.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Administrator on 2021/9/10. 3 | // 4 | 5 | #include "util.h" 6 | 7 | uaddr getLibAddr(const char* name){ 8 | u64 ret = 0; 9 | char buf[4096], *temp; 10 | int pid; 11 | FILE *fp; 12 | pid = getpid(); 13 | sprintf(buf, "/proc/%d/maps", pid); 14 | fp = fopen(buf, "r"); 15 | if(fp == NULL) 16 | { 17 | puts("open failed"); 18 | goto _error; 19 | } 20 | while(fgets(buf, sizeof(buf), fp)){ 21 | if(strstr(buf, name)){ 22 | temp = strtok(buf, "-"); 23 | ret = strtoul(temp, NULL, 16); 24 | break; 25 | } 26 | } 27 | _error: 28 | fclose(fp); 29 | return ret; 30 | } 31 | 32 | u32 elfhash(const char* input){ 33 | const char* s = input; 34 | u32 h = 0, g = 0; 35 | while(*s) { 36 | h = (h << 4) + *s++; 37 | g = h & 0xf0000000; 38 | h ^= g; 39 | h ^= g >> 24; 40 | } 41 | return h; 42 | } 43 | 44 | u32 dl_gnu_hash (const char *s){ 45 | u32 h = 5381; 46 | for (unsigned char c = *s; c != '\0'; c = *++s) 47 | h = ((h << 5) + h) + c; // h = h * 33 + c 48 | 49 | 50 | return h; 51 | } -------------------------------------------------------------------------------- /app/src/main/cpp/util.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Administrator on 2021/9/10. 3 | // 4 | 5 | #ifndef CHECKNATIVEHOOK_UTIL_H 6 | #define CHECKNATIVEHOOK_UTIL_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "log.h" 19 | 20 | typedef uint32_t u32; 21 | typedef uint64_t u64; 22 | 23 | #ifdef __arm__ 24 | typedef u32 uaddr; 25 | #define ElfW(type) Elf32_ ## type 26 | #elif __aarch64__ 27 | typedef u64 uaddr; 28 | #define ElfW(type) Elf64_ ## type 29 | #endif 30 | 31 | 32 | uaddr getLibAddr(const char* name); 33 | u32 elfhash(const char* input); 34 | u32 dl_gnu_hash (const char *s); 35 | 36 | #endif //CHECKNATIVEHOOK_UTIL_H 37 | -------------------------------------------------------------------------------- /app/src/main/cpp/xhook.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in all 11 | // copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | // SOFTWARE. 20 | // 21 | 22 | // Created by caikelun on 2018-04-11. 23 | 24 | #ifndef XHOOK_H 25 | #define XHOOK_H 1 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #define XHOOK_EXPORT __attribute__((visibility("default"))) 32 | 33 | int xhook_register(const char *pathname_regex_str, const char *symbol, 34 | void *new_func, void **old_func) XHOOK_EXPORT; 35 | 36 | int xhook_ignore(const char *pathname_regex_str, const char *symbol) XHOOK_EXPORT; 37 | 38 | int xhook_refresh(int async) XHOOK_EXPORT; 39 | 40 | void xhook_clear() XHOOK_EXPORT; 41 | 42 | void xhook_enable_debug(int flag) XHOOK_EXPORT; 43 | 44 | void xhook_enable_sigsegv_protection(int flag) XHOOK_EXPORT; 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/checknativehook/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.checknativehook; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.TextView; 9 | 10 | public class MainActivity extends AppCompatActivity { 11 | 12 | // Used to load the 'native-lib' library on application startup. 13 | static { 14 | System.loadLibrary("native-lib"); 15 | } 16 | 17 | Button got_btn; 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_main); 23 | 24 | // Example of a call to a native method 25 | TextView tv = findViewById(R.id.sample_text); 26 | got_btn = findViewById(R.id.got_btn); 27 | got_btn.setOnClickListener(new View.OnClickListener() { 28 | @Override 29 | public void onClick(View v) { 30 | tv.setText(stringFromJNI(true)); 31 | } 32 | }); 33 | 34 | 35 | tv.setText(stringFromJNI(false)); 36 | } 37 | 38 | /** 39 | * A native method that is implemented by the 'native-lib' native library, 40 | * which is packaged with this application. 41 | */ 42 | public native String stringFromJNI(boolean startGotHook); 43 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 |