├── LICENSE ├── README.md ├── app ├── build.gradle ├── debug.keystore ├── proguard-android.txt ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── CMakeLists.txt │ └── native-lib.cpp │ ├── java │ └── com │ │ └── github │ │ └── qs00019 │ │ └── messnative │ │ ├── MainActivity.java │ │ └── TestSo.java │ └── res │ ├── layout │ └── activity_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── bintray_groovy.gradle ├── build.gradle ├── buildSrc ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── groovy │ └── com │ │ └── github │ │ └── qs00019 │ │ └── messnative │ │ ├── MessExtension.groovy │ │ ├── MessPlugin.groovy │ │ └── RewriteNativeTask.groovy │ └── resources │ └── META-INF │ └── gradle-plugins │ └── com.github.qs00019.messnative.properties ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── maven_localserver.gradle ├── pic.jpg └── settings.gradle /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 eleme 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MessNative 2 | 3 | ## 背景 4 | Android JNI接口混淆方案。以下文章描述了java暴露jni接口的问题 5 | https://www.jianshu.com/p/0350cb715934 6 | https://www.jianshu.com/p/676861ca29fd 7 | 8 | 本项目参考了Mess,对java与native交互的类和方法进行了混淆,然后改变RegisterNatives注册java的方法字符串为混淆后的字符串,达到混淆native方法的目的。实现原理见 9 | https://www.jianshu.com/p/799e5bc62633 10 | 11 | 12 | ## 使用方法 13 | 14 | ```groovy 15 | 16 | dependencies { 17 | classpath 'com.android.tools.build:gradle:3.3.0' 18 | classpath 'com.github.qs00019:messnative:1.0.2' 19 | } 20 | 21 | apply plugin: 'com.android.application' 22 | apply plugin: 'com.github.qs00019.messnative' 23 | 24 | //java类名和C中动态注册的文件名 25 | messnative { 26 | //匹配混淆的类 27 | classAndNativesMap = [["com.github.qs00019.messnative.TestSo","src/main/cpp/native-lib.cpp"]] 28 | //匹配混淆类的方法 29 | classAllMethodAndNatives = [["com.github.qs00019.messnative.TestSo","src/main/cpp/native-lib.cpp"]] 30 | } 31 | 32 | ``` 33 | 34 | 复制android SDK下proguard目录下的proguard-android.txt到当前目录,需要注释native方法的默认混淆 35 | ``` 36 | #-keepclasseswithmembernames class * { 37 | # native ; 38 | #} 39 | ``` 40 | 41 | build.gradle中修改 42 | ``` 43 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 44 | ``` 45 | ``` 46 | proguardFiles 'proguard-android.txt', 'proguard-rules.pro' 47 | ``` 48 | 49 | 50 | ## 注意 51 | 在C中替换java方法名时,groovy返回的methodSignature是java语法,C里动态注册用的是smali语法。当前版本未做方法签名判断,所以有方法重写是,替换回出错。 52 | 53 | ## Sample示例 54 | 示例工程混淆后反编译,SoTest类的方法被混淆 55 | ![示例图片](https://github.com/qs00019/MessNative/blob/master/pic.jpg) 56 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.github.qs00019.messnative' 3 | 4 | android { 5 | compileSdkVersion 28 6 | buildToolsVersion "28.0.3" 7 | defaultConfig { 8 | applicationId "com.github.qs00019.messnative" 9 | minSdkVersion 15 10 | targetSdkVersion 28 11 | versionCode 1 12 | versionName "1.0" 13 | externalNativeBuild { 14 | cmake { 15 | cppFlags "" 16 | abiFilters 'armeabi-v7a' 17 | } 18 | } 19 | } 20 | externalNativeBuild { 21 | cmake { 22 | path "src/main/cpp/CMakeLists.txt" 23 | } 24 | } 25 | 26 | signingConfigs { 27 | debug { 28 | storeFile file("${project.projectDir}/debug.keystore") 29 | keyAlias 'androiddebugkey' 30 | keyPassword 'android' 31 | storePassword 'android' 32 | } 33 | } 34 | buildTypes { 35 | release { 36 | minifyEnabled true 37 | shrinkResources true 38 | proguardFiles 'proguard-android.txt', 'proguard-rules.pro' 39 | signingConfig signingConfigs.debug 40 | } 41 | } 42 | } 43 | 44 | dependencies { 45 | compile fileTree(dir: 'libs', include: ['*.jar']) 46 | compile 'com.android.support:appcompat-v7:25.3.0' 47 | compile "com.android.support:recyclerview-v7:25.3.0" 48 | } 49 | 50 | messnative { 51 | classAndNativesMap = [["com.github.qs00019.messnative.TestSo","src/main/cpp/native-lib.cpp"]] 52 | classAllMethodAndNatives = [["com.github.qs00019.messnative.TestSo","src/main/cpp/native-lib.cpp"]] 53 | } 54 | -------------------------------------------------------------------------------- /app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qs00019/MessNative/eb490e6fac7c62aa10216b8f00e754ef52a1c8e4/app/debug.keystore -------------------------------------------------------------------------------- /app/proguard-android.txt: -------------------------------------------------------------------------------- 1 | # This is a configuration file for ProGuard. 2 | # http://proguard.sourceforge.net/index.html#manual/usage.html 3 | # 4 | # This file is no longer maintained and is not used by new (2.2+) versions of the 5 | # Android plugin for Gradle. Instead, the Android plugin for Gradle generates the 6 | # default rules at build time and stores them in the build directory. 7 | 8 | -dontusemixedcaseclassnames 9 | -dontskipnonpubliclibraryclasses 10 | -verbose 11 | 12 | # Optimization is turned off by default. Dex does not like code run 13 | # through the ProGuard optimize and preverify steps (and performs some 14 | # of these optimizations on its own). 15 | -dontoptimize 16 | -dontpreverify 17 | # Note that if you want to enable optimization, you cannot just 18 | # include optimization flags in your own project configuration file; 19 | # instead you will need to point to the 20 | # "proguard-android-optimize.txt" file instead of this one from your 21 | # project.properties file. 22 | 23 | -keepattributes *Annotation* 24 | -keep public class com.google.vending.licensing.ILicensingService 25 | -keep public class com.android.vending.licensing.ILicensingService 26 | 27 | # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native 28 | #-keepclasseswithmembernames class * { 29 | # native ; 30 | #} 31 | 32 | # keep setters in Views so that animations can still work. 33 | # see http://proguard.sourceforge.net/manual/examples.html#beans 34 | -keepclassmembers public class * extends android.view.View { 35 | void set*(***); 36 | *** get*(); 37 | } 38 | 39 | # We want to keep methods in Activity that could be used in the XML attribute onClick 40 | -keepclassmembers class * extends android.app.Activity { 41 | public void *(android.view.View); 42 | } 43 | 44 | # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations 45 | -keepclassmembers enum * { 46 | public static **[] values(); 47 | public static ** valueOf(java.lang.String); 48 | } 49 | 50 | -keepclassmembers class * implements android.os.Parcelable { 51 | public static final android.os.Parcelable$Creator CREATOR; 52 | } 53 | 54 | -keepclassmembers class **.R$* { 55 | public static ; 56 | } 57 | 58 | # The support library contains references to newer platform versions. 59 | # Don't warn about those in case this app is linking against an older 60 | # platform version. We know about them, and they are safe. 61 | -dontwarn android.support.** 62 | 63 | # Understand the @Keep support annotation. 64 | -keep class android.support.annotation.Keep 65 | 66 | -keep @android.support.annotation.Keep class * {*;} 67 | 68 | -keepclasseswithmembers class * { 69 | @android.support.annotation.Keep ; 70 | } 71 | 72 | -keepclasseswithmembers class * { 73 | @android.support.annotation.Keep ; 74 | } 75 | 76 | -keepclasseswithmembers class * { 77 | @android.support.annotation.Keep (...); 78 | } 79 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | -dontshrink 20 | -optimizationpasses 5 21 | -verbose 22 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #优化配置 23 | -ignorewarnings #忽略警告 24 | #-keep class com.github.qs00019.messnative.TestSo -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /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.4.1) 7 | 8 | # Creates and names a library, sets it as either STATIC 9 | # or SHARED, and provides the relative paths to its source code. 10 | # You can define multiple libraries, and CMake builds them for you. 11 | # Gradle automatically packages shared libraries with your APK. 12 | 13 | add_library( # Sets the name of the library. 14 | native-lib 15 | 16 | # Sets the library as a shared library. 17 | SHARED 18 | 19 | # Provides a relative path to your source file(s). 20 | native-lib.cpp ) 21 | 22 | # Searches for a specified prebuilt library and stores the path as a 23 | # variable. Because CMake includes system libraries in the search path by 24 | # default, you only need to specify the name of the public NDK library 25 | # you want to add. CMake verifies that the library exists before 26 | # completing its build. 27 | 28 | find_library( # Sets the name of the path variable. 29 | log-lib 30 | 31 | # Specifies the name of the NDK library that 32 | # you want CMake to locate. 33 | log ) 34 | 35 | # Specifies libraries CMake should link to your target library. You 36 | # can link multiple libraries, such as libraries you define in this 37 | # build script, prebuilt third-party libraries, or system libraries. 38 | 39 | target_link_libraries( # Specifies the target library. 40 | native-lib 41 | 42 | # Links the target library to the log library 43 | # included in the NDK. 44 | ${log-lib} ) -------------------------------------------------------------------------------- /app/src/main/cpp/native-lib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern "C" JNIEXPORT jstring JNICALL 5 | printHelloMethod(JNIEnv *env, jclass type, jstring input) { 6 | return input; 7 | } 8 | 9 | 10 | const JNINativeMethod gMethods[] = { 11 | {"printHello","(Ljava/lang/String;)Ljava/lang/String;",(void *) printHelloMethod}, 12 | }; 13 | 14 | 15 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { 16 | 17 | //LOGD("JNI_OnLoad"); 18 | JNIEnv *env = NULL; 19 | jint result = -1; 20 | if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) { 21 | //LOGD("GetEnv Error"); 22 | return -1; 23 | } 24 | const char *gClassName = "com/github/qs00019/messnative/TestSo"; 25 | jclass myClass = env->FindClass(gClassName); 26 | if (myClass == NULL) { 27 | //LOGD("cannot get class:%s", gClassName); 28 | return -1; 29 | } 30 | if (env->RegisterNatives(myClass, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) < 31 | 0) { 32 | //LOGD("register native method failed!"); 33 | return -1; 34 | } 35 | 36 | return JNI_VERSION_1_6; 37 | 38 | } 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/qs00019/messnative/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.github.qs00019.messnative; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.View; 6 | import android.widget.EditText; 7 | import android.widget.Toast; 8 | 9 | 10 | public class MainActivity extends AppCompatActivity { 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.activity_main); 16 | final EditText edit = (EditText)findViewById(R.id.edit); 17 | findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { 18 | @Override 19 | public void onClick(View view) { 20 | Toast.makeText(MainActivity.this,TestSo.printHello(edit.getText().toString()),Toast.LENGTH_SHORT).show(); 21 | } 22 | }); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/qs00019/messnative/TestSo.java: -------------------------------------------------------------------------------- 1 | package com.github.qs00019.messnative; 2 | 3 | 4 | 5 | public class TestSo { 6 | static { 7 | System.loadLibrary("native-lib"); 8 | } 9 | 10 | public static native String printHello(String input); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 |