开发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;
}