著录项信息
专利名称 | 一种Android平台软件保护系统、方法及设备 |
申请号 | CN201110429661.2 | 申请日期 | 2011-12-20 |
法律状态 | 暂无 | 申报国家 | 中国 |
公开/公告日 | 2012-10-31 | 公开/公告号 | CN102760219A |
优先权 | 暂无 | 优先权号 | 暂无 |
主分类号 | G06F21/14 | IPC分类号 | G;0;6;F;2;1;/;1;4查看分类表>
|
申请人 | 北京安天电子设备有限公司 | 申请人地址 | 北京市海淀区闵庄路3号清华科技园玉泉慧谷一期1号楼
变更
专利地址、主体等相关变化,请及时变更,防止失效 |
权利人 | 北京安天网络安全技术有限公司 | 当前权利人 | 北京安天网络安全技术有限公司 |
发明人 | 肖梓航;李柏松 |
代理机构 | 暂无 | 代理人 | 暂无 |
摘要
本发明主要公开了一种在Android系统中保护应用软件不受逆向分析和破解系统和方法。主要方法是:为Android系统中Dalvik虚拟机和Linux系统库增加接口,使Android具有从内存中直接加载DEX格式文件和SO格式文件的能力;将应用软件的核心代码存储在在线服务器中,加密并签名后发送给安装在客户端的应用软件;应用软件接收到核心代码后验证签名并解密,然后将明文存储在内存中,直接加载到系统中,然后调用其中的代码,最后释放内存。该方法极大地增加了攻击者进行逆向分析和破解的难度,能有效保护Android应用软件的安全。
1.一种Android平台软件保护系统,其特征在于,包括智能终端和在线服务器:
所述智能终端包括修改后的Android操作系统和应用软件的非核心代码;所述修改后的Android操作系统对Android操作系统的源代码进行修改,实现应用软件的核心代码在内存中的动态加载;所述应用软件的非核心代码在完整的Android应用程序之中,具备应用软件所需要的功能以外的功能,包括:向在线服务器发送请求,接收在线服务器发来的核心代码,经过验证之后在内存中加载应用软件的核心代码,根据需要通过API接口调用应用软件的核心代码;当应用软件不再使用所述核心代码时,则释放掉存储所述核心代码的内存;
在线服务器存储应用软件的核心代码,接收智能终端中应用软件非核心代码发来的请求,将被请求的核心代码经过处理之后发送给智能终端中的应用软件非核心代码。
2.如权利要求1所述的Android平台软件保护系统,其特征在于,应用软件的核心代码包括DEX格式文件和SO格式文件。
3.如权利要求1所述的Android平台软件保护系统,其特征在于,所述将被请求的核心代码经过处理之后发送给智能终端中的应用软件非核心代码为:将部分或者全部被请求的核心代码进行加密和/或将被请求的核心代码进行数字签名之后发送给智能终端中的应用软件非核心代码。
4.一种Android平台软件保护方法,其特征在于,适用于权利要求1所述的系统,所述方法包括:
智能终端接收在线服务器发送来的应用软件的核心代码所在的文件以及相应的密文;
根据接收到的文件验证数字签名并解密得到应用软件的核心代码文件;
将应用软件的核心代码文件拷贝到内存中,调用修改后的Android操作系统的接口完成核心代码文件的加载;
根据需要通过API接口调用应用软件的核心代码;
释放掉存储核心代码的内存。
5.如权利要求4所述的Android平台软件保护方法,其特征在于,智能终端在接收在线服务器发送来的应用软件的核心代码所在的文件以及相应的密文之前,向在线服务器发送需要应用软件核心代码的请求。
6.一种智能终端,其特征在于所述智能终端为权利要求1所述系统中的智能终端,所述智能终端包括修改后的Android操作系统,还包括:
接收单元,用于接收在线服务器发送来的应用软件的核心代码所在的文件以及相应的密文;
验证单元,用于根据接收到的文件验证数字签名并解密得到应用软件的核心代码文件;
加载单元,用于将应用软件的核心代码文件拷贝到内存中,调用修改后的Android操作系统的接口完成核心代码文件的加载;
调用单元,用于根据需要通过API接口调用应用软件的核心代码;
释放单元,用于释放掉存储核心代码的内存。
7.如权利要求6所述的智能终端,其特征在于,还包括:
发送单元,用于向在线服务器发送需要应用软件核心代码的请求。
一种Android平台软件保护系统、方法及设备\n技术领域\n[0001] 本发明涉及一种计算机软件保护技术,特别是用于Android平台的软件防泄密和版权保护系统及方法、服务器和智能终端。\n背景技术\n[0002] 目前,由Google公司主导开发的Android操作系统已经是全球市场占有率最高的移动智能终端平台。Android的应用软件数量不断增长,并建立了良好的软件销售模式。与传统PC平台一样,Android应用软件的成功商业化,也引发了对它们的逆向分析和破解。\n[0003] 对应用软件的逆向分析(reversing analysis)包括:\n[0004] 一、 对软件的可执行代码采用反汇编、反编译、调试等方法进行分析,以了解其代码的执行流程和算法实现等;\n[0005] 二、 对软件的配置文件和数据文件进行分析,以获得这些文件的格式和语义等;\n[0006] 三、 对软件的网络通信数据进行分析,以获得软件与服务器通信的协议格式、协议语义、数据加密方法和数据具体含义等。\n[0007] 其中,后两类分析建立在第一类分析的基础之上,即需要先分析可执行代码,才能进一步分析配置文件、数据文件、网络通信数据等。\n[0008] 通过逆向分析,攻击者可以获得软件中的商业机密。例如,在手机的反病毒软件中,恶意代码检测算法、特征匹配算法等可执行代码,以及恶意代码特征库等数据文件,一旦被攻击者逆向分析得到具体细节,既可能被其他同类软件所利用,也可能被恶意代码作者进行针对性防御或攻击。再比如,在手机的网银支付软件中,通过网络传输的数据涉及用户的身份认证和金融账户信息,一旦软件代码、配置文件、网络通信数据等被攻击者通过逆向分析彻底了解,就有可能导致进一步的恶意攻击,对个人和银行造成直接的经济损失。\n[0009] 破解(cracking)是在逆向分析基础上的一种具有专门目的的攻击。商业软件需要用户付费后使用。对未付费用户,一般不允许使用,或只能使用少量功能,或只能使用一段试用期。为了保障这一策略,商业软件通常包含对用户许可(License)和用户身份的鉴别(以下将负责这一鉴别工作的代码片段称为“鉴权代码”),以判断用户是否已经付费。攻击者通过对鉴权代码的逆向分析,并进一步篡改代码执行流程、篡改、复制或伪造相关配置文件、篡改网络数据、修改内存数据等,使未付费用户也可以获得付费用户才拥有的功能。这种攻击称之为破解,它极大地损害了软件开发者的经济权益,违反了知识产权保护的相关法律。\n[0010] Android平台的应用软件开发一般采用Java语言。源代码被编译成Java类文件,再用Android SDK(Software Development Kit,软件开发工具包)中的工具转换为DEX格式的二进制可执行文件,最后与软件配置、资源文件等一起打包成APK格式文件,即Android应用软件安装包。用户下载APK格式文件,并安装到Android终端。应用软件运行时,DEX格式文件中的指令在Android系统中的Dalvik虚拟机之中执行。\n[0011] Android是一个源代码完全开放的操作系统。无论是DEX格式文件的指令编码方法,还是Dalvik虚拟机的工作原理,都因为源码公开而已经被人们所知。目前已经出现了针对DEX格式文件的各类逆向分析工具,包括反汇编工具smali、反编译工具dex2jar,以及针对APK格式文件的apktool等自动化工具。此外,逆向分析和破解的技术在传统PC平台上已经出现多年,Android平台的攻击者已经借鉴了传统的方法。在这些工具和方法的帮助下,目前攻击者已经可以轻易地对绝大部分Android应用软件进行逆向分析和破解。\n[0012] 例如,常见的破解流程是:使用apktool解开APK文件,apktool会调用smali对其中的DEX格式文件进行反汇编;攻击者分析smali的反汇编结果,了解该应用软件的代码流程;然后找到鉴权代码,对关键的部分进行修改,例如把鉴权时的条件跳转指令改成无条件跳转指令;再使用apktool将这些修改过的代码重新打包成APK格式文件,并重新签名。\n这样就得到了一个破解后的APK文件。\n[0013] 此外,Android应用程序还可以使用NDK(Native Development Kit,原生开发工具包)开发。Android系统运行于Linux之上,每个应用软件所在的Dalvik虚拟机是一个独立的Linux进程。Android NDK提供了这样一种开发方法:程序员用C语言编写软件的部分功能,由NDK的工具将源码编译为Linux中的动态链接文件(SO格式文件);用Java语言编写其他功能,用SDK工具编译为DEX格式文件;最后由SDK将SO格式文件和DEX格式文件一起打包为APK格式文件。在运行时,DEX中的代码加载SO格式文件,并调用其提供的函数接口。\n[0014] NDK开发中的SO格式文件是Linux ELF格式标准的一种,其中的指令格式是ARM体系结构的ARM指令集或Thumb指令集。目前有IDA Pro等反汇编工具和x86/ARM Decompiler等反编译工具可以对这种文件进行逆向分析。\n[0015] 目前这一平台防御逆向分析和破解方法包括:\n[0016] 一、代码混淆。即自动化地用等效但冗余复杂的代码替换开发人员手写的Java源代码,提高攻击者进行逆向分析的工作量。\n[0017] 二、更改字符串信息。在高质量的Java源代码中,包、类、方法、变量的名字往往具有较好的可读性,即具有明确含义,因此可以通过名称猜测其功能。DEX文件完整地保存了这些名字,为逆向分析提供了方便。但大部分名字只在应用程序内部使用,例如自定义的类。如果将这些名字替换为无意义的字符串,并不会影响程序的运行,但会使逆向分析陷入理解困难。Android SDK中的ProGuard工具就利用这种方法来保护软件。\n[0018] 三、使用NDK开发。如前所述,对SO文件的逆向分析涉及对ARM格式汇编语言的理解,一定程度上提高了对软件代码进行逆向分析的难度。\n[0019] 这些方法存在以下问题:\n[0020] 1. 无论是代码还是加密后的数据,都以文件形式长期存在于Android安装文件和Android设备之中,攻击者可以轻易地获得;\n[0021] 2. 通过代码混淆,代码依然可以被反汇编和反编译,只是提高了理解代码所需要的时间;\n[0022] 3. 通过更改字符串信息,代码本身的逻辑并未发生改变,依然可以被反汇编和反编译,同样只是提高了理解代码所需要的时间;\n[0023] 4. 随着攻击者逐渐了解熟悉ARM格式汇编语言,并随着该平台反编译工具的不断成熟,采用NDK开发的方法所提高的逆向分析难度会越来越低。\n[0024] 理论上来说,应用软件在计算设备中的执行最终都无法躲避被逆向分析。软件保护的本质是不断提高逆向分析和破解的难度与时间成本,使攻击者得到有价值信息需要付出的成本高于其所能获得的利益。\n[0025] 软件保护会带来额外的软件开发成本,例如增加开发难度、延长开发时间等。因此,从是否需要特别保护的角度,逻辑上可以将应用软件的代码分为两部分:\n[0026] 一、非核心代码,不需要特别保护,例如与用户交互的界面、复用的第三方库代码等;\n[0027] 二、核心代码,需要特别保护,例如重要的算法、鉴权代码、重要配置数据等。\n[0028] 这两个部分如何划分,没有通用的方法,由每个应用软件的实际情况决定。例如,在反病毒软件中,恶意代码检测算法、特征匹配算法等都是核心模块;在网银软件中,用户登陆代码、金融交易代码等都是核心模块;在收费商业软件中,付费代码、鉴权代码等都是核心模块。\n[0029] 本发明还涉及对Android系统中DEX文件动态加载技术的修改。\n[0030] 通常情况下,Android应用软件中的DEX文件是在安装时由系统保存在指定的位置。为了扩展应用软件的能力,Android提供了DEX文件动态加载技术。具体而言,应用软件在运行时,可以通过dalvik.system.DexClassLoader类加载一个之前没有安装的APK格式或JAR格式文件,并将该文件中所包含的名为“classes.dex”的DEX格式文件加载至Dalvik虚拟机;进一步地,可以通过该类的findClass()等方法,调用这个DEX格式文件中实现的代码。\n[0031] 到目前为止的Android版本(从1.0至4.0),通过上述方法动态加载DEX格式文件存在下列要求:包含了“classes.dex”的APK或JAR格式文件必须是一个物理文件,保存在设备内置的NAND闪存或外置的SD卡中;动态加载时,系统会在设备内置的NAND闪存或外置的SD卡中生成一个临时文件,该文件是对DEX格式文件的优化(扩展名为.odex)。\n发明内容\n[0032] 针对以上技术问题,本发明主要公开了一种在Android系统中保护应用软件不受逆向分析和破解系统和方法。为Android系统中Dalvik虚拟机和Linux系统库增加接口,使Android具有从内存中直接加载DEX格式文件和SO格式文件的能力;将应用软件的核心代码存储在在线服务器中,加密并签名后发送给安装在客户端的应用软件;应用软件接收到核心代码后验证签名并解密,然后将明文存储在内存中,直接加载到系统中,然后调用其中的代码,最后释放内存。该方法极大地增加了攻击者进行逆向分析和破解的难度,能有效保护Android应用软件的安全。\n[0033] 本发明由三部分组成:\n[0034] 1、修改过的Android操作系统,实现DEX格式文件在内存中的动态加载;\n[0035] 2、应用软件的非核心代码,安装在智能终端(包括手机、平板电脑等)中,且该智能终端使用上述修改过的Android操作系统;\n[0036] 3、应用软件的核心代码,存储在长期在线的服务器中。\n[0037] 首先,对Android操作系统的源代码进行修改。在Dalvik虚拟机上增加这样的功能,使Dalvik虚拟机可以从指定的内存地址直接加载一个DEX格式文件,并使得应用程序可以通过其中代码的包名、类名、方法名,调用这些代码在Dalvik虚拟机中执行。在Android底层的Linux上增加这样的功能,使Linux可以从指定的内存地址直接加载一个SO格式文件,并使得应用程序可以通过其中代码的API接口,调用这些代码在Linux中执行。\n[0038] 应用软件的核心代码是由Java源代码经过Android SDK中的工具编译成的DEX格式文件,或者是由C源代码经过Android NDK中的工具编译成的SO格式文件。存储这些核心代码的服务器接收智能终端中应用软件非核心代码发来的请求,将其请求的核心代码加密、进行数字签名,然后发送给智能终端中的应用软件。\n[0039] 应用软件的非核心代码位于完整的Android应用程序(即APK格式文件)之中。软件开发者将这一应用程序公开分发,用户将其安装至智能终端中。非核心代码除了完成应用软件所需要的功能以外,还具备以下功能:向服务器发送请求,接收发来的核心代码,并验证其数字签名;申请一段内存,将核心代码解密至这段内存;根据核心代码是DEX格式还是SO格式,使Dalvik虚拟机或Linux从这段内存中直接加载核心代码,然后根据需要通过API接口调用核心代码的功能;最后当应用软件不再使用核心代码时,释放掉这一段内存。\n[0040] 具体而言,本发明提供了一种Android平台软件保护系统,包括智能终端和在线服务器:\n[0041] 所述智能终端包括修改后的Android操作系统和应用软件的非核心代码;所述修改后的Android操作系统对Android操作系统的源代码进行修改,实现应用软件的核心代码在内存中的动态加载;所述应用软件的非核心代码在完整的Android应用程序之中,具备应用软件所需要的功能以外的功能,包括:向在线服务器发送请求,接收在线服务器发来的核心代码,经过验证之后在内存中加载应用软件的核心代码,根据需要通过API接口调用应用软件的核心代码;\n[0042] 在线服务器存储应用软件的核心代码,接收智能终端中应用软件非核心代码发来的请求,将被请求的核心代码经过处理之后发送给智能终端中的应用软件非核心代码。\n[0043] 所述系统应用软件的核心代码包括DEX格式文件和SO格式文件。\n[0044] 所述系统的在线服务器存储应用软件的核心代码,接收智能终端中应用软件非核心代码发来的请求,将部分或者全部被请求的核心代码进行加密和/或将被请求的核心代码进行数字签名之后发送给智能终端中的应用软件非核心代码。\n[0045] 本发明还提供了一种Android操作系统的源代码修改方法,适用于所述的系统,所述方法包括:\n[0046] 对Android操作系统的Dalvik虚拟机,扩展Android Framework中dalvik.system.DexClassLoader类的功能,扩展后的dalvik.system.DexClassLoader类提供调用接口,接收内存中的DEX格式文件,以加载DEX格式文件的方式加载所述的DEX格式文件;\n[0047] 在Android源码中Linux内核和系统库的源码部分增加一个接口,所述接口从指定的内存地址加载SO格式文件;\n[0048] 编译整个Android源码工程,生成相应的系统镜像和开发工具。\n[0049] 所述方法加载所述的DEX格式文件时产生的.odex临时文件保存在内存中。\n[0050] 本发明还提供了一种Android平台软件保护方法,适用于所述的系统,所述方法包括:\n[0051] 在线服务器对存储的部分或全部的应用软件的核心代码进行加密;\n[0052] 在线服务器对存储的应用软件的核心代码进行数字签名;\n[0053] 将应用软件的核心代码所在的文件以及相应的密文发送给智能终端。\n[0054] 本发明提供的一种服务器,所述服务器所述系统中的在线服务器,所述服务器包括:\n[0055] 加密单元,用于对存储的部分或全部的应用软件的核心代码进行加密;\n[0056] 数字签名单元,用于对存储的应用软件的核心代码进行数字签名;\n[0057] 发送单元,用于将应用软件的核心代码所在的文件以及相应的密文发送给智能终端。\n[0058] 本发明提供的一种Android平台软件保护方法,适用于所述的系统,所述方法包括:\n[0059] 智能终端接收在线服务器发送来的应用软件的核心代码所在的文件以及相应的密文;\n[0060] 根据接收到的文件验证数字签名并解密得到应用软件的核心代码文件;\n[0061] 将应用软件的核心代码文件拷贝到内存中,调用修改后的Android操作系统的接口完成核心代码文件的加载;\n[0062] 根据需要通过API接口调用应用软件的核心代码;\n[0063] 释放掉存储核心代码的内存。\n[0064] 进一步的,智能终端在接收在线服务器发送来的应用软件的核心代码所在的文件以及相应的密文之前,向在线服务器发送需要应用软件核心代码的请求。\n[0065] 本发明提供了一种智能终端,所述智能终端为所述系统中的智能终端,所述智能终端包括修改后的Android操作系统,还包括:\n[0066] 接收单元,用于接收在线服务器发送来的应用软件的核心代码所在的文件以及相应的密文;\n[0067] 验证单元,用于根据接收到的文件验证数字签名并解密得到应用软件的核心代码文件;\n[0068] 加载单元,用于将应用软件的核心代码文件拷贝到内存中,调用修改后的Android操作系统的接口完成核心代码文件的加载;\n[0069] 调用单元,用于根据需要通过API接口调用应用软件的核心代码;\n[0070] 释放单元,用于释放掉存储核心代码的内存。\n[0071] 所述的智能终端还包括:\n[0072] 发送单元,用于向在线服务器发送需要应用软件核心代码的请求。\n[0073] 本发明的有益效果是:\n[0074] 其一,与现有的软件保护方案相比,本发明所述方法使攻击者极难获得应用软件的核心代码,因而无法对其进行逆向分析。\n[0075] 首先,公开分发的应用软件不包含核心代码,攻击者无法像以往从软件市场或下载站点下载到应用软件,直接对其做静态的反汇编就能看到所有代码,要获得这一部分代码必须将该应用软件运行起来,使其连接服务器。\n[0076] 其次,在服务器和智能终端上应用软件之间的通信完全采用加密和数字签名,即便攻击者抓取了网络通信数据,在没有密钥的情况下,无法解出明文的核心代码。使用数字签名,也保证了攻击者无法在这一过程中伪造出虚假的核心代码,骗取应用软件加载。\n[0077] 最后,在智能终端的Android操作系统中,核心代码始终只存在于内存中,而且只在应用软件需要其中功能时存在于内存中,而没有以文件形式存在于设备内置的NAND闪存或外置的SD卡中。目前,Android应用程序所运行的Dalvik虚拟机位于独立的Linux进程上,且进程权限为该应用程序独有的用户创建,攻击者难以读取到核心代码所在的虚拟内存空间。即便攻击者能够读到,由于存储核心代码的内存空间是运行时动态分配的,考虑到Linux和Dalvik在内存管理的复杂性,攻击者也很难准确找到核心代码在内存中具体哪个地址,以及这段内存的实际长度。此外,目前的Linux内核和Android 4.0以后都开始采用ASLR(地址空间分布随机化)技术,这进一步加大了攻击者定位核心代码内存地址的的难度。\n[0078] 再者,即便攻击者最终获得了核心代码,对其逆向分析和修改后,也极难将其植入应用软件所在进程的内存空间中,更难以要求应用程序加载这份被植入的内存段(这涉及新的内存分配、程序指令的动态修改等)。因此,无法对应用软件进行破解。\n[0079] 此外,本发明所述软件保护技术与其他现有软件保护技术的保护原理并不相同,因此也不冲突,可以与现有其他保护技术共同使用,例如代码混淆、更改字符串信息等。因此,这一方案可以与现有技术共同使用,更为全面地保护软件安全。\n附图说明\n[0080] 为了更清楚地说明本发明或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明中记载的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。\n[0081] 图1为本发明一种Android平台软件保护系统示意图;\n[0082] 图2为本发明一种Android操作系统的源代码修改方法流程图;\n[0083] 图3为本发明在线服务器工作流程图;\n[0084] 图4为本发明在线服务器系统示意图;\n[0085] 图5为本发明智能终端工作流程图;\n[0086] 图6为本发明智能终端系统示意图。\n具体实施方式\n[0087] 为了使本技术领域的人员更好地理解本发明实施例中的技术方案,并使本发明的上述目的、特征和优点能够更加明显易懂,下面结合附图对本发明中技术方案作进一步详细的说明。\n[0088] 首先介绍本发明提供的一种Android平台软件保护系统,如图1所示,包括智能终端101和在线服务器102:\n[0089] 所述智能终端101包括修改后的Android操作系统和应用软件的非核心代码;所述修改后的Android操作系统对Android操作系统的源代码进行修改,实现应用软件的核心代码在内存中的动态加载;所述应用软件的非核心代码在完整的Android应用程序之中,具备应用软件所需要的功能以外的功能,包括:向在线服务器102发送请求,接收在线服务器102发来的核心代码,经过验证之后在内存中加载应用软件的核心代码,根据需要通过API接口调用应用软件的核心代码;\n[0090] 在线服务器102存储应用软件的核心代码,接收智能终端101中应用软件非核心代码发来的请求,将被请求的核心代码经过处理之后发送给智能终端101中的应用软件非核心代码。\n[0091] 应用软件的核心代码包括DEX格式文件和SO格式文件。\n[0092] 在线服务器102存储应用软件的核心代码,接收智能终端101中应用软件非核心代码发来的请求,将部分或者全部被请求的核心代码进行加密和/或将被请求的核心代码进行数字签名之后发送给智能终端101中的应用软件非核心代码。\n[0093] 本发明包括修改Dalvik虚拟机和Linux系统的方法,主要流程如图2所示。\n[0094] S201:修改Dalvik虚拟机\n[0095] 修改Dalvik虚拟机的主要工作是,扩展Android Framework中dalvik.system.DexClassLoader类的能力,使其接收内存中一段DEX格式文件的数据,以加载DEX格式文件的方式加载这段数据,并提供与现有接口类似的调用其中代码的接口。此外,从安全的角度考虑,还要使加载过程中产生的.odex临时文件不存储在设备内置的NAND闪存或外置的SD卡中,而是也保存在内存中。\n[0096] 在Android 4.0.1_r1版的源码中,已经实现了上述功能的一部分代码。\n[0097] 具体而言,在源码的libcore/dalvik/src/main/java/dalvik/system/DexFile.java文件中,存在如下的JNI接口声明:native private static int openDexFile(byte[] fileContents),该接口的功能是从内存中的字节数组中读取一个DEX格式文件。该JNI接口的函数实现位于源码的dalvik/vm/native/dalvik_system_DexFile.cpp文件(第\n248行),函数名是Dalvik_dalvik_system_DexFile_openDexFile_bytearray,它调用了dvmRawDexFileOpenArray函数,后者的实现位于源码的dalvik/vm/RawDexFile.cpp文件(第249行)。分析这两个函数可知,它在构造一个DEX格式文件结构时,产生的.odex临时文件也保存在了内存里。\n[0098] 接下来开始在源码中增加一些代码,以完成对Dalvik虚拟机的修改。\n[0099] 在源码的libcore/dalvik/src/main/java/dalvik/system/DexFile.java文件中,为DexFile类增加一个构造函数,原型为private DexFile(byte[] fileContents, int flags),其代码与现有的private DexFile(String sourceName, String outputName, int flags)函数的代码一样,但其中的openDexFile调用使用前面所述的那个JNI接口。\n[0100] 在 源 码 的libcore/dalvik/src/main/java/dalvik/system/DexFile.java 文件中,为DexFile类增加一个方法,原型为static public DexFile loadDex(byte[] fileContents, int flags),其代码与现有的loadDex方法相似,区别是调用前面实现的这个DexFile构造函数。\n[0101] 在 源 码 的 libcore/dalvik/src/main/java/dalvik/system/DexPathList.java文件中,为DexPathList类增加一个方法,原型为private static DexFile loadDexFile(byte[] fileContents),其实现代码与现有loadDexFile方法相似,但调用前面实现的DexFile类的loadDex方法。\n[0102] 在 源 码 的 libcore/dalvik/src/main/java/dalvik/system/DexPathList.java文件中,为DexPathList类增加一个方法,原型为private static Element[] makeDexElements(byte[] fileContents),其实现代码与现有的makeDexElements方法相似,但在第207行的if语句中只进入第一条分支,并调用前面实现的DexPathList类的loadDexFile方法。\n[0103] 在源码的libcore/dalvik/src/main/java/dalvik/system/DexPathList.java文件中,为DexPathList类增加一个构造函数,原型为public DexPathList(ClassLoader definingContext, byte[] fileContents),其实现代码与现有构造函数相似,但调用前面实现的DexPathList类的makeDexElements方法。\n[0104] 在 源 码 的 libcore/dalvik/src/main/java/dalvik/system/\nBaseDexClassLoader.java文件中,为BaseDexClassLoader类增加一个构造函数,原型为public BaseDexClassLoader(byte[] fileContents),其实现代码与现有构造函数相似,但调用前面实现的DexPathList类的构造函数。\n[0105] 在 源 码 的 libcore/dalvik/src/main/java/dalvik/system/DexClassLoader.java文 件 中,为 DexClassLoader 类 增 加 一 个 构 造 函 数,原 型 为 public DexClassLoader(byte[] fileContents),其实现代码与现有构造函数一样,但调用前面实现的BaseDexClassLoader类的构造函数。\n[0106] 至此,我们得到了符合本发明所要求的修改后的Dalvik虚拟机源代码。\n[0107] S202:修改Linux系统\n[0108] 修改Linux系统的主要目的是,在Android源码工程中的Linux内核和系统库部分增加部分代码,使其增加一个接口,该接口的主要功能是从指定的内存地址加载一段SO格式文件的数据。\n[0109] 这一工作目前在业界已有多种方法实现。例如,在glibc中增加一个dlopen_mem()的系统调用,原型为void *dlopen_mem(char *addr, size_t len, int flag),其实现代码是在glibc标准库中现有dlopen()系统调用的源码基础上修改而成。具体而言,dlopen()的第一个参数是要打开的SO格式文件的磁盘路径,它会打开这个文件并将其全部内容读取出来。在dlopen_mem()的实现中,直接从参数addr和len读取数据,然后继续执行dlopen()的后续代码即可。\n[0110] 至此,我们得到了符合本发明所要求的修改后的Linux系统源代码。\n[0111] S203:编译Android工程\n[0112] 采用常规方法将整个Android源码工程编译,生成相应的系统镜像、SDK开发工具、NDK开发工具。\n[0113] 这样,在得到的SDK开发工具中,就可以使用新增的DexClassLoader(byte[] fileContents)接口,从内存中动态加载DEX格式文件;在得到的NDK开发工具中,就可以使用新增的dlopen_mem()系统调用,从内存中动态加载SO格式文件;在新的系统镜像中,使用了上述接口和系统调用的应用软件就可以正常运行。\n[0114] 本发明还提供了存储核心代码的在线服务器的工作流程,如图3所示,包括:\n[0115] S301:加密核心代码\n[0116] 核心代码以DEX格式文件或SO格式文件的形式存在,对核心代码的全部或一部分采用通用的密码学算法进行加密,以保证其在传输过程中的保密性。可以使用对称加密,也可以使用非对称加密。\n[0117] 例如,选择对称加密算法AES,使用的密钥记为akey,对核心代码所在的文件file进行加密,得到加密后的文件file_enc。\n[0118] 再选择一个非对称加密算法,例如RSA,将使用的公钥记为rkey_pub,私钥记为rkey_pri。使用私钥rkey_pri对AES密钥akey加密,得到akey的密文akey_enc。\n[0119] 在这里,RSA算法使用的公钥和私钥在事先就生成,并将公钥rkey_pub编写到相应的客户端应用软件中。\n[0120] S302:签名核心代码\n[0121] 对核心代码采用通用的数字签名算法进行签名,以保证文件的完整性。\n[0122] 例如,采用一种最经典的数字签名方法。使用哈希算法SHA1对核心代码所在文件密文file_enc进行数字摘要,得到一个哈希值hvalue。\n[0123] 使用RSA算法以及上述私钥rkey_pri对这个哈希值hvalue进行加密,得到密文hvalue_enc。\n[0124] S303:发送给客户端\n[0125] 将核心代码所在文件密文file_enc、AES算法所用密钥的密文akey_enc、哈希值的密文hvalue_enc,一同发送给客户端。\n[0126] 相应的,本发明还提供了一种服务器,如图4所示,所述服务器为所述系统中的在线服务器102,所述服务器包括:\n[0127] 加密单元401,用于对存储的部分或全部的应用软件的核心代码进行加密;\n[0128] 数字签名单元402,用于对存储的应用软件的核心代码进行数字签名;\n[0129] 发送单元403,用于将应用软件的核心代码所在的文件以及相应的密文发送给智能终端。\n[0130] 本发明还提供了应用软件中非核心代码的工作流程,在安装到客户端的应用软件中,包含了非核心的代码。这些代码可以分为两部分:一、与该软件具体应用相关的代码;\n二、负责加载核心代码的代码。本发明只涉及后一部分代码,下面给出其主要工作流程和实现方法。如图5所示,包括:\n[0131] S501:从服务器接收S303发送给客户端的file_enc、akey_enc、hvalue_enc。\n[0132] S502:验证数字签名,以保证文件的完整性。\n[0133] 例如,对S302中所述的签名方法,首先用事先选择并编写到应用软件的RSA公钥rkey_pub,解密hvalue_enc,得到哈希值hvalue。\n[0134] 接下来,用SHA1算法对发送来的file_enc进行数字摘要,得到另一个哈希值hvalue2,比较hvalue和hvalue2是否完全相同。\n[0135] 若不相同,则认为接收到的核心代码是不完整的,有可能被篡改,报告异常并退出软件。\n[0136] 若相同,则认为接收到的核心代码是完整的,进入下一步。\n[0137] S503:用RSA公钥rkey_pub解密akey_enc,得到AES算法密钥akey。用AES算法,以akey作为密钥,解密file_enc,得到核心代码所在文件file的完整内容。\n[0138] S504:根据核心代码所在文件是DEX格式还是SO格式,在Java中或者C中申请该文件大小的内存,并将文件内容拷贝至其中。\n[0139] 具体而言,若文件是DEX格式,则采用Java语言中的byte数组记录内存地址,通过new方法申请内存,使用System.arraycopy方法拷贝;若文件是SO格式,则在NDK中使用C语言的char *指针记录内存地址,通过malloc函数申请内存,使用memcpy函数拷贝,使用int型变量记录数据长度。\n[0140] S505:调用此前修改Dalvik虚拟机和Linux系统得到的新的函数接口,从前一步的内存中直接加载核心代码。\n[0141] 若文件是DEX格式,则调用S201中得到的public DexClassLoader(byte[] fileContents)构造函数,将内存地址作为参数,得到一个DexClassLoader对象,即完成了DEX格式对象的动态加载;\n[0142] 若文件是SO格式,则调用S202中得到的void *dlopen_mem(char *addr, size_t len, int flag)系统调用,其参数addr为S504中得到的内存地址,参数len为S504中记录的数据长度,参数flag为0,得到一个void *型的句柄,即完成了SO格式对象的动态加载。\n[0143] S506:根据应用软件的具体需求,调用核心代码中的类、方法、函数等。\n[0144] 若文件是DEX格式,则使用S505中得到的DexClassLoader对象的loadClass()方法,根据核心代码中Java类的名称得到该类的Class对象;进一步,使用该Class对象的getDeclaredMethod方法,根据核心代码中的Java类的方法的名称,得到该类中的方法的Method对象。现在,就可以调用这个Method对象的invoke方法,来调用该方法了。\n[0145] 若文件是SO格式,则使用S505中得到的void *型的句柄,根据核心代码中C语言函数的名称,通过dlsym()系统调用,得到这个函数的指针。现在,就可以直接调用这个函数指针,来运行其中实现的代码了。\n[0146] S507:但应用软件不再需要使用核心代码时,释放掉存储了核心代码的内存。当核心代码所在文件是DEX格式,则调用Java语言中byte[]对象的delete方法;当文件是SO格式,则调用C语言中的free方法。\n[0147] 相应的,本发明还提供了一种智能终端,所述智能终端为所述系统中的智能终端\n101,所述智能终端101包括修改后的Android操作系统,还包括:\n[0148] 接收单元601,用于接收在线服务器发送来的应用软件的核心代码所在的文件以及相应的密文;\n[0149] 验证单元602,用于根据接收到的文件验证数字签名并解密得到应用软件的核心代码文件;\n[0150] 加载单元603,用于将应用软件的核心代码文件拷贝到内存中,调用修改后的Android操作系统的接口完成核心代码文件的加载;\n[0151] 调用单元604,用于根据需要通过API接口调用应用软件的核心代码;\n[0152] 释放单元605,用于释放掉存储核心代码的内存。\n[0153] 所述的智能终端101,还包括:\n[0154] 发送单元600,用于向在线服务器发送需要应用软件核心代码的请求。\n[0155] 本说明书中方法的实施例采用递进的方式描述,对于系统的实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。\n[0156] 虽然通过实施例描绘了本发明,本领域普通技术人员知道,本发明有许多变形和变化而不脱离本发明的精神,希望所附的权利要求包括这些变形和变化而不脱离本发明的精神。
法律信息
- 2018-09-14
专利权质押合同登记的生效
IPC(主分类): G06F 21/14
专利号: ZL 201110429661.2
申请日: 2011.12.20
授权公告日: 2015.12.16
登记号: 2018990000700
登记生效日: 2018.08.17
出质人: 北京安天网络安全技术有限公司
质权人: 中信银行股份有限公司哈尔滨分行
发明名称: 一种Android平台软件保护系统、方法及设备
- 2018-09-11
专利权质押合同登记的注销
IPC(主分类): G06F 21/14
专利号: ZL 201110429661.2
申请日: 2011.12.20
授权公告日: 2015.12.16
登记号: 2017990000776
解除日: 2018.08.17
出质人: 北京安天网络安全技术有限公司
质权人: 中信银行股份有限公司哈尔滨分行
- 2017-09-15
专利权质押合同登记的生效
IPC(主分类): G06F 21/14
专利号: ZL 201110429661.2
申请日: 2011.12.20
授权公告日: 2015.12.16
登记号: 2017990000776
登记生效日: 2017.08.21
出质人: 北京安天网络安全技术有限公司
质权人: 中信银行股份有限公司哈尔滨分行
发明名称: 一种Android平台软件保护系统、方法及设备
- 2017-05-10
专利权人的姓名或者名称、地址的变更
专利权人由北京安天电子设备有限公司变更为北京安天网络安全技术有限公司
地址由100080 北京市海淀区中关村大街1号海龙大厦14层1415室变更为100080 北京市海淀区闵庄路3号清华科技园玉泉慧谷一期1号楼
- 2015-12-16
- 2013-08-14
著录事项变更
申请人由北京安天电子设备有限公司变更为北京安天电子设备有限公司
地址由100084 北京市海淀区农大南路1号硅谷亮城2B-521变更为100080 北京市海淀区中关村大街1号海龙大厦14层1415室
- 2012-12-26
实质审查的生效
IPC(主分类): G06F 21/22
专利申请号: 201110429661.2
申请日: 2011.12.20
- 2012-10-31
引用专利(该专利引用了哪些专利)
序号 | 公开(公告)号 | 公开(公告)日 | 申请日 | 专利名称 | 申请人 | 该专利没有引用任何外部专利数据! |
被引用专利(该专利被哪些专利引用)
序号 | 公开(公告)号 | 公开(公告)日 | 申请日 | 专利名称 | 申请人 | 1 | | 2016-07-27 | 2016-07-27 | | |