Android so库的生成和调用

521 阅读2分钟

接到需求说我们APP的加密被破解了,需要更换私钥的存储方式。我说反编译可以直接看到源码,不可能完全阻止他们破解,只能说增加复杂度,建议使用付费版加壳。产品说那就加一下复杂度吧,好家伙,是时候掏出大学里学的C++了,虽然完全没印象。

下面是一些实战细节,全靠CV大法。

环境

  • Android Studio 4.1.3
  • Gradle 4.1.3
  • Cmake 3.10.2
  • ndk 21.1.6352462
  • buildToolsVersion 30.0.3
  1. 配置app/build.gradle
// app/build.gradle
defaultConfig {
    ...
    //设置NDK版本(生成动态so库的时候要用)
    ndkVersion "21.1.6352462"
    // gradle 执行的任务名字
    externalNativeBuild {
        cmake {
            cppFlags ""
            // 过滤生成的库类型
//                abiFilters 'armeabi-v7a'
            //  库格式'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }
    }
}

//生成指定版本的 CMakeLists.txt 文件
externalNativeBuild {
    cmake {
        path "src/main/cpp/CMakeLists.txt"
        version "3.10.2"
    }
}
  1. 创建cpp/xx

  1. CMakeLists.txt
# 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的最低版本
cmake_minimum_required(VERSION 3.10.2)

#这些 privateKey.cpp资源打包设置成一个名为bugly 的共享库(SHARED 替换为STATIC则设置为静态库)
#  privateKey.cpp
add_library( # Sets the name of the library.
        bugly
        # Sets the library as a shared library.
        SHARED
        # Provides a relative path to your source file(s).
        privateKey.cpp )

# 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.

#(设置要链接的库文件的名称 bugly)
target_link_libraries( # Specifies the target library.
        bugly

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib} )
  1. privateKey.cpp

注意方法名必须和java中的路径对应

#include <jni.h>
#include <string>

extern "C"
JNIEXPORT jstring JNICALL Java_com_jed_frame_utils_MyJniUtil_keyFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string token = "Hello Jed, love you o!!";
    return env->NewStringUTF(token.c_str());
}

  1. 调用
String content = MyJniUtil.keyFromJNI();
Log.d(TAG, "onClick: " + content);

这个时候已经可以运行了,现在我们要把c++代码生成so库

  1. 更新gradle方法

  1. 运行生成so库的方法

  1. 把so库拷贝到项目中

在app/src/main文件夹下新建jniLibs文件夹,将我们的So库复制到jniLibs文件夹中

(注意:Android Studio只能识别jniLibs文件夹中So库,如果需要改变So库的识别路径,可以在app/build.gradle中指定jniLibs.srcDir)

    sourceSets.main {
        jniLibs.srcDir 'src/main/jni_libs'
    }

image.png

  1. 删除so库以外的东西,build.gradle中的配置,cpp文件等等