CN107590013B - 一种检测Android应用Service构件泄露的高效方法 - Google Patents
一种检测Android应用Service构件泄露的高效方法 Download PDFInfo
- Publication number
- CN107590013B CN107590013B CN201710790636.4A CN201710790636A CN107590013B CN 107590013 B CN107590013 B CN 107590013B CN 201710790636 A CN201710790636 A CN 201710790636A CN 107590013 B CN107590013 B CN 107590013B
- Authority
- CN
- China
- Prior art keywords
- srv
- service
- application
- android
- intent
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Landscapes
- Debugging And Monitoring (AREA)
Abstract
本发明提供了快速检测安卓应用潜在的Service构件泄露的方法。其特征在于,包括以下步骤:步骤1、重复尝试“启动(start)并停止(stop)”以及“绑定(bind)并解绑(unbind)”应用在其AndroidManifest.xml文件中所声明的各个service;步骤2、获取应用堆栈内存;步骤3、分析应用堆栈内存,鉴别泄露的Service构件。本发明的能准确的检测安卓应用潜在的Service构件泄露风险,具有全自动、效率高、可重现等特征。
Description
技术领域
本发明专利涉及安卓软件应用,内存泄露检测领域,尤其涉及一种检测安卓应用Service构件泄露的高效方法。
背景技术
近年来,随着移动设备的普及,基于移动设备的安卓应用数量不断增加。然而,由于安卓复杂的生命周期管理机制,开发安卓应用极容易引入泄露Service构件的可能性。这些潜在的应用构件的泄露,会不断消耗系统内存等资源,导致应用卡顿甚至崩溃,极大的影响用户体验和商家品牌形象。为此,如何自动化高效的检测应用潜在的Service构件的泄露,有着极大的意义。然而,现有检测安卓应用Service泄露的工作要么需要大量的人工介入,要么难以重现泄露场景。为此,本发明旨在为安卓应用潜在的Service构件的泄露现象的自动化检测提供一个快速检测方案。
发明内容
本发明主要针对现有工作的不足,提出了一种检测Android应用Service构件泄露的高效方法。
该方法基于以下现实:安卓应用往往包含一系列的Service,这些Service中部分仅仅供应用内部使用(“android:exported=false”),还有一部分可供本应用之外的其他应用的各种构件所使用(“android:exported=true”);对于“android:exported=true”的Service,其他应用的构件可以通过startService()或bindService()两个API来访问该应用;通常情况下,两种方式都会创建Service实例;当不需要使用该服务的时候,应用构件可以通过stopService()或unbindService()两个方法来停止服务或解除对服务的绑定。当一个Service实例被停止并且没有其他构件绑定该服务的时候,系统则会自动销毁该Service实例;安卓系统为了管理应用的Service实例,在应用对应的ActivityThread实例中提供了专门用于记录处于运行态的服务的域mServices;当一个Service实例被创建,则会在mServices域中添加对该实例的间接引用,当一个Service实例被销毁,mServices域也会自动删除相应的引用关系。通过对mServices域值的比较,可以判断Service实例是否已被销毁;不能被GC回收的Service实例,一定存在通往GC root的不包含SoftReference、WeakReference、PhantomReference、FinalizerReference以及Finalizer类型对象的路径。
为了实现上述发明目的,本发明采用的技术方案为:
一种安卓应用Service构件泄露的高效检测方法,其特征在于,分为主程序(Master)与客户端检测应用(APKchecker)两部分。主程序(Master)运行在PC端,客户端检测应用(APKchecker)运行在测试安卓设备(安卓实体机或虚拟机)上。其主要步骤包括:
步骤一、主程序(Master)借助Android-Debug-Bridge(ADB)安装待检测应用APKtarget;
步骤二、主程序(Master)借助Android-Debug-Bridge(ADB)安装客户端检测应用(APKchecker);
步骤三、主程序(Master)以“Start模式”启动客户端检测应用(APKchecker);
步骤四、客户端检测应用(APKchecker)以“Start模式”尝试检测待测应用所发布的各项服务;
步骤五、主程序(Master)记录相应应用堆栈内存;
步骤六、主程序(Master)以“Bind模式”启动客户端检测应用(APKchecker)尝试检测待测应用所发布的各项服务;
步骤七、客户端检测应用(APKchecker)以“Bind模式”尝试检测待测应用所发布的各项服务;
步骤八、主程序(Master)记录相应应用堆栈内存;
步骤九、分析获取得到的应用堆栈内存,检测泄露的应用构件。
运行在测试安卓设备(安卓实体机或虚拟机)上的客户端检测应用(APKchecker)负责不断“启动/停止”或“绑定/解绑”指定服务并记录相应应用的堆栈,其具体工作流程如包含如下步骤:
1)获取待检测应用APKtarget的AndroidManifest.xml文件,确定应用所包含的所有Service列表,记为LSrv;
2)依据启动模式不同,采取不同处理逻辑:
a)若启动模式为“Start模式”,针对LSrv中每个Service,重复start/stop该Service;
b)若启动模式为“Bind模式”针对LSrv中每个Service,重复bind/unbind该Service;
为了获取待检测应用APKtarget的AndroidManifest.xml文件,确定应用所包含的所有Service列表,客户端检测应用(APKchecker)具体通过以下步骤来实现该功能:
1)利用逆向工程工具对待检测安卓应用.apk文件进行反编译,获取应用AndroidMenifest.xml描述文件
2)分析AndroidMenifest.xml文件,查找<service>标签,确定应用的服务列表;针对每个<service>标签所刻画的服务srvi,若其“android:exported”属性为“true”,则将srvi加入待检测服务列表LSrv;若其“android:exported”属性为“false”,但<service>标签包含<intent-filter>子标签,则同样将srvi加入待检测服务列表LSrv。对于包含<intent-filter>子标签的<service>标签,需要进一步分析该<intent-filter>子标签,则需要进一步分析该子标签,获取其所包含的<action>标签的“adroid:name”属性的值,记为srvi.act;在该过程中,若果有多个<intent-filter>标签,则随机抽取一个;若选中的<intent-filter>标签包含多个<action>子标签,则随机抽取其中一个,并以它“adroid:name”属性的值记为srvi.act。
客户端检测应用(APKchecker)针对LSrv中每个Service,重复start/stop该Service,包含以下步骤:
1)针对权力所获得的应用服务列表LSrv中的每一个服务srvi∈LSrv,重复以下步骤k次(k>=2,由用户指定)
a)利用安卓系统提供的startService(Intent intent)API来启动对应服务srvi。特别的,若srvi.act不为空,则需要在参数intent中通过intent.setAction(srvi.act)的方式来指定具体的action。
b)利用安卓系统提供的stopService(Intent intent)API来停止先前启动的服务srvi。特别的,若srvi.act不为空,则需要在参数intent中通过intent.setAction(srvi.act的方式来指定具体的action。
客户端检测应用(APKchecker)针对LSrv中每个Service,重复bind/unbind该Service,包含以下步骤:
1)针对所获得的应用服务列表LSrv中的每一个服务srvi∈LSrv,重复以下步骤k次(k>=2,由用户指定):
a)利用安卓系统提供的bindService(Intent intent,ServiceConnectionconnection,int flags)API来启动对应服务srvi。特别的,若srvi·act不为空,则需要在参数intent中通过intent.setAction(srvi·act)的方式来指定具体的action。flags=BIND_AUTO_CREATE。
b)利用安卓系统提供的unbindService(Connection connection)API来解除对先前绑定的服务srvi的绑定。
本发明所提出安卓应用Service构件泄露的高效检测方法的步骤四要完成获取得到的应用堆栈内存的分析,检测泄露的应用构件,具体包括以下步骤:
1)针对一个转储的应用堆栈.hprof文件,首先获取其中所包含的所有Service对象实例,用Ssrv表示;
2)针对所获得的每一个Service对象实例s∈Ssrv进行逐个鉴别,判定s是否已经被销毁,若s被判定为已销毁,则将其从Ssrv中删除;
3)针对处理后得到的Ssrv中的剩余对象实例s,进一步判定其是否是泄露的,若是则将其从Ssrv中删除;
4)返回Ssrv,即获得所有泄露的Service实例。
要判定一个给定的Service实例s是否被销毁,则是依据该s是否被某个ActivityThread实例所管理,即判断是否存在如下的引用关系序列:at→mServices→array[]→s,其中at表示应用所对应的一个ActivityThread实例。若存在这样一个引用关系序列,则s被at表示的ActivityThread实例所管理;否则,s则被认为是被销毁的。
要判定一个给定的销毁了的Service实例s是否泄露,具体包括以下步骤:
1)获取Service实例s到达所有GC root的路径,记为LP;
2)从LP中去除所有包含java.lang.ref.SoftReference、java.lang.ref.WeakReference、java.lang.ref.PhantomReference、java.lang.ref.FinalizerReference以及java.lang.ref.Finalizer类型对象的路径;从LP中去除所有以java.lang.Daemons$FinalizerDaemon类对象结尾的路径,同时从LP中去除包含FinalizerWatchdogDaemon线程的路径
3)若LP为空,则s不是泄露的;否则,s则是泄露的。
本发明能够自动化地实现以下功能:逐个启动并销毁待检测安卓应用的各个Service实例,收集安卓应用堆栈内容,并通过进一步分析所转储的应用堆栈内容,鉴别泄露Service构件实例。相对现有其他工作而言,本发明具有以下有益效果:
1)自动化;
2)高效率;
3)可重现。
附图说明
图1为本发明实施例的Service泄露检测方法的整体架构和流程框架。
图2为本发明实施例的分析堆栈文件识别泄露Service实例的流程。
具体实施方式
下面结合本发明实例中的附图,对本发明实施例中的技术方案进行清楚、完整地的描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部实施例。基于本发明的实施例,本领域普通技术人员在没有做出创造性劳动的前提下所获得的所有其他实施例,都属于本发明的保护范围。
1.主要过程:
图1所示为本发明提供的一种安卓应用Service泄露高效检测方法的整体架构和流程框架图,图1中:
系统整体分为主程序(Master)与客户端检测应用(APKchecker)两部分。主程序(Master)运行在PC端,客户端检测应用(APKchecker)运行在测试安卓设备(安卓实体机或虚拟机)上。
对于待检测的一个安卓应用,我们首先安装待检测应用APKtarget;然后,安装客户端检测应用(APKchecker);再然后,针对应用每个服务,分别尝试重复“启动/停止”或“绑定/解绑”该服务多次,并转储应用运行时刻堆栈;最后,利用内存分析工具分析转储的堆栈文件,以确定泄露的Service实例。
图2所示为本发明中自动化分析堆栈文件(即.hprof文件),并进一步鉴别泄露Service实例的流程。针对每一个待分析的堆栈文件(即.hprof文件),首先找出其中所包含的所有的Service子类集合Sclass;然后,针对Sclass中的每一个子类,找到其所有Service实例,存并添加到列表Ssrv之中;接下来,遍历Ssrv的每一个实例s,依据该s是否被某个ActivityThread实例所管理,即判断是否存在如下的引用关系序列:at→mServices→array[]→s,其中at表示一个ActivityThread实例。若存在这样一个引用关系序列,则s被at表示的ActivityThread实例所管理;否则,s则被认为是被销毁的,则将s从Ssrv中删除。
再然后,则要逐个判断剩余在Ssrv的每一个实例s是否真是泄露的,而这是通过对s到达所有GC root的路径进行分析而得到的。简单而言,首先需要获取s到达所有GC root的路径的集合,记为LP;逐一处理LP中的每一条路径p,若路径p包含任何java.lang.ref.SoftReference、java.lang.ref.WeakReference、java.lang.ref.PhantomReference、java.lang.ref.FinalizerReference以及java.lang.ref.Finalizer类型对象,则将路径p从LP中删除。此外,进一步从LP中去除所有以java.lang.Daemons$FinalizerDaemon类对象结尾的路径,同时从LP中去除包含FinalizerWatchdogDaemon线程的路径。当LP中所有路径都处理完毕,若LP为空,则判定实例s不是泄露的实例,而是有可能会被GC回收的;否则,LP不为空,则实例s仍在某些地方被引用而不能被GC回收,从而判定实例s为泄露的实例。
以上的实施例仅为说明本发明的技术思想,不能以此限定本发明的保护范围,凡是按照本发明提出的技术思想,在技术方案基础上所做的任何改动,均落入本发明保护范围之内。本发明未涉及的技术均可通过现有的技术加以实现。
Claims (3)
1.一种安卓应用Service构件泄露的高效检测方法,其特征在于:分为主程序Master与客户端检测应用APKchecker两部分;主程序Master运行在PC端,客户端检测应用APKchecker运行在测试安卓设备上,其具体步骤包括:
步骤一、主程序Master借助Android-Debug-Bridge安装待检测应用APKtarget;
步骤二、主程序Master借助Android-Debug-Bridge安装客户端检测应用APKchecker;
步骤三、主程序Master以“Start模式”启动客户端检测应用APKchecker;
步骤四、客户端检测应用APKchecker以“Start模式”尝试检测待测应用所发布的各项服务;
步骤五、主程序Master记录相应应用堆栈内存;
步骤六、主程序Master以“Bind模式”启动客户端检测应用APKchecker尝试检测待测应用所发布的各项服务;
步骤七、客户端检测应用APKchecker以“Bind模式”尝试检测待测应用所发布的各项服务;
步骤八、主程序Master记录相应应用堆栈内存;
步骤九、分析获取得到的应用堆栈内存,检测泄露的应用构件;
步骤九具体包括以下步骤:
步骤9.1、针对一个转储的应用堆栈.hprof文件,首先获取其中所包含的所有Service对象实例,用Ssrv表示;
步骤9.2、针对步骤9.1所获得的每一个Service对象实例s进行逐个鉴别,判定s是否已经被销毁,若s被判定为已销毁,则将其从Ssrv中删除;
所述步骤9.2判定一个Service实例s是否被销毁,则是依据该s是否被某个ActivityThread实例所管理,即判断是否存在如下的引用关系序列:at→mServices→array[]→s,其中at表示一个ActivityThread实例;若存在这样一个引用关系序列,则s被at表示的ActivityThread实例所管理;否则,s则被认为是被销毁的;
步骤9.3、针对步骤9.2处理后得到的Ssrv中的剩余对象实例s,进一步判定其是否是泄露的,若是则将其从Ssrv中删除;
所述步骤9.3判定一个Service实例s是否泄露,具体包括以下步骤:
步骤9.3.1、获取Service实例s到达所有GC root的路径,记为LP;
步骤9.3.2、从LP中去除所有包含java.lang.ref.SoftReference、java.lang.ref.WeakReference、java.lang.ref.PhantomReference、java.lang.ref.FinalizerReference以及java.lang.ref.Finalizer类型对象的路径;从LP中去除所有以java.lang.Daemons$FinalizerDaemon类对象结尾的路径,同时从LP中去除包含FinalizerWatchdogDaemon线程的路径;
步骤9.3.3、若LP为空,则s不是泄露的;否则,s则是泄露的;
步骤9.4、返回Ssrv,即获得所有泄露的Service实例。
2.根据权利要求1所述的安卓应用Service构件泄露的高效检测方法,其特征在于,步骤四、步骤六包含如下步骤:
步骤2.1、获取待检测应用APKtarget的AndroidManifest.xml文件,确定应用所包含的所有Service列表,记为LSrv;
步骤2.2、依据启动模式,选择不同处理逻辑:
步骤2.2.1、若启动模式为“Start模式”,则针对LSrv中每个Service,重复start/stop该Service;
其中的步骤2.2.1包含以下步骤:
步骤2.2.1.1、针对步骤2.1所获得的应用服务列表LSrv中的每一个服务srvi∈LSrv,重复以下步骤k次,其中k由用户指定,且k>=2:
步骤2.2.1.1.1、利用安卓系统提供的startService(Intent intent)API来启动对应服务srvi;若srvi.act不为空,则需要在参数intent中通过intent.setAction(srvi·act)的方式来指定具体的action;
步骤2.2.1.1.2、利用安卓系统提供的stopService(Intent intent)API来停止先前启动的服务srvi;若srvi·act不为空,则需要在参数intent中通过intent.setAction(srvi·act)的方式来指定具体的action;
步骤2.2.1.2、转储应用当前的堆栈内容
步骤2.2.2、若启动模式为“Bind模式”,针对LSrv中每个Service,重复bind/unbind该Service;
其中的步骤2.2.2包含以下步骤:
步骤2.2.2.1、针对步骤2.1所获得的应用服务列表LSrv中的每一个服务srvi∈LSrv,重复以下步骤k次,其中k由用户指定,且k>=2:
步骤2.2.2.1.1、利用安卓系统提供的bindService(Intent intent,ServiceConnection connection,int flags)API来启动对应服务srvi;若srvi.act不为空,则需要在参数intent中通过intent.setAction(srvi.act)的方式来指定具体的action;flags=BIND_AUTO_CREATE;
步骤2.2.2.1.2、利用安卓系统提供的unbindService(Connectionconnection)API来解除对先前绑定的服务srvi的绑定;
步骤2.2.2.2、转储应用当前的堆栈内容。
3.根据权利要求2所述的安卓应用Service构件泄露的高效检测方法,其特征在于,其中的步骤2.1具体包括以下步骤:
步骤2.1.1、利用逆向工程工具对待检测安卓应用.apk文件进行反编译,获取应用AndroidMenifest.xml描述文件;
步骤2.1.2、分析AndroidMenifest.xml文件,查找<service>标签,确定应用的服务列表;针对每个<service>标签所刻画的服务srvi,若其“android:exported”属性为“true”,则将srvi加入待检测服务列表LSrv;若其“android:exported”属性为“false”,但<service>标签包含<intent-filter>子标签,则同样将srvi加入待检测服务列表LSrv;对于包含<intent-filter>子标签的<service>标签,需要进一步分析该<intent-filter>子标签,获取其所包含的<action>标签的“adroid:name”属性的值,记为srvi.act;在该过程中,如果有多个<intent-filter>标签,则随机抽取一个;若选中的<intent-filter>标签包含多个<action>子标签,则随机抽取其中一个,并以它“adroid:name”属性的值记为srvi.act。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201710790636.4A CN107590013B (zh) | 2017-09-05 | 2017-09-05 | 一种检测Android应用Service构件泄露的高效方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201710790636.4A CN107590013B (zh) | 2017-09-05 | 2017-09-05 | 一种检测Android应用Service构件泄露的高效方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN107590013A CN107590013A (zh) | 2018-01-16 |
CN107590013B true CN107590013B (zh) | 2020-12-04 |
Family
ID=61051816
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201710790636.4A Active CN107590013B (zh) | 2017-09-05 | 2017-09-05 | 一种检测Android应用Service构件泄露的高效方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN107590013B (zh) |
Families Citing this family (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN109358896A (zh) * | 2018-10-12 | 2019-02-19 | 四川长虹电器股份有限公司 | 应用软件生命周期交叉检测的方法 |
CN110505112B (zh) * | 2019-07-09 | 2021-06-22 | 星融元数据技术(苏州)有限公司 | 一种网络性能监测方法、装置和存储介质 |
Citations (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103996007A (zh) * | 2014-05-29 | 2014-08-20 | 诸葛建伟 | Android应用权限泄露漏洞的测试方法及系统 |
CN104317702A (zh) * | 2014-09-30 | 2015-01-28 | 广东欧珀移动通信有限公司 | 一种智能移动终端内存自动化测试方法与装置 |
CN104834862A (zh) * | 2015-03-25 | 2015-08-12 | 南京大学 | 一种安卓权限提升攻击的全面静态分析系统 |
CN106095689A (zh) * | 2016-06-24 | 2016-11-09 | 北京奇虎科技有限公司 | 一种应用内存泄露的检测方法和装置 |
CN106649105A (zh) * | 2016-12-08 | 2017-05-10 | 武汉斗鱼网络科技有限公司 | 一种内存泄漏的检测方法和装置 |
-
2017
- 2017-09-05 CN CN201710790636.4A patent/CN107590013B/zh active Active
Patent Citations (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103996007A (zh) * | 2014-05-29 | 2014-08-20 | 诸葛建伟 | Android应用权限泄露漏洞的测试方法及系统 |
CN104317702A (zh) * | 2014-09-30 | 2015-01-28 | 广东欧珀移动通信有限公司 | 一种智能移动终端内存自动化测试方法与装置 |
CN104834862A (zh) * | 2015-03-25 | 2015-08-12 | 南京大学 | 一种安卓权限提升攻击的全面静态分析系统 |
CN106095689A (zh) * | 2016-06-24 | 2016-11-09 | 北京奇虎科技有限公司 | 一种应用内存泄露的检测方法和装置 |
CN106649105A (zh) * | 2016-12-08 | 2017-05-10 | 武汉斗鱼网络科技有限公司 | 一种内存泄漏的检测方法和装置 |
Non-Patent Citations (1)
Title |
---|
大规模移动应用第三方库自动检测和分类方法;王浩宇 等;《软件学报》;20170220;第28卷(第6期);全文 * |
Also Published As
Publication number | Publication date |
---|---|
CN107590013A (zh) | 2018-01-16 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
Rayside et al. | Object ownership profiling: a technique for finding and fixing memory leaks | |
CN101414272B (zh) | 内存泄漏的检测方法和装置 | |
Cui et al. | Tracking rootkit footprints with a practical memory analysis system | |
US9632916B2 (en) | Method and apparatus to semantically connect independent build and test processes | |
CN107292169B (zh) | 恶意软件的威胁溯源方法及装置 | |
US20080270855A1 (en) | Method For Detecting Memory Error | |
JP2009129451A (ja) | 悪性コードによって挿入されたダイナミックリンクライブラリ検出装置及び方法 | |
CN107590013B (zh) | 一种检测Android应用Service构件泄露的高效方法 | |
CN111832026B (zh) | 一种漏洞利用定位方法、系统、装置及介质 | |
CN111221721B (zh) | 一种单元测试案例自动化录制和执行方法及装置 | |
CN107168875B (zh) | 一种基于安卓应用多入口特性的Activity构件泄露检测方法 | |
CN107885489B (zh) | 一种快速检测实名登记数据指标的方法和系统 | |
CN113626823B (zh) | 一种基于可达性分析的组件间交互威胁检测方法及装置 | |
CN113127367B (zh) | Android动态权限申请的缺陷检测方法 | |
CN113282504A (zh) | 一种增量代码覆盖率检测方法及业务开发方法、装置 | |
CN105574409A (zh) | 一种注入代码提取方法及装置 | |
Toffalini et al. | Static analysis of context leaks in android applications | |
CN114048488B (zh) | 漏洞检测方法及系统 | |
CN111274585B (zh) | 一种Web应用越权漏洞检测方法、装置、设备和介质 | |
CN115470130A (zh) | 一种移动应用安全检测方法、装置及电子设备 | |
Liang et al. | Automatic detection of integer sign vulnerabilities | |
CN113419893B (zh) | 内存泄漏查证方法、装置、电子设备和存储介质 | |
US20230142407A1 (en) | Apparatus for analyzing non-informative firmware and method using the same | |
CN109426601B (zh) | 一种对程序进行无状态检测的方法和装置 | |
CN117668839A (zh) | 开源软件的检测方法及装置、存储介质和电子设备 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |