forked from uestccokey/EZProtect
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
like2
authored and
like2
committed
Jan 26, 2022
1 parent
dc60f7a
commit 1127695
Showing
58 changed files
with
2,773 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,70 @@ | ||
# EZProtect | ||
# EZProtect | ||
|
||
一个Native级的Android应用防篡改库 | ||
|
||
去年在开发一个个人项目的过程中,发现自己的应用被人破解修改,并且被二次打包放到了网上,因此对应用安全防护进行了一点研究。 | ||
|
||
虽然市场上大部分App已经进行了代码混淆、签名校验和Dex加固,但是现在的破解工具太方便了。诸如脱壳、去签名、重打包等功能,手机安装MT管理器或者NP管理器后都可以一条龙完成,因此需要继续增加破解难度。 | ||
|
||
国内开发者用的最多的防篡改库可能是 https://github.com/lamster2018/EasyProtector ,该库集成了不少检测方法,但是他的重大缺点就是校验方法放在Java层,使用Xposed等框架可以轻易过掉检测,因此实现了一个Native级的Android应用防篡改库。 | ||
|
||
### 防护能力 | ||
|
||
1.防动态调试 | ||
|
||
2.防逆向分析 | ||
|
||
3.防恶意注入 | ||
|
||
4.防二次打包 | ||
|
||
5.防数据窃取 | ||
|
||
### 检测功能 | ||
|
||
#### 1.检测是否被动态调试 | ||
|
||
有经验的破解者通常会通过IDA等工具来动态调试So,以过掉So库中的检测功能,因此首先需要对动态调试进行拦截,通常采用 | ||
|
||
1.通过ptrace自添加防止被调试器挂载来反调试 | ||
|
||
2.通过系统提供的Debug.isDebuggerConnected()方法来进行判断 | ||
|
||
#### 2.检测APK的签名 | ||
|
||
非常基础的检测手段,因为容易被一键破解,因此需要配合其他手段防御 | ||
|
||
#### 3.检测APK的包名 | ||
|
||
判断opendir("/data/data/CORRECT_PACKAGE_NAME")是否等于nullptr,如果没有指定私有目录的访问权限,说明不是正确的包名 | ||
|
||
#### 4.检测是否被Xposed等框架注入 | ||
|
||
检测"/proc/self/maps"目录下的文件,如果出现包含xposed、substrate、frida等名称的文件,说明有框架正在注入 | ||
|
||
#### 5.检测PMS是否被Hook | ||
|
||
通过检测PMS是否继承Proxy类可以知道是否已被Hook | ||
|
||
#### 6.检测Application的className属性 | ||
|
||
大部分工具都会通过修改入口Application类,并在修改后的Application类中添加各种破解代码来实现去签名校验,它们常常费了很大的劲比如Hook了PMS,同时为了防止你读取原包做文件完整性校验可能还进行了IO重定向,但偏偏忽视了对Application类名的隐藏,经测试该检测可以防御大部分工具的一键破解 | ||
|
||
#### 7.检测Application的allowBackup属性 | ||
|
||
正常情况下应该为false,如果检测到为true,说明应用被Hook了,破解者正在尝试导出应用私有信息 | ||
|
||
#### 8.检测应用版本号 | ||
|
||
破解者为了防止应用更新导致破解失效,通常会修改此versionCode,因此需要进行检测 | ||
|
||
#### 9.检测Native与Java层获取到的APK的文件路径或者大小 | ||
|
||
因为pm命令获取到的APK文件路径通常不容易被修改,这里与通过JavaApi获取到的APK文件路径做比较,如果文件路径或者文件大小不一致时,大概率是应用被IO重定向了,或者使用了VirtualXposed等分身软件 | ||
|
||
#### 10.Apk和So文件完整性校验 | ||
|
||
可以获取到当前APK文件和此加密So包的文件信息用于服务器校验 | ||
|
||
注意,编译时需要使用Ollvm混淆,配置可以参考文章 | ||
https://blog.csdn.net/u013314647/article/details/117740784?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
plugins { | ||
id 'com.android.application' | ||
id 'org.jetbrains.kotlin.android' | ||
} | ||
|
||
android { | ||
compileSdk 31 | ||
|
||
defaultConfig { | ||
applicationId project.applicationId | ||
minSdk 16 | ||
targetSdk 31 | ||
versionCode project.versionCode as int | ||
versionName project.versionName | ||
|
||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
} | ||
|
||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
} | ||
} | ||
compileOptions { | ||
sourceCompatibility JavaVersion.VERSION_1_8 | ||
targetCompatibility JavaVersion.VERSION_1_8 | ||
} | ||
kotlinOptions { | ||
jvmTarget = '1.8' | ||
} | ||
} | ||
|
||
dependencies { | ||
|
||
api project(':app:ezprotect') | ||
implementation 'androidx.core:core-ktx:1.7.0' | ||
implementation 'androidx.appcompat:appcompat:1.3.1' | ||
implementation 'com.google.android.material:material:1.4.0' | ||
implementation 'androidx.constraintlayout:constraintlayout:2.1.1' | ||
testImplementation 'junit:junit:4.13.2' | ||
androidTestImplementation 'androidx.test.ext:junit:1.1.3' | ||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# For more information about using CMake with Android Studio, read the | ||
# documentation: https://d.android.com/studio/projects/add-native-code.html | ||
|
||
# Sets the minimum version of CMake required to build the native library. | ||
|
||
cmake_minimum_required(VERSION 3.18.1) | ||
|
||
#-mllvm -fla 控制流扁平化 | ||
#-mllvm -sub 指令替换 | ||
#-mllvm -bcf 虚假控制流程 | ||
#-mllvm -sobf 字符串加密 | ||
set(CMAKE_CXX_FLAGS "-mllvm -fla -mllvm -sub -mllvm -sobf ${CMAKE_CXX_FLAGS}") | ||
|
||
# Creates and names a library, sets it as either STATIC | ||
# or SHARED, and provides the relative paths to its source code. | ||
# You can define multiple libraries, and CMake builds them for you. | ||
# Gradle automatically packages shared libraries with your APK. | ||
|
||
file(GLOB native_src | ||
"src/main/cpp/util/*.cpp" | ||
"src/main/cpp/protect/*.cpp" | ||
) | ||
add_library( # Sets the name of the library. | ||
ezcore | ||
|
||
# Sets the library as a shared library. | ||
SHARED | ||
|
||
# Provides a relative path to your source file(s). | ||
${native_src}) | ||
|
||
# Searches for a specified prebuilt library and stores the path as a | ||
# variable. Because CMake includes system libraries in the search path by | ||
# default, you only need to specify the name of the public NDK library | ||
# you want to add. CMake verifies that the library exists before | ||
# completing its build. | ||
|
||
find_library( # Sets the name of the path variable. | ||
log-lib | ||
|
||
# Specifies the name of the NDK library that | ||
# you want CMake to locate. | ||
log) | ||
|
||
# Specifies libraries CMake should link to your target library. You | ||
# can link multiple libraries, such as libraries you define in this | ||
# build script, prebuilt third-party libraries, or system libraries. | ||
|
||
target_link_libraries( # Specifies the target library. | ||
ezcore | ||
|
||
# Links the target library to the log library | ||
# included in the NDK. | ||
${log-lib}) | ||
|
||
add_definitions("-fvisibility=hidden") | ||
|
||
# APK签名MD5值 | ||
add_definitions(-DCORRECT_APK_SIGN="${CORRECT_APK_SIGN}") | ||
# APK包名 | ||
add_definitions(-DCORRECT_PACKAGE_NAME="${CORRECT_PACKAGE_NAME}") | ||
# Application名 | ||
add_definitions(-DCORRECT_APPLICATION_NAME="${CORRECT_APPLICATION_NAME}") | ||
# 加固后的Application名 【可选】比如360免费加固后的Application名为com.stub.StubApp | ||
add_definitions(-DCORRECT_APPLICATION_NAME_REINFORCE="") | ||
# 版本号,破解者为了防止应用更新导致破解失效,通常会修改此versionCode,因此进行检测 | ||
add_definitions(-DCORRECT_VERSION_CODE=${CORRECT_VERSION_CODE}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
plugins { | ||
id 'com.android.library' | ||
id 'org.jetbrains.kotlin.android' | ||
} | ||
|
||
android { | ||
compileSdk 31 | ||
|
||
defaultConfig { | ||
minSdk 16 | ||
targetSdk 31 | ||
|
||
consumerProguardFiles "consumer-rules.pro" | ||
externalNativeBuild { | ||
cmake { | ||
arguments "-DANDROID_STL=c++_static", | ||
"-DCORRECT_VERSION_CODE=" + project.versionCode, | ||
"-DCORRECT_APPLICATION_NAME=" + "cn.ezandroid.ezprotect.MyApplication", | ||
"-DCORRECT_PACKAGE_NAME=" + project.applicationId, | ||
"-DCORRECT_APK_SIGN=" + "0f65981c4d8c44aaea1d9e232fbde4b1" | ||
} | ||
} | ||
} | ||
|
||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
} | ||
} | ||
externalNativeBuild { | ||
cmake { | ||
path "CMakeLists.txt" | ||
version "3.18.1" | ||
} | ||
} | ||
compileOptions { | ||
sourceCompatibility JavaVersion.VERSION_1_8 | ||
targetCompatibility JavaVersion.VERSION_1_8 | ||
} | ||
kotlinOptions { | ||
jvmTarget = '1.8' | ||
} | ||
|
||
ndkVersion "21.1.6352462" | ||
} | ||
|
||
dependencies { | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Add project specific ProGuard rules here. | ||
# You can control the set of applied configuration files using the | ||
# proguardFiles setting in build.gradle. | ||
# | ||
# For more details, see | ||
# http://developer.android.com/guide/developing/tools/proguard.html | ||
|
||
# If your project uses WebView with JS, uncomment the following | ||
# and specify the fully qualified class name to the JavaScript interface | ||
# class: | ||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
# public *; | ||
#} | ||
|
||
# Uncomment this to preserve the line number information for | ||
# debugging stack traces. | ||
#-keepattributes SourceFile,LineNumberTable | ||
|
||
# If you keep the line number information, uncomment this to | ||
# hide the original source file name. | ||
#-renamesourcefileattribute SourceFile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest package="cn.ezandroid.ezprotect.lib" /> |
Oops, something went wrong.