我们在做移动安全的过程中,会遇到so文件,那么so文件到底是什么?它是如何调用的?它与java代码有什么关系?
1.新建Android Studio项目,并新建JniTest类
JniTest.java
package com.sy.sohelloworld;
public class JniTest {
static {
System.loadLibrary("JniTest");
}
public native static String getString();
}
之后make project,在app/build目录下会生成.class文件。
2. 在app/src/main文件夹下新建jni文件夹,在Android Studio的终端进入该目录下,执行以下命令,会在当前目录生成com_sy_sohelloworld_JniTest.h文件:
javah -jni -classpath D:\AndroidHome\workspace\SoHelloWorld\app\build\intermediates\javac\debug\classes com.sy.sohelloworld.JniTest
3.在jni目录下新建test.c文件,并且实现之前.h文件中的方法。
#include "jni.h"
#include "com_sy_sohelloworld_JniTest.h"
JNIEXPORT jstring JNICALL Java_com_sy_sohelloworld_JniTest_getString
(JNIEnv *env, jclass jz){
return (*env)->NewStringUTF(env,"flag is {21232f297a57a5a743894a0e4a801fc3}");
}
4. 利用ndk-build命令来生成.so文件,必须有Android.mk文件和Android.mk文件,并且与对应的.cpp/.c文件在同一个目录下。
Android.mk文件用于向构建系统描述源文件和共享库,用于定义 Application.mk、构建系统和环境变量所未定义的项目范围设置。Application.mk 文件实际上是定义要编译的多个变量的微小 GNU Makefile 片段。
(1)在jni目录下新建Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JniTest
LOCAL_SRC_FILES := Test.c
include $(BUILD_SHARED_LIBRARY)
(2)在jni目录下新建Application.mk文件
APP_ABI := all
(3)关联下载好的ndk包
(4)将ndk-build添加到环境变量中,之后cmd进入到jni目录下,执行命令ndk-build,成功生成so文件。
5.调用so文件
(1)在app/build.gradle文件添加如下配置:
sourceSets {
main() {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //屏蔽默认的jni编译生成过程
}
}
(2)在layout/activity_main.xml文件添加如下代码:
android:id="@+id/textView"
(3)在MainActivity中调用
package com.sy.sohelloworld;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
textView.setText(JniTest.getString());
}
}
6.编译运行,如下所示: