1 JNI类型签名
| |
| |
| java中变量---》通过JNI---》转成c变量 |


返回值V,代表void 没有返回值
2 JNI中java调用c案例
2.1 数字处理
Utils.java
| package com.justin.s9day11; |
| public class Utils { |
| static { |
| System.loadLibrary("utils"); |
| } |
| |
| |
| |
| public static native int v1(int a1, int a2); |
| } |
| |
demo.c
| #include <jni.h> |
| |
| |
| |
| JNIEXPORT jint JNICALL |
| Java_com_justin_s9day11_Utils_v1(JNIEnv *env, jclass clazz, jint a1, jint a2) { |
| return a1 + a2; |
| } |
MainActivity.java
| tv.setText(String.valueOf(Utils.v1(1,2))); |
2.2 通过指针修改字符串
Utils.java
| package com.justin.s9day11; |
| public class Utils { |
| static { |
| System.loadLibrary("utils"); |
| } |
| |
| |
| public static native String v2(String s); |
| } |
| |
demo.c
| #include <jni.h> |
| |
| JNIEXPORT jstring JNICALL |
| Java_com_justin_s9day11_Utils_v2(JNIEnv *env, jclass clazz, jstring s) { |
| |
| |
| |
| |
| char *info = (*env)->GetStringUTFChars(env, s, 0); |
| info += 1; |
| *info = 'j'; |
| info += 3; |
| *info = 'j'; |
| info -= 4; |
| |
| |
| return (*env)->NewStringUTF(env, info); |
| |
| } |
| |
MainActivity.java
| tv.setText(Utils.v2("aaaaaaaa")); |
2.3 通过数组修改字符串
Utils.java
| package com.justin.s9day11; |
| public class Utils { |
| static { |
| System.loadLibrary("utils"); |
| } |
| |
| |
| public static native String v3(String s); |
| } |
| |
demo.c
| #include <jni.h> |
| |
| JNIEXPORT jstring JNICALL |
| Java_com_justin_s9day11_Utils_v3(JNIEnv *env, jclass clazz, jstring s) { |
| |
| char *info = (*env)->GetStringUTFChars(env, s, 0); |
| |
| info[1] = 't'; |
| info[4] = 't'; |
| |
| return (*env)->NewStringUTF(env, info); |
| |
| |
| } |
| |
| |
MainActivity.java
| tv.setText(Utils.v3("aaaaaaaa")); |
2.4 字符串拼接
Utils.java
| package com.justin.s9day11; |
| public class Utils { |
| static { |
| System.loadLibrary("utils"); |
| } |
| |
| |
| public static native String v4(String name,String role); |
| } |
| |
demo.c
| #include <jni.h> |
| #include <malloc.h> |
| #include <string.h> |
| |
| JNIEXPORT jstring JNICALL |
| Java_com_justin_s9day11_Utils_v4(JNIEnv *env, jclass clazz, jstring name, jstring role) { |
| |
| char *nameString = (*env)->GetStringUTFChars(env, name, 0); |
| char *roleString = (*env)->GetStringUTFChars(env, role, 0); |
| char *s = malloc(strlen(nameString) + strlen(roleString) + 1); |
| |
| strcpy(s, nameString); |
| |
| strcat(s, roleString); |
| |
| return (*env)->NewStringUTF(env, s); |
| } |
| |
| |
MainActivity.java
| tv.setText(Utils.v4("justin","teacher")); |
2.5 字符处理-把字符串转成16进制
Utils.java
| package com.justin.s9day11; |
| public class Utils { |
| static { |
| System.loadLibrary("utils"); |
| } |
| |
| |
| public static native String v5(String data); |
| } |
| |
demo.c
| |
| JNIEXPORT jstring JNICALL |
| Java_com_justin_s9day11_Utils_v5(JNIEnv *env, jclass clazz, jstring data) { |
| |
| char *urlParams = (*env)->GetStringUTFChars(env, data, 0); |
| |
| int size = GetStringLen(urlParams); |
| |
| char v34[size * 2]; |
| |
| char *v28 = v34; |
| |
| for (int i = 0; urlParams[i] != '\0'; i++) { |
| sprintf(v28, "%02x", urlParams[i]); |
| v28 += 2; |
| } |
| |
| return (*env)->NewStringUTF(env, v34); |
| } |
| |
| |
MainActivity.java
| tv.setText(Utils.v5("name=justin&age=19")); |
2.6 字节处理-->java传进去的是字节类型
Utils.java
| package com.justin.s9day11; |
| public class Utils { |
| static { |
| System.loadLibrary("utils"); |
| } |
| |
| public static native String v6(byte[] data); |
| public static native String v7(byte[] data); |
| |
| } |
| |
demo.c
| |
| JNIEXPORT jstring JNICALL |
| Java_com_justin_s9day11_Utils_v6(JNIEnv *env, jclass clazz, jbyteArray data) { |
| |
| char *byteArray = (*env)->GetByteArrayElements(env, data, 0); |
| |
| int size = (*env)->GetArrayLength(env, data); |
| |
| |
| char v34[size * 2]; |
| char *v28 = v34; |
| |
| for (int i = 0; byteArray[i] != '\0'; i++) { |
| sprintf(v28, "%02x", byteArray[i]); |
| v28 += 2; |
| } |
| return (*env)->NewStringUTF(env, v34); |
| |
| } |
| |
| |
| JNIEXPORT jstring JNICALL |
| Java_com_justin_s9day11_Utils_v7(JNIEnv *env, jclass clazz, jbyteArray data) { |
| char *byteArray = (*env)->GetByteArrayElements(env, data, 0); |
| int size = (*env)->GetArrayLength(env, data); |
| char v34[size * 2]; |
| char *v28 = v34; |
| int v29 = 0; |
| do { |
| sprintf(v28, "%02x", byteArray[v29++]); |
| v28 += 2; |
| } while (v29 != size); |
| |
| return (*env)->NewStringUTF(env, v34); |
| } |
| |
MainActivity.java
| |
| tv.setText(Utils.v7("name=justin&age=19".getBytes())); |
3 JNI中c调用java案例
| |
| |
| |
| |
| |
| |
| |
| |
| 静态方法:static修饰的,类来调用,不需要对象 |
| 成员方法:需要对象来调用,需要在c中实例化得到对象再调用 |
3.1 调用java的静态方法
Utils.java
| package com.justin.s9day11; |
| public class Utils { |
| static { |
| System.loadLibrary("utils"); |
| } |
| |
| public static native String v8(); |
| } |
| |
demo.c
| |
| JNIEXPORT jstring JNICALL |
| Java_com_justin_s9day11_Utils_v8(JNIEnv *env, jclass clazz) { |
| |
| |
| |
| jclass cls = (*env)->FindClass(env, "com/justin/s9day11/Foo"); |
| |
| |
| |
| |
| jmethodID method3 = (*env)->GetStaticMethodID(env, cls, "getSign", "(Ljava/lang/String;I)Ljava/lang/String;"); |
| |
| |
| |
| |
| |
| |
| jstring res1 = (*env)->CallStaticObjectMethod(env, cls, method3,(*env)->NewStringUTF(env, "lqz"),99); |
| |
| |
| return res1; |
| |
| |
| |
| |
| |
| |
| } |
| |
MainActivity.java
Foo.java
| package com.justin.s9day11; |
| |
| public class Foo { |
| |
| public static String getSign() { |
| return "justin123"; |
| } |
| |
| |
| public static String getSign(String name) { |
| return name + "_NB"; |
| } |
| |
| public static String getSign(String name, int age) { |
| return name + String.valueOf(age); |
| } |
| } |
| |
3.2 调用java的成员方法
Utils.java
| package com.justin.s9day11; |
| public class Utils { |
| static { |
| System.loadLibrary("utils"); |
| } |
| public static native String v9(); |
| |
| } |
| |
demo.c
| |
| JNIEXPORT jstring JNICALL |
| Java_com_justin_s9day11_Utils_v9(JNIEnv *env, jclass clazz) { |
| |
| |
| |
| jclass cls = (*env)->FindClass(env, "com/justin/s9day11/Foo"); |
| |
| jmethodID init = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V"); |
| |
| |
| |
| |
| jobject cls_obj = (*env)->NewObject(env, cls, init, (*env)->NewStringUTF(env, "lqz")); |
| |
| |
| jmethodID method1 = (*env)->GetMethodID(env, cls, "ShowName", "()Ljava/lang/String;"); |
| |
| |
| jstring res1 = (*env)->CallObjectMethod(env, cls_obj, method1); |
| |
| return res1; |
| |
| |
| } |
MainActivity.java
Foo.java
| package com.justin.s9day11; |
| |
| public class Foo { |
| public String name; |
| |
| |
| |
| |
| public Foo(String name) { |
| this.name = name+"_NB"; |
| |
| } |
| public Foo(String name,int age) { |
| this.name = name; |
| |
| } |
| |
| |
| public String ShowName() { |
| return this.name; |
| } |
| } |
| |
| |
| |
4 JNI注册中的动态注册和静态注册
4.1 静态注册
| 上述编写的C语言的函数和Java的对应关系,在函数名上就可以体现,例如: |
| |
| ``` |
| |
| Java_com_justin_s8day12_Utils_v9 |
| Java_com_justin_s8day12_Utils_v8 |
| |
| ``` |
| 这种称为静态注册,如果是静态注册,那么在逆向时,是比较方便的,直接可以找到函数在C中的实现。 |
4.2 动态注册
| |
| 1 新建c文件:dynamic.c |
| |
| 2 在CMakeLists.txt注册 |
| add_library( |
| dynamic |
| SHARED |
| dynamic.c) |
| 3 在CMakeLists.txt注册 |
| target_link_libraries( |
| s9day11 |
| utils dynamic |
| ${log-lib}) |
| 4 新建Dynamic.java |
| package com.justin.s9day11; |
| public class Dynamic { |
| static { |
| System.loadLibrary("dynamic"); |
| } |
| |
| public static native int vv1(int a1,int a2); |
| public static native int vv2(String s); |
| |
| |
| } |
dynamic.c
| #include <jni.h> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| jint plus1(JNIEnv *env, jobject obj, jint v1, jint v2) { |
| return v1 + v2; |
| } |
| |
| jint plus2(JNIEnv *env, jobject obj, jstring s1) { |
| return 100; |
| } |
| |
| static JNINativeMethod gMethods[] = { |
| {"vv1", "(II)I", (void *) plus1}, |
| {"vv2", "(Ljava/lang/String;)I", (void *) plus2}, |
| }; |
| |
| |
| |
| |
| JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { |
| |
| JNIEnv *env = NULL; |
| if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) { |
| return JNI_ERR; |
| } |
| |
| |
| |
| |
| jclass clazz = (*env)->FindClass(env, "com/justin/s9day11/Dynamic"); |
| |
| int res = (*env)->RegisterNatives(env, clazz, gMethods, |
| 2); |
| |
| |
| |
| |
| if (res < 0) { |
| return JNI_ERR; |
| } |
| |
| return JNI_VERSION_1_6; |
| |
| } |
5 反编译自己的app
| |
| |
| |
| -反编译so后,找JNI_OnLoad |
| -找到对应关系,双击进入,按F5,查看源代码 |
| |


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2021-10-21 Linux的bg和fg命令