开发NDK时,为保存你的so文件不被拿去反调试,可以添加应用签名校验
checksign.hpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #ifndef checksign_hpp #define checksign_hpp
#include <stdio.h> #include <jni.h> static const char *app_packageName = "com.uilucky.demo"; static const int app_signature_hash_code = 1985487779; static const char *RELEASE_SIGN = "78454545454545454545555555555555555555555555555555555..."; jobject getApplication(JNIEnv *env); /* 校验APP签名是否一致 返回值为1 表示合法 */ jint check_sing(JNIEnv *env);
#endif /* checksign_hpp */
|
checksign.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include "checksign.hpp" #include <iostream> jobject getApplication(JNIEnv *env) { jobject application = NULL; jclass activity_thread_clz = env->FindClass("android/app/ActivityThread"); if (activity_thread_clz != NULL) { jmethodID currentApplication = env->GetStaticMethodID( activity_thread_clz, "currentApplication", "()Landroid/app/Application;"); if (currentApplication != NULL) { application = env->CallStaticObjectMethod(activity_thread_clz, currentApplication); } } return application; } jint check_sing(JNIEnv *env){ jobject contextObject = getApplication(env); jclass native_class = env->GetObjectClass(contextObject); jmethodID pm_id = env->GetMethodID(native_class, "getPackageManager", "()Landroid/content/pm/PackageManager;"); jobject pm_obj = env->CallObjectMethod(contextObject, pm_id); jclass pm_clazz = env->GetObjectClass(pm_obj); // 得到 getPackageInfo 方法的 ID jmethodID package_info_id = env->GetMethodID(pm_clazz, "getPackageInfo","(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); jclass native_classs = env->GetObjectClass(contextObject); jmethodID mId = env->GetMethodID(native_classs, "getPackageName", "()Ljava/lang/String;"); jstring pkg_str = static_cast<jstring>(env->CallObjectMethod(contextObject, mId)); // 获得应用包的信息 jobject pi_obj = env->CallObjectMethod(pm_obj, package_info_id, pkg_str, 64); // 获得 PackageInfo 类 jclass pi_clazz = env->GetObjectClass(pi_obj); // 获得签名数组属性的 ID jfieldID signatures_fieldId = env->GetFieldID(pi_clazz, "signatures", "[Landroid/content/pm/Signature;"); jobject signatures_obj = env->GetObjectField(pi_obj, signatures_fieldId); jobjectArray signaturesArray = (jobjectArray)signatures_obj; jsize size = env->GetArrayLength(signaturesArray); jobject signature_obj = env->GetObjectArrayElement(signaturesArray, 0); jclass signature_clazz = env->GetObjectClass(signature_obj); jmethodID string_id = env->GetMethodID(signature_clazz, "toCharsString", "()Ljava/lang/String;"); jstring str = static_cast<jstring>(env->CallObjectMethod(signature_obj, string_id)); char *c_msg = (char*)env->GetStringUTFChars(str,0); //return str; if(strcmp(c_msg,RELEASE_SIGN)==0)//签名一致 返回合法的 api key,否则返回错误 { return 1; }else { return 0; } }
|
RELEASE_SIGN 获取方法,可以在android 中使用如下代码打印
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public static String getSignature(Context context) { try { /** 通过包管理器获得指定包名包含签名的包信息 **/ PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES); /******* 通过返回的包信息获得签名数组 *******/ Signature[] signatures = packageInfo.signatures; /******* 循环遍历签名数组拼接应用签名 *******/ return signatures[0].toCharsString(); /************** 得到应用签名 **************/ } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } return null; }
|