// // Created by SamuelGjk on 2017/3/23. // #include #include #include "native-secret.h" #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "secret", __VA_ARGS__)) #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "secret", __VA_ARGS__)) static int verifySign(JNIEnv *env); jint JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *env = NULL; if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) { return JNI_ERR; } if (verifySign(env) == JNI_OK) { return JNI_VERSION_1_4; } LOGE("签名不一致!"); return JNI_ERR; } static 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); } else { LOGE("Cannot find method: currentApplication() in ActivityThread."); } env->DeleteLocalRef(activity_thread_clz); } else { LOGE("Cannot find class: android.app.ActivityThread"); } return application; } static const char *SIGN = ""; static int verifySign(JNIEnv *env) { // Application object jobject application = getApplication(env); if (application == NULL) { return JNI_ERR; } // Context(ContextWrapper) class jclass context_clz = env->GetObjectClass(application); // getPackageManager() jmethodID getPackageManager = env->GetMethodID(context_clz, "getPackageManager", "()Landroid/content/pm/PackageManager;"); // android.content.pm.PackageManager object jobject package_manager = env->CallObjectMethod(application, getPackageManager); // PackageManager class jclass package_manager_clz = env->GetObjectClass(package_manager); // getPackageInfo() jmethodID getPackageInfo = env->GetMethodID(package_manager_clz, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); // context.getPackageName() jmethodID getPackageName = env->GetMethodID(context_clz, "getPackageName", "()Ljava/lang/String;"); // call getPackageName() and cast from jobject to jstring jstring package_name = (jstring) (env->CallObjectMethod(application, getPackageName)); // PackageInfo object jobject package_info = env->CallObjectMethod(package_manager, getPackageInfo, package_name, 64); // class PackageInfo jclass package_info_clz = env->GetObjectClass(package_info); // field signatures jfieldID signatures_field = env->GetFieldID(package_info_clz, "signatures", "[Landroid/content/pm/Signature;"); jobject signatures = env->GetObjectField(package_info, signatures_field); jobjectArray signatures_array = (jobjectArray) signatures; jobject signature0 = env->GetObjectArrayElement(signatures_array, 0); jclass signature_clz = env->GetObjectClass(signature0); jmethodID toCharsString = env->GetMethodID(signature_clz, "toCharsString", "()Ljava/lang/String;"); // call toCharsString() jstring signature_str = (jstring) (env->CallObjectMethod(signature0, toCharsString)); // release env->DeleteLocalRef(application); env->DeleteLocalRef(context_clz); env->DeleteLocalRef(package_manager); env->DeleteLocalRef(package_manager_clz); env->DeleteLocalRef(package_name); env->DeleteLocalRef(package_info); env->DeleteLocalRef(package_info_clz); env->DeleteLocalRef(signatures); env->DeleteLocalRef(signature0); env->DeleteLocalRef(signature_clz); const char *sign = env->GetStringUTFChars(signature_str, NULL); if (sign == NULL) { LOGE("分配内存失败"); return JNI_ERR; } LOGI("应用中读取到的签名为:%s", sign); LOGI("native中预置的签名为:%s", SIGN); int result = strcmp(sign, SIGN); // 使用之后要释放这段内存 env->ReleaseStringUTFChars(signature_str, sign); env->DeleteLocalRef(signature_str); if (result == 0) { // 签名一致 return JNI_OK; } return JNI_ERR; } jstring Java_moe_yukinoneko_diycode_api_Secret_getClientId(JNIEnv *env, jclass type) { return env->NewStringUTF(""); } jstring Java_moe_yukinoneko_diycode_api_Secret_getSecret(JNIEnv *env, jclass type) { return env->NewStringUTF(""); }