注:NDK的形式采用XPOSED无法拦截到。
so为了确保调用方是自己的应用,调用的时候将应用的Context传入,通过Context将应用的签名拿出来,然后和so中定义好的签名进行对比,如果一致则进行调用,代码如下:
/**
*校验APP包名和签名是否合法返回值为1表示合法
*/
jint checkSignature(JNIEnv* env,jobject thiz,jobject context){
//Context的类
jclass context_clazz=(*env)->GetObjectClass(env,context);
//得到getPackageManager方法的ID
jmethodID methodID_getPackageManager = (*env)->GetMethodID(env,
context_clazz,"getPackageManager",
"()Landroid/content/pm/PackageManager;");
//获得PackageManager对象
jobject packageManager = (*env)->CallObjectMethod(env,context,methodID_getPackageManager);
// //获得PackageManager类
jclass packageManager_clazz=(*env)->GetObjectClass(env,packageManager);
//得到getPackageInfo方法的ID
jmethodID methodID_getPackageInfo=(*env)->GetMethodID(env,packageManager_clazz,"getPackageInfo",
"(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
// //得到getPackageName方法的ID
jmethodID methodID_getPackageName = (*env)->GetMethodID(env,context_clazz,"getPackageName","()Ljava/lang/String;");
//获得当前应用的包名
jstring application_package = (*env)->CallObjectMethod(env,context,methodID_getPackageName);
const char* package_name = (*env)->GetStringUTFChars(env,application_package,0);
LOGE("packageName:%s/n",package_name);
//获得PackageInfo
jobject packageInfo = (*env)->CallObjectMethod(env,packageManager,methodID_getPackageInfo,application_package,64);
jclass packageinfo_clazz = (*env)->GetObjectClass(env,packageInfo);
//获取签名
jfieldID fieldID_signatures = (*env)->GetFieldID(env,packageinfo_clazz,"signatures","[Landroid/content/pm/Signature;");
jobjectArray signature_arr = (jobjectArray)(*env)->GetObjectField(env,packageInfo,fieldID_signatures);
//Signature数组中取出第一个元素
jobject signature = (*env)->GetObjectArrayElement(env,signature_arr,0);
//读signature的hashcode
jclass signature_clazz = (*env)->GetObjectClass(env,signature);
jmethodID methodID_hashcode = (*env)->GetMethodID(env,signature_clazz,"hashCode","()I");
jint hashCode = (*env)->CallIntMethod(env,signature,methodID_hashcode);
LOGE("hashcode:%d/n",hashCode);
if(strcmp(package_name,app_packageName) != 0){
return -1;
}
if(hashCode != app_signature_hash_code){
return -2;
}
return 1;
}
JAVA的代码:
public class SignatureUtils {
public static int getSignatureHashCode(Context context){
Signature signature = getSignature(context);
int hashCode = signature.hashCode();
return hashCode;
}
public static Signature getSignature(Context argContext) {
Signature signature = null;
try {
String packageName = argContext.getPackageName();
PackageManager packageManager = argContext.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(packageName,packageManager.GET_SIGNATURES);
Signature[] signatures = packageInfo.signatures;
signature = signatures[0];
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return signature;
}
}