-
简介:上一篇我们讲到了java调用C,今天继续聊C调用java
-
1.C调用java的静态方法
- 1.1:入口,java调用C的代码
package com.nb.s4;
class EncryptUtils {
static {
System.loadLibrary("enc");
}
public static native String v8();
}
- 1.2:C语言实现,调用java代码
#include <jni.h>
#include <string.h>
#include <syslog.h>
#include<stdlib.h>
JNIEXPORT jstring
JNICALL
Java_com_nb_s4luffy_EncryptUtils_v8(JNIEnv *env, jclass clazz) {
// 找到类
jclass cls = (*env)->FindClass(env, "com/nb/s4/SignQuery");
// 找到方法
jmethodID method1 = (*env)->GetStaticMethodID(env, cls, "getPart1", "()Ljava/lang/String;");
jmethodID method2 = (*env)->GetStaticMethodID(env, cls, "getPart2", "(I)Ljava/lang/String;");
jmethodID method3 = (*env)->GetStaticMethodID(env, cls, "getPart3","(Ljava/lang/String;)Ljava/lang/String;");
jmethodID method4 = (*env)->GetStaticMethodID(env, cls, "getPart4", "(Ljava/lang/String;I)I");
// 执行方法
jstring res1 = (*env)->CallStaticObjectMethod(env, cls, method1);
jstring res2 = (*env)->CallStaticObjectMethod(env, cls, method2, 100);
jstring res3 = (*env)->CallStaticObjectMethod(env,cls,method3,(*env)->NewStringUTF(env, "hahahahh"));
jint res4 = (*env)->CallStaticIntMethod(env,cls,method4,(*env)->NewStringUTF(env, "hahahahh"),18);
char *p1 = (*env)->GetStringUTFChars(env, res1, 0);
char *p2 = (*env)->GetStringUTFChars(env, res2, 0);
char *p3 = (*env)->GetStringUTFChars(env, res3, 0);
char *result = malloc(50);
strcat(result,p1);
strcat(result,p2);
strcat(result,p3);
return (*env)->NewStringUTF(env, result);
}
- 1.3:被c调用的java代码
package com.nb.s4;
public class SignQuery {
public static String getPart1() {
return "xwliang";
}
public static String getPart2(int len) {
return "root".substring(2);
}
public static String getPart3(String prev) {
return "xxx";
}
public static int getPart4(String prev, int v1) {
return 100;
}
}
- 2.C调用java的实例方法
- 2.1:C语言入口,java调C
package com.nb.s4;
class EncryptUtils {
static {
System.loadLibrary("enc");
}
public static native String v9();
}
- 2.2:C语言实现算法,其中部分代码调用java
#include <jni.h>
#include <string.h>
#include <syslog.h>
#include<stdlib.h>
JNIEXPORT jstring
JNICALL
Java_com_nb_s4luffy_EncryptUtils_v9(JNIEnv *env, jclass clazz) {
// 找到类
jclass cls = (*env)->FindClass(env, "com/nb/s4luffy/SignQuery2");
// 找到构造方法
jmethodID init = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;I)V");
// 实例化对象 new SignQuery2(...)
jobject cls_obj = (*env)->NewObject(env, cls, init, (*env)->NewStringUTF(env, "hahahahh"), 22);
// 找到方法
jmethodID method1 = (*env)->GetMethodID(env, cls, "getPart1", "()Ljava/lang/String;");
jmethodID method2 = (*env)->GetMethodID(env, cls, "getPart2", "(I)Ljava/lang/String;");
jmethodID method3 = (*env)->GetMethodID(env, cls, "getPart3","(Ljava/lang/String;)Ljava/lang/String;");
jmethodID method4 = (*env)->GetMethodID(env, cls, "getPart4", "(Ljava/lang/String;I)I");
// 执行方法
jstring res1 = (*env)->CallObjectMethod(env, cls_obj, method1);
jstring res2 = (*env)->CallObjectMethod(env, cls_obj, method2, 100);
jstring res3 = (*env)->CallObjectMethod(env,cls_obj,method3,(*env)->NewStringUTF(env, "hahahahh"));
jint res4 = (*env)->CallIntMethod(env,cls_obj,method4,(*env)->NewStringUTF(env, "hahahahh"),18);
char *p1 = (*env)->GetStringUTFChars(env, res1, 0);
return (*env)->NewStringUTF(env, p1);
}
- 2.3:被调用的java
package com.nb.s4;
public class SignQuery {
String name;
String city;
int count;
public SignQuery(String city, int count) {
this.name = "xwliang";
this.city = city;
this.count = count;
}
public String getPart1() {
return this.name;
}
public String getPart2(int len) {
return "root".substring(2);
}
public String getPart3(String prev) {
return "xxx-";
}
public int getPart4(String prev, int v1) {
return 100;
}
}
- 3.静态注册与动态注册
- 3.1:上述编写的C语言的函数和Java的对应关系,在函数名上就可以体现,例如:
Java_com_nb_s2long_EncryptUtils_s2
Java_com_nb_s2long_EncryptUtils_s5
这种称为静态注册,如果是静态注册,那么在逆向时,是比较方便的,直接可以找到函数在C中的实现。
- 3.2:动态注册
package com.nb.s3jni;
class DynamicUtils {
static {
System.loadLibrary("dynamic");
}
public static native int add(int v1, int v2);
}
#include <jni.h>
jint plus(JNIEnv *env, jobject obj, jint v1, jint v2) {
return v1 + v2;
}
static JNINativeMethod gMethods[] = {
{"add", "(II)I", (void *) plus},
};
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
// 在java虚拟机中获取env
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
// 找到Java中的类
jclass clazz = (*env)->FindClass(env, "com/nb/s3jni/DynamicUtils");
// 将类中的方法注册到JNI中 (RegisterNatives)
int res = (*env)->RegisterNatives(env, clazz, gMethods, 1); //第三个参数,与C中的方法对应;第4个参数,代表对应关系的个数
if (res < 0) {
return JNI_ERR;
}
return JNI_VERSION_1_6;
}
- 3.3:这种情况下,在逆向时,就不能直接找对应关系了,就需要去找jni_onload
JNI_Onload方法中
int res = (*env)->RegisterNatives(env, clazz, gMethods, 2);
然后根据gMethods找到java与C的对应关系。
标签:return,14,int,APP,String,env,JNI,public,cls From: https://www.cnblogs.com/xwltest/p/18008912