so层获取Java层的字段和静态字段
一、编写java代码
1.java代码定义字段名称以及类型,一个静态一个非静态 //普通字段
public String testStr = "java普通字段";
//静态字段
public static String staticTtestStr = "java静态字段";
二、使用javah生成c的头部文件
1.生成头文件,来到java的源码目录,ADT下来到src目录,AndroidStudio来到蓝色文件夹目录即java执行以下命令:
//javah 包名+类名,会自动生成.h文件包含类里面的所有被native修饰的方法
javah com.example.mypc.myxphook.MainActivity
2.如果报以下错误(错误: 编码GBK的不可映射字符)可尝试加入参数://javah -encoding UTF-8 包名加类名
javah -encoding UTF-8 com.example.mypc.myxphook.MainActivity
4.重命名.h文件并移动到src同级的jni目录(我这里重命名testJni.h)并创建.c文件
三、编写c代码
1.默认创建完的文件是空的,需要引入javah生成的.h文件改名后再头部使用#includ引入,然后把头文件内的方法复制过来,尾部的分号删除,加上花括号{}然后在花括号内写实现代码,这里简单实现获取java层的字段内容
2.编写c代码引入头文件,复制方法到c文件内,开始编写实现代码.方法最后返回的是一个jobject类型的数据,但是不影响在java内接收.
2.1 获取普通字段内容
2.2获取静态字段内容
友情提示:编写代码的时候从我们最终的目的逆向编写代码,先获取字段,然后在获取字段所需的参数比如jclass,jfieldID,等...
四、附上c的最终代码,以及运行结果
1.c文件代码如下://
// Created by MyPC on 2020/4/14.
//
#include "testJni.h"
//获取JAVA层普通字段值内容,编写顺序从下至上(缺啥找啥)
JNIEXPORT jstring JNICALL Java_com_example_mypc_myxphook_MainActivity_getTestStr
(JNIEnv *env, jobject obj){
//查找Java的Class类返回一个jclass,env 第二个参数为类的路径
//JNI原方法 jclass (*FindClass)(JNIEnv*, const char*);
jclass clazz = (*env)->FindClass(env,"com/example/mypc/myxphook/MainActivity");
//env,obj,字段变量名称,签名也就是类型,L标识类类型,尾部加分号;
//JNI原方法 jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);
jfieldID jfieldId = (*env)->GetFieldID(env,clazz,"testStr","Ljava/lang/String;");
//获取字段 env,obj,字段id
//JNI原方法 jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID);
jobject str = (*env)->GetObjectField(env,obj,jfieldId);
//返回字符串
return str;
}
//获取java层静态字段值内容
JNIEXPORT jstring JNICALL Java_com_example_mypc_myxphook_MainActivity_getStaticTestStr
(JNIEnv *env, jobject obj){
//查找Java的Class类返回一个jclass,env 第二个参数为类的路径
//JNI原方法 jclass (*FindClass)(JNIEnv*, const char*);
jclass clazz = (*env)->FindClass(env,"com/example/mypc/myxphook/MainActivity");
//获取静态字段ID env,obj,字段变量名称,签名也就是类型,L标识类类型,尾部加分号;
//JNI 原方法 jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*, const char*);
jfieldID jfieldId = (*env)->GetStaticFieldID(env, clazz, "staticTtestStr", "Ljava/lang/String;");
//获取静态字段值内容
//JNI原方法 jobject (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);
jobject staticStr = (*env)->GetStaticObjectField(env, clazz, jfieldId);
return staticStr;
}
2.编译(如果使用AndroidStudio配置了jni目录就不需要运行ndk-build否则会报错)打包运行结果如下:
在浏览的同时希望给予作者打赏,来支持作者的服务器维护费用.一分也是爱~