博文转自http://www.tuicool.com/articles/UVjme2r,感谢博主的分享

为了防止被反编译,打算把关键代码写到so里(比如加解密),在so里加上判断APk包签名是否一致的代码,避免so被二次打包。其实用JNI读签名就是用了Java的反射机制。

先看Java读取签名的方法:

 try {
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 64);
Signature sign = info.signatures[0];
Log.i("test", "hashCode : " + sign.hashCode());
} catch (NameNotFoundException e) {
e.printStackTrace();
}

然后我们用JNI c语言实现,同样需要传递Context:

 int getSignHashCode(JNIEnv *env, 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 pm_clazz = (*env)->GetObjectClass(env, packageManager);
// 得到 getPackageInfo 方法的 ID
jmethodID methodID_pm = (*env)->GetMethodID(env, pm_clazz, "getPackageInfo",
"(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
//
// // 得到 getPackageName 方法的 ID
jmethodID methodID_pack = (*env)->GetMethodID(env, context_clazz,
"getPackageName", "()Ljava/lang/String;"); // 获得当前应用的包名
jstring application_package = (*env)->CallObjectMethod(env, context,
methodID_pack);
const char *str = (*env)->GetStringUTFChars(env, application_package, 0);
__android_log_print(ANDROID_LOG_DEBUG, "JNI", "packageName: %s\n", str); // 获得PackageInfo
jobject packageInfo = (*env)->CallObjectMethod(env, packageManager,
methodID_pm, 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);
__android_log_print(ANDROID_LOG_DEBUG, "JNI", "hashcode: %d\n", hashCode);
return hashCode;
}

第二个参数jobject不是JNI函数的默认参数,而是传入的Context实例。

转:Android开发:使用JNI读取应用签名的更多相关文章

  1. 【转】 Android 开发 之 JNI入门 - NDK从入门到精通

    原文网址:http://blog.csdn.net/shulianghan/article/details/18964835 NDK项目源码地址 : -- 第一个JNI示例程序下载 : GitHub  ...

  2. 【Android 应用开发】Android 开发 之 JNI入门 - NDK从入门到精通

    NDK项目源码地址 : -- 第一个JNI示例程序下载 : GitHub - https://github.com/han1202012/NDKHelloworld.git -- Java传递参数给C ...

  3. Android 开发 之 JNI入门 - NDK从入门到精通

    NDK项目源码地址 : -- 第一个JNI示例程序下载 : GitHub - https://github.com/han1202012/NDKHelloworld.git -- Java传递参数给C ...

  4. Android中使用JNI获得APK签名的哈希值

    原地址:http://blog.csdn.net/i5suoi/article/details/19036975 最近在研究android应用中的安全问题,貌似只有将核心代码写到JNI底层才是最安全的 ...

  5. Android开发时包名、签名、渠道和版本号的易坑点(转)

    本文中总结一下 Android 开发中容易被忽视的一些注意事项吧: 一.谨慎选择包名 包名 (Package Name) 就相当于一款应用在户口本上登记的名字,是系统用来区分不同应用的字段.重复的包名 ...

  6. Android开发 - Retrofit 2 使用自签名的HTTPS证书进行API请求

    为了确保数据传输的安全,现在越来越多的应用使用Https的方式来进行数据传输,使用https有很多有点,比如: HTTPS协议是由SSL+HTTP协议构建的可进行加密传输.身份认证的网络协议,要比ht ...

  7. Android开发中Ant命令编译和APK签名的一些心得

    本文章麦子学院跟小伙伴们详细的分享一下关于Android Ant命令行编译和APK签名详解一些实现方法,这是一个朋友在自己做安卓开发时写的,希望对大家会有所帮助呀. 最近在做Android开发时,需要 ...

  8. 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化

    第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...

  9. 《android开发艺术探索》读书笔记(十四)--JNI和NDK编程

    接上篇<android开发艺术探索>读书笔记(十三)--综合技术 No1: Java JNI--Java Native Interface(java本地接口),它是为了方便java调用C. ...

随机推荐

  1. JDBC代码示例

    package test; import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;imp ...

  2. BootStrap框架

    简介: Bootstrap,来自 Twitter,是目前很受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷,是一个CSS ...

  3. UIProgressView改变高度

    CGAffineTransform transform = CGAffineTransformMakeScale(1.0f, 3.0f); progressView.transform = trans ...

  4. 2016 - 3 - 12 SQLite的学习之SQL语言入门

    1.SQL语句的特点: 1.1 不区分大小写 1.2 每条语句以;结尾 2.SQL语句中常用关键字: select,insert,update,from,create,where,desc,order ...

  5. 如何快速在当前目录打开cmd命令提示符

    对于稍微熟悉电脑一些的朋友来说.cmd绝对是个很方便的东西.但是每次使用cmd都要cd半天才能到当前目录.怎么快速打开当前目录呢? 当前目录按住shift再右键.然后会看到右键菜单里有一个" ...

  6. angular 滚动

    AngularJs $anchorScroll.$controller.$document $anchorScroll 根据HTML5的规则,当调用这个函数时,它检查当前的url的hash值并且滚动到 ...

  7. esxi 6 虚拟机安装复制

    打开VMware vSphere Client 连接到esxi服务器,选择配置-存储器, 右击存储器标识,选择浏览存储数据, 首先新建一个文件夹,用来存放系统镜像,这里新建了iso文件夹, 选择iso ...

  8. Ubuntu 使用Cisco VPN、AnyConnect、OpenConnect的方法。

    自己建的廉价Shadowsocks服务器总是不稳定,众所周知,PPTP在中国大陆已经废了.为了连接外网,所以购买了BlueCloud的VPN.但是他们家的VPN是使用Cisco VPN,可以使用Any ...

  9. ThinkPHP_基础(1)目录结构

    (说明:文中的颜色一一对应) 目录结构 www WEB部署目录(或者子目录) ├─index.php 入口文件 ├─README.md README文件 ├─composer.json Compose ...

  10. sphinx 注意点

    强制更新索引indexer --all --rotate合并索引indexer --merge index1 index2 --rotate No fields in schema - will no ...