著录项信息
专利名称 | 一种Android应用程序分块保护的方法 |
申请号 | CN201310378841.1 | 申请日期 | 2013-08-27 |
法律状态 | 授权 | 申报国家 | 中国 |
公开/公告日 | 2013-11-27 | 公开/公告号 | CN103413076A |
优先权 | 暂无 | 优先权号 | 暂无 |
主分类号 | G06F21/14 | IPC分类号 | G;0;6;F;2;1;/;1;4查看分类表>
|
申请人 | 北京理工大学 | 申请人地址 | 北京市海淀区中关村南大街5号
变更
专利地址、主体等相关变化,请及时变更,防止失效 |
权利人 | 北京理工大学 | 当前权利人 | 北京理工大学 |
发明人 | 张欢;李元章;朱瑞瑾;张全新;谭毓安 |
代理机构 | 暂无 | 代理人 | 暂无 |
摘要
本发明涉及一种Android应用程序分块保护的方法,包括以下步骤:一、将需要保护的应用程序生成的classes.dex文件加密;二、在Java编译器中将需要保护的代码删除,并将初始的完全加密的Dex文件以资源形式存放在应用程序的APK中;三、在应用程序的APK中加入封装好的DexFile类;四、通过IDA工具查看原始dex文件类中方法的地址并做记录;五、在应用程序java代码中重写调用Dex文件类中方法的代码,使得程序运行的时候将Dex文件以字节的形式读入数组中,根据传入的类地址解密相关类并相应的修改Dex文件校验码和签名;六、根据重写的代码,重新生成应用程序的APK。本发明可以对Android应用程序的代码进行保护。
1.一种Android应用程序分块保护的方法,包括以下步骤:
一、将需要保护的应用程序生成的classes.dex文件加密;
二、在Java编译器中将需要保护的代码删除,并将初始的完全加密的Dex文件以资源形式存放在应用程序的APK中;
三、在应用程序的APK中加入封装好的DexFile类;
四、通过IDA工具查看原始dex文件类中方法的地址并做记录;
五、在应用程序java代码中重写调用Dex文件类中方法的代码,使得程序运行的时候将Dex文件以字节的形式读入数组中,根据传入的类地址解密相关类并相应的修改Dex文件校验码和签名,从而可以使用分段解密后的Dex文件;
六、根据重写的代码,重新生成应用程序的APK。
一种Android应用程序分块保护的方法\n技术领域\n[0001] 本发明涉及一种Android应用程序分块保护的方法,属于数据安全技术领域。\n背景技术\n[0002] Android平台是Google公司研发的基于Linux开放性内核操作系统,它采用了软件堆层架构,底层Linux内核只提供基本功能,其他的应用软件则由各公司自行开发。\nAndroid平台因其开放性和跨平台特性深受用户的喜爱,用户可以在Android应用市场随意下载和安装应用程序,由于其开源性而拥有规模庞大的应用程序,因此开发者们对于Android程序代码保护也越来越关注。\n[0003] Android应用程序是用Java语言实现,编译后转换成Dalvik字节码存放在Dex文件中。为了支持平台无关性,Android采用Dalvik字节码文件格式,而后在Dalvik虚拟机上解释执行。Dalvik虚拟机的指令集相对简单通用,每一个类编译成一个单独的文件,Class文件保留方法变量名称等大量语义信息。这些特点都导致Android字节码更容易被反编译为Android源代码。攻击者通过反编译技术,获得软件的全部或部分源代码,从而获取关键信息如核心算法、秘密信息等为自己所用。\n发明内容\n[0004] 本发明的目的是提出一种Android应用程序分块保护的方法。\n[0005] Android应用程序是用Java语言实现的,Java编译器首先将Java文件编译成.class文件,然后通过Android SDK提供的dx工具将所有的.class文件转化成一个classes.dex文件。本发明通过对应用程序生成的Dex文件进行加密,将程序中重要的代码隐藏起来,在程序运行时,只对需要的类进行解密并动态加载,没有用到的类还是以加密形式存在,等该类加载完成后再加密。这样即使程序被反编译,由于重要代码已经被隐藏在Dex文件中,并且已经被加密过,攻击者也不能获得关键信息。并且不管在程序运行的哪个时刻,都不存在完全被解密的原始的Dex文件。达到了对应用程序代码进行保护的作用。\n[0006] 本发明的目的是通过以下技术方案实现的:\n[0007] 一种Android应用程序分块保护的方法,包括以下步骤:\n[0008] 一、将需要保护的应用程序生成的classes.dex文件加密;\n[0009] 二、在Java编译器中将需要保护的代码删除,并将初始的完全加密的Dex文件以资源形式存放在应用程序的APK中;\n[0010] 三、在应用程序的APK中加入封装好的DexFile类;\n[0011] 四、通过IDA工具查看原始dex文件类中方法的地址并做记录;\n[0012] 五、在应用程序java代码中重写调用Dex文件类中方法的代码,使得程序运行的时候将Dex文件以字节的形式读入数组中,根据传入的类地址解密相关类并相应的修改Dex文件校验码和签名,从而可以使用分段解密后的Dex文件;\n[0013] 六、根据重写的代码,重新生成应用程序的APK。\n[0014] 有益效果\n[0015] 使用本发明的方法,即使程序被反编译,由于重要代码已经被隐藏在Dex文件中,并且已经被加密过,攻击者也不能获得关键信息。并且不管在程序运行的哪个时刻,都不存在完全被解密的原始的Dex文件。达到了对应用程序代码进行保护的作用。\n附图说明\n[0016] 图1是Dex文件结构。\n[0017] 图2是分块加密解密示意图。\n[0018] 图3是加载一个类并调用其方法流程图。\n具体实施方式\n[0019] 下面结合附图对本发明方法的实施方式做详细说明。\n[0020] 本发明主要包括以下两个方面:\n[0021] 一是对Dex文件加密和运行时分块解密:\n[0022] 加密解密算法在此不做详细说明。Dex文件的结构如附图说明1中所示,可以看到,Dex文件中数据并不是按Class类存放,所以一个类中不同的方法在Dex文件中的地址也是不同的。可以通过专门的工具如IDA来查看Dex文件中类中方法的地址,记录下来,在程序运行的时候将这个地址集合作为参数传递给解密函数,这样就实现了分块解密。仅仅解密还是不够的,由于Dex文件头中有校验码和SHA-1签名字段,如果改变Dex文件的数据,上述两个字段也应该随之变化,所以还需要根据解密后的Dex文件计算新的校验码和签名写回Dex文件中,这样才得到了真正的可以使用的分段解密后的Dex文件。附图说明\n2中形象的展示了是如何在程序运行的时候进行分块加密解密,以A、B两个类举例说明,为了更直观的展示,一个类以一个整体块表示。\n[0023] 二是动态加载Dex文件中的类。\n[0024] 初始的完全加密的Dex文件以资源形式存放在应用程序的APK中。程序运行的时候将Dex文件以字节的形式读入数组中,根据传入的类地址解密相关类并相应的修改Dex文件校验码和签名。使用System.Dalvik.DexFile类中提供的openDexFile(byte[])方法打开分段解密后的Dex字节数组,利用findClass()方法加载有关类,需要传入类的完全名称(包名+类名),类加载完成后,就可以利用Java的反射机制调用类中的方法。这里用到的openDexFile(byte[])和findClass()都是System.Dalvik.DexFile类中的私有方法,需要重新定义一些方法,把这些私有方法赋值给新定义的方法,这样我们在程序中就可以使用了,我们把跟打开Dex及加载类有关的操作都封装在DexFile类中。附图说明3中展示了动态加载一个类并调用其中方法的流程图。\n[0025] 以一个序列码验证的应用程序(validate.apk)为例进行说明,该应用的功能是验证用户是否合法,根据用户输入的用户名和序列码(16位数字和字母的组合区分大小写),经过两个验证函数(validate1,validate2),如果用户合法就返回true,否则返回false。我们对这两个验证函数的代码进行保护。该应用程序为开源程序。具体的操作步骤如下:\n[0026] 第一步,对validate.apk中的classes.dex文件加密。\n[0027] 第二步,在Eclipes中打开生成validate.apk的工程,将validate1和validate2函数体中的代码删除,并将第一步中加密的dex文件放入assets文件夹下。\n[0028] 第三步,将我们封装好的DexFile类加入代码中。\n[0029] 第四步,通过IDA工具查看原始dex文件并对validate1和validate2函数所在类的地址做记录。\n[0030] 第五步,在validate1和validate2函数体中重新写入代码。首先利用InputStream流从assets文件夹中读入dex文件到byteOfarr[]这个字节数组中,传入第四步中得到的函数所在类的地址,对dex文件进行部分解密,并相应的修改dex文件头的校验码和签名,然后实例化一个DexFile对象dexfile,用dexfile.openDexFile(byteOfarrr)方法打开dex文件,利用dexfile.getClass(name)加载类,返回加载后的类对象localClass,利用localClass.getConstructor()获取类的构造函数constructor,并实例化该构造函数constructor.newInstance()。利用localClass.getMethod(“validate1”)和localClass.getMethod(“validate1”)获取函数方法,利用Method.invoke()调用方法。\n[0031] 第六步,重新编译生成APK,能够正常运行。\n[0032] 至此就已经在该序列码验证实例上实现该发明阐述的方案,攻击者反编译重新生成后的APK,获得不了程序的关键代码,因为已经被加密。\n[0033] 本发明不仅限于以上实施例,凡是利用本发明的设计思路,做一些简单变化的方案,都应计入本发明的保护范围之内。
法律信息
- 2022-08-12
未缴年费专利权终止
IPC(主分类): G06F 21/14
专利号: ZL 201310378841.1
申请日: 2013.08.27
授权公告日: 2016.03.02
- 2016-03-02
- 2015-07-08
著录事项变更
发明人由张欢 谭毓安 朱瑞瑾 张全新李元章变更为张欢 李元章 朱瑞瑾 张全新谭毓安
- 2013-12-18
实质审查的生效
IPC(主分类): G06F 21/14
专利申请号: 201310378841.1
申请日: 2013.08.27
- 2013-11-27
引用专利(该专利引用了哪些专利)
序号 | 公开(公告)号 | 公开(公告)日 | 申请日 | 专利名称 | 申请人 |
1
| |
2012-02-22
|
2011-09-26
| | |
2
| |
2011-11-09
|
2011-06-30
| | |
3
| |
2012-10-03
|
2012-05-12
| | |
被引用专利(该专利被哪些专利引用)
序号 | 公开(公告)号 | 公开(公告)日 | 申请日 | 专利名称 | 申请人 | 该专利没有被任何外部专利所引用! |