现在很多android应用的注册码配置的时候,为了保证本身应用的安全,将获取机器唯一标识的字段放在jni中执行。
手机或者pad的机器唯一标识主要有
imei 手机设备号
imsi 手机串口
macaddr 手机上的物理地址
一般都是
jint Java_com_example_jnicalltest_Jnihelper_testobj(JNIEnv* env, jobject thiz, jobject obj)
比如这个是一个c语言写的jni函数
java应用层调用的时候一般是使用
Jnihelper.testobj(MainActivity.this);
这个方法,注意传入的这个类继承于 android.app.Activity,再网上继承是 android.app.Context,而不管怎样,这个类传入以后,在c语言中的这个函数的实现部分,就可以使用
jmethodID systemService = (*env)->GetMethodID(env,clazz,"getSystemService","(Ljava/lang/String;)Ljava/lang/Object;");
这类的接口找到这个类是否存在这样的接口了.
找到有这样的接口,肯定有,因为你可以查看android api的文档,也不会写一个不存在的接口
然后就调用
jobject tm = (*env)->CallObjectMethod(env, obj, systemService,jstrMSG);
这样的接口,来调用了 传入的obj的 getSystemService 这个成员方法,获取jobject的返回值,然后再进行相关的操作,最终用这样的方法取得了想要的手机唯一码值
原理大概就这些,基本搞清楚了
然后就是想有没有神马方法能够让jni中的so库调用我们的class,而不是android系统的Context的class,如果能够调用我们的class,那样我们写神马返回值不都能够回传到jni中,从而破坏掉其业务逻辑。
是有方法的:
1 com_example_jnicalltest_Jnihelper 编写这样的包在自己的工程中,以为直接修改so中的调用函数名比较麻烦,所以还是在自己的工程中老老实实的建立一样的package方便,像上面的函数,基本上就是建立 com.example.jnicalltest.Jnihelper 这样的类就行了
package com.example.jnicalltest;
public class Jnihelper {
static {
System.loadLibrary("screenshot");
}
public static native int testobj(Object testobj);
public static native int testsystem(Object testsystem);
}
比如这样的写法...
转载于:https://blog.51cto.com/sunzeduo/1301612