EspyDroid:检测安卓反射泄露

揭示安卓应用程序中由反射引起的安全敏感信息泄露

1 引言

反射是应用在运行时检查和修改对象结构与行为的能力。反射支持诸如检查对象的类、构造类的实例、检查类的字段、调用对象的方法,以及在运行时更改构造函数、方法和字段的可访问性标志等语言特性。

不幸的是,恶意软件作者正在利用反射来规避静态分析器的检测。通过对四年间的数据进行分析,Andrubis[18]报道称,57.08%的安卓恶意软件样本使用了反射技术。反射并不使用常规的编程语言语法,而是将类名、方法名等作为参数传递给反射API。此外,这些参数可以动态构造或在运行时提供。恶意软件家族Obad和FakeInstaller是两种最复杂的恶意软件家族,它们结合反射和代码混淆技术,以逃避静态分析技术的检测。

此外,安卓为应用程序内组件间的通信提供了组件间通信(ICC)功能。ICC是安卓提供的一项功能,旨在促进组件的重用。Intent[5]是一种消息传递对象,用于请求某个组件(来自同一或不同的应用)执行操作,以实现组件间通信(ICC)。

不幸的是,恶意软件作者滥用此功能,将泄露分布在给定应用的多个组件中[20]。针对单个组件泄露设计的分析技术可能无法适用于基于ICC的泄露[10]。

示意图0

代码清单1.1展示了来自知名安卓测试套件DroidBench的1应用Onlytelephony的应用。该应用使用了反射API和ICC(第7–9行)。类android.Telephony.TelephonyManager定义了方法getDeviceId()。主活动通过使用类.通过名称查找反射API(第3行)实例化该类的对象。然而,方法名是通过使用reverse()函数动态构建的(第2行)。然后,它将这个动态构建的方法名传递给getMethod()反射API(第5行),从而创建方法对象。最后,它通过反射APIinvoke()调用方法getDeviceId()(第6行),返回imei值。主活动通过安卓Intent将imei值传递给活动2(第7–9行),而活动2通过短信执行imei的泄露。

清单1.1. 利用反射API进行泄露

1 String cls="android.Telephony.TelephonyManager" 
2 String reverse=new StringBuffer("dIeciveDteg").reverse().toString();
3 类 c=类.通过名称查找(cls); 
4 tM =(电话管理器) this.getSystemService (上下文.TELEPHONY SERVICE); 
5 方法 method = c.getMethod(reverse, new 类<?>[0]); 
6 String id=(String) 方法.invoke(tM); 
7 Intent i=new Intent(this, 活动2.类);
8 i.putExtra("imei", id);
9 startActivity(i);
$MainActivity$
10 Intent im = getIntent();
11 String 值= getIntent().getExtras().getString("imei");
12 SmsManager sm =SmsManager.getDefault();
13 sm.sendTextMessage(phoneNo,null,值,null,null); $Activity2$

这里的reverse()方法只是一个示例,在其他情况下会应用更复杂的方法,例如加密、子串、拼接等,以规避静态分析。FlowDroid对该示例的分析结果[8], IccTA[16], AmanDroid[25],和DroidSafe[14]静态分析工具未能捕获任何隐私泄露,因为反射阻碍了污点分析。具备反射感知能力的静态分析方法DroidRA[17]也未能识别出该应用中的泄露。失败的原因在于应用程序在运行时构造了方法名。反射API目标的动态构造非常简单,可以通过多种方式实现,例如字符串拼接、加密、静态无法解析的Intent以及子字符串生成。此外,不仅可以通过反射调用类或方法,Intent也可以通过反射调用。1.2展示了来自DroidBench的另一个动机示例2其中Intent被用于反射。

示意图1

清单1.2. Intent反射

1 类<?> i =类.通过名称查找("android.content.Intent"); 
2 构造函数 c = i.getConstructor(上下文.class, 类.class); 
3 对象 intent = c.newInstance(this, A2.class); 
4 方法 m= intent.getClass().getMethod("put"+"Extra", params); 
5 对象[] obj ={"imei", id }; 
6 m.invoke(intent, obj); 
7 startActivity((Intent)intent);

与清单1.1中的普通Intent创建方式不同(第7–9行),该应用通过反射API创建Intent对象(第1–3行),调用方法将imei传递给A2(第4–6行),并启动A2 Activity(第7行)。此处恶意软件使用Intent反射来隐藏两个组件之间的通信。

对各种在反射中实现任何类型非恒定参数使用的应用进行分析的结果表明,即使是基于反射API常量字符串分析的静态反射感知分析方法,在识别泄露方面也存在失败。这极大地提出了对具备ICC支持的反射感知运行时分析方法的需求。

贡献

本工作的主要贡献如下:
– 本文提出了EspyDroid:一种结合动态分析与代码插桩的系统,用于揭示应用通过反射以及参数混淆或加密所进行的隐藏泄漏。EspyDroid解析反射调用的实际参数,并使用运行时参数自动将应用插桩为等效的非反射调用,从而生成已插桩应用。
– EspyDroid能够检测通过Intent在多个组件之间分布的信息泄露,甚至当Intent本身也是通过反射调用时也能检测。
– 我们在广泛使用的DroidBench[4]基准、75个PlayStore应用以及从VirusShare[7]中随机选取的277个应用上测试了EspyDroid。结果表明,相比分析原始应用,分析EspyDroid生成的插桩后的应用可提高静态分析器在发现信息泄露方面的精确度和准确性。
– 为了便于其他研究人员和实践者在该方向上的使用,我们计划将EspyDroid作为开源工具连同用户文档一并发布。

组织结构

本文其余部分组织如下:第2节简要介绍反射API及其类别。我们在第3节讨论所提出的解决方案。第4节报告评估结果。第5节描述了我们方案的局限性。相关工作包含在第6节中,并在第7节总结全文。

2 背景

本节提供了反射API的分类,并举例说明了这些API在实施信息泄露中的使用方式。源是指任何访问用户私有数据的方法,接收器是指任何可能将这些数据泄露到应用程序外部的方法。恶意Android应用利用反射API来隐藏对敏感源和汇聚点的调用。反射API属于四个主要类别[1]。接下来我们将介绍这些类别,以及每一类如何被用于数据泄露。

构造类对象或检查对象的类

恶意应用通过反射实例化与源和接收器方法对应的类,以隐藏泄露的识别。分析技术必须正确识别被实例化的类,以捕获对私有信息的访问。清单1.3使用反射APIConcreteClass通过forName反射API创建该类的对象,并使用newInstance反射API进行实例化(第2行)。类名ConcreteClass并未直接出现在应用字节码中。它将设备ID存储到该类的imei字段中(第3行),从而执行泄露。

代码清单1.3. 反射类实例化

1 String cls ="preConcreteClasspost".substring(3, 16); 
2 BaseClass bc=(BaseClass) 类.通过名称查找(cls).新建实例(); 
3 bc.imei = telephonyManager.getDeviceId();//source

检查或调用类方法

恶意应用通过反射调用方法来隐藏访问(泄露)用户数据的敏感源(汇聚点)。DroidBench中的1.4示例通过setImei(第4和第5行)方法使用getMethod和invoke API进行反射调用。ReflectiveClass类的setImei方法调用汇聚点方法sendtextMessage()以泄露设备ID。

清单1.4. 反射方法调用

1 //source 
2 = = "ReflectiveClass"
String imei telephonyManager.getDeviceId(); 类 c 类.通过名称查找( );
3 //No class type information 
4 = = "setIme"+"i"
对象 o c.newInstance(); 方法 m c.getMethod( ,String.class); 
5 m.invoke(o, imei);

检查或设置类字段

该值通过反射API的set()方法赋给类的字段,并通过反射API的get()方法获取该值。

清单1.5. 基于字段的反射访问

1 String 设备ID= telephonyManager.getDeviceId();//source
2 类<?> c= this.getClassLoader().loadClass("ConcreteClass");
3 Object o = c.getConstructor(String.类).newInstance();
4 字段 f1=c.getField("imei");
5 f1.set(o, 设备ID);
6 字段 f2=c.getField("imei");
7 String refdeviceId =(String) f2.get(o);

清单1.5首先将敏感值,即设备ID存储到imei类字段中(第4‐5行),然后通过反射API检索(第6‐7行)。该应用程序向接收器发送refdeviceId而不是deviceId(此种情况下分析将能够识别出泄漏)以隐藏泄漏。

获取类的构造函数并实例化构造函数

类的特定构造函数可通过getConstructor()API获取。恶意应用通过构造函数将敏感数据存储在类字段中,随后再次读取并造成泄露。分析必须能够处理基于构造函数的反射式类实例化。如Listing1.6所示的示例,使用ConcreteClass的构造函数(第3行)反射式地实例化BaseClass对象,并将设备ID存入其中。

清单1.6. 基于构造函数的反射类实例化

1 String deviceId= telephonyManager.getDeviceId();//source
2 类<?> cls =类.通过名称查找("ConcreteClass");
3 BaseClass bc=(BaseClass) cls.getConstructor(String.class).newInstance(deviceId);

我们准备了一个包含四个类别的各种反射API的列表。该列表用于EspyDriod的所有阶段。

3 提出的解决方案:EspyDroid

EspyDroid是一个结合动态分析与代码插桩的系统,用于揭示通过反射和运行时数据依赖实现的潜在隐藏泄漏。EspyDroid的整体架构如图1所示。

EspyDroid的完整系统由四个主要模块组成:应用钩子、动态分析器、日志追踪器和插桩。

EspyDroid首先在APK中搜索反射API的存在。EspyDroid假设反射API本身未被混淆。我们使用Andro‐Guard[3]来检查反射的存在,它是一个用Python编写的静态分析工具,可直接在APK文件上运行。在确认存在反射后,应用将进行进一步分析。从动机示例中可以看出,如果参数具有任何运行时依赖,则无法通过静态方式推断反射API的参数和返回值信息。应用钩子和动态分析器的目标是通过监控第2节中提到的四个类别的相关反射API来获取这些信息。

3.1 应用钩子和动态分析器

动态分析器模块使用APIMonitor[2]工具为反射API添加监控代码。监控代码类似于反射API的包装,当重新打包的应用执行期间调用指定的API时,该代码会将这些API记录到安卓logcat中,并附带预定义的标签。为了实现应用的自动UI探索,我们采用了先前工作中的智能UI探索模块[13],这是一种基于深度优先的黑盒测试方法,并通过Robotium框架进行扩展[6]。探索时间取决于应用GUI的复杂程度。在包含40个应用的实验数据集上,平均探索时间为6分钟。

需要注意的是,详细的解释内容过于庞大,无法在本文中完整呈现。然而,感兴趣的读者可以参考[6]。将属于四个反射类别的各种反射API作为输入提供给APIMonitor,并将REFLECTIONCALL设置为标签。APIMonitor的限制在于,它仅记录API的参数类型、值以及返回类型和值,但不会添加有关调用这些API的包装类或方法的任何信息。而获取反射API所在包装类和方法的信息对于插桩是必要的。下一节将详细说明其必要性。为了实现这一点,EspyDroid首先使用Soot对APK进行挂钩[15],使得每当一个反射API被记录时,其包装类和方法的信息也会以预定义标签WRACLASS‐METHOD一同被记录。图2显示了相应的日志输出到Listing的动机示例1.1在应用钩子和动态分析之后。运行时分析与监控使EspyDroid能够解析具有运行时参数依赖、加密或混淆的反射调用。

3.2 日志追踪器

日志追踪器处理原始日志,并将其以处理后的形式存储在适当的数据结构中。我们使用独立的哈希映射数据结构来存储属于四种反射类别的各种运行时值。日志追踪器读取每行日志并检查两个标签之一。如果发现WRACLASS‐METHOD标签,则将对应的包装类类名/方法名值作为哈希映射的键进行保存。接着,它处理带有REFLECTION‐CALL标签的日志语句,并将数据存储在相应的数据结构中。我们使用以下六个哈希映射数据结构:

<String, 数组列表<数组列表<String>>> mapWraToClasses
<String, 数组列表<数组列表<String>>> mapWraToMethodDeclared
<String, 数组列表<数组列表<String>>> mapWraToFieldDeclared
<String, 数组列表<数组列表<String>>> mapWraToFieldGetSet
<String, 数组列表<数组列表<String>>> mapWraToConsGet
<String, 数组列表<数组列表<String>>> mapWraToConsInstantiation

哈希映射mapWraToClasses用于类反射,mapWraToMethodDeclared用于方法声明与调用,mapWraToFieldDeclared用于字段声明,mapWraToConsGet用于字段值的设置/获取,mapWraToConsGet用于构造函数引用创建,以及mapWraToConsInstantiation用于存储构造函数实例化的相关信息。

图3展示了这些哈希映射的总体结构。其中,包含该反射调用的Jimple类名/方法名(例如,JC1/M1)作为键,而该调用的各种运行时值则作为值存储在对应的数组列表中。选择包装类类名/方法名作为键的原因是为了在插桩时提供便利,确保特定类和方法中的所有反射仅在该类中解析。哈希映射中的数组列表包含了运行时存储的不同参数,例如反射调用的类或方法名、方法修饰符、方法参数等。图4展示了对应于图2日志的哈希映射数据结构。

3.3 插桩

该模块的目的是通过插入与反射调用等效的非反射调用来实现插桩,从而使静态分析器能够进行后续分析。我们选择了Jimple(Soot的中间表示(IR))来进行插桩。Soot是一个最初设计用于分析和转换Java字节码的框架,并已扩展支持安卓。Java中的变量对应于Jimple中的局部变量。为了保持语义完整性,原始的反射调用并未被消除。此处的关键概念是以保持数据流精度的方式来构造非反射语句。例如,为了能够检测到泄露,必须使非反射语句将其结果赋值给与反射语句相同的结果赋值目标局部变量。此外,在插桩后的非反射调用中,对应于反射调用参数的局部变量也必须保持一致。

Soot将APK的所有类转换为Jimple以进行插桩。算法1描述了插桩的高层概念。该模块遍历APK的每一条Jimple语句,并检查属于四个反射类别的各种反射语句(第1–3行)。它使用来自日志中哈希映射解析得到的参数和返回值的运行时信息,在Jimple中构建等效的非反射语句。非反射语句的运行时构建取决于反射API的类别。因此,它执行类别检查(第5、9、17和22行)。但在所有情况下,均使用相应的哈希映射来获取运行时信息。在所有情况下,哈希映射的键均为包含反射调用的Jimple类名/方法名,以确保属于任何Jimple类/方法的反射仅在该Jimple类中被解析。接下来,使用数组列表中的索引来确保在方法内部访问的是同一条反射语句的信息。因此,在插桩过程中,我们首先获取Jimple

算法1. EspyDroid的插桩算法

结果:已插桩应用
1 对于 each Jimple class JC of apk执行do
2   for each statement S of JC do
3     如果 S是反射调用那么
4       根据反射的类别进行插桩;
5       如果 S是类反射那么
6         从mapWraToClasses哈希映射中获取类名;
7         在 S 之后对“$r= new aclassname”语句进行插桩
8       end
9       如果 S是方法声明反射那么
10        在 S 之前对“$r= new aclassname”语句进行插桩
11        查找实际方法名的运行时详细信息 ,
            来自 mapWraToMethodDeclared 的参数类型、返回类型 哈希映射
12        通过使用反向查找来找到与参数对应的局部变量 数据流分析。
13        根据信息构建非反射语句 在上述两个步骤中获得;
14        找到 JC 中与此方法对应的调用语句 使用数据流分析进行声明;
15        在此 invoke 之后插桩构建的语句 以保持数据流准确的方式声明;
16      end
17      如果 S是构造器调用反射那么
18        从 mapWraToConsGet 哈希映射中查找类名和参数
            使用 mapWraToConsInstantiation 哈希映射的类型;
19        通过使用反向查找来找到与参数对应的局部变量 S 的数据流分析;
20        构造并插桩一个非反射的构造函数调用 根据上述信息在 S 之后的语句;
21      end
22      如果 S是字段反射那么
23        从 mapWraToFieldDeclared 中查找字段名及其类名 哈希映射
24        使用上述内容构造非反射字段访问语句,并根据字段是静态还是非静态。
            此外,语句的构造还取决于字段的值被检索或赋值;
25      end
26    end
27  end
28 结束

包含此反射调用的类名和方法名,使用Soot API获取。该信息用作键,以从相应的哈希映射中映射运行时值。

第一类是类反射,它可以通过使用forName/loadClass/getClass API中的任意一种来实例化类。类名是这些API的参数,通常会被恶意应用混淆。该模块使用mapWraToClasses哈希映射来获取类名对应的实际运行时值 aclassname(第6行),并构造一个“$r = new aclassname”语句,在类反射语句之后进行插桩(第7行)。这里确保了$r是类型为aclassname的局部变量。因此,该局部变量声明语句也会被插桩。

第二类是方法反射,它可以通过使用getMethod/getDeclaredMethod API创建方法对象,然后通过invoke API调用该方法。为了构造非反射语句,需要获取反射调用的运行时值、方法的类名、修饰符、返回类型、参数类型、与参数对应的Jimple局部变量,以及Jimple类和包装方法。除与参数对应的变量外,所有这些信息均从mapWraToMethodDeclared哈希映射中获取。在方法反射语句中,方法的参数以对象数组的形式传递,而在对应的非反射语句中,这些参数需要作为单独的局部变量。为了获取这些局部变量,实现了反向数据流分析,用于计算构成对象数组的各个局部变量(第12行)。非反射语句将在该方法声明的invoke之后进行插桩。可能存在一组方法声明后跟一组调用的情况,并且这些调用可能是交错的。例如,方法M1、M2、M3的声明可能按M3、M2、M1的顺序进行调用。为了处理这种交错调用的情况,我们还实现了前向数据流分析,以找到与当前方法声明对应的调用,并仅在该调用之后插桩非反射语句。为了使静态分析器能够执行精确的数据流分析,确保非反射语句将结果赋值给与反射语句赋值相同的局部变量。

第三类是构造器调用反射,其中方法名始终为 ,但需要其类名和参数类型以及对应于参数的变量来构建非反射语句。类名从mapWraToConsGet获取,参数类型从mapWraToConsInstantiation哈希映射中获取。采用类似的反向数据流分析方法来获取对应于方法参数的变量。

第四类是字段反射,其中反射API可能用于获取字段的值或将值赋给字段。非反射语句的构造需要字段名、其所属类以及对应字段的Jimple局部变量。前两个信息从哈希映射中获得,而最后一个信息仅从当前Jimple中获取。插桩在当前字段反射之后进行,以保持数据流的准确性。

如清单所示的Intent反射1.2,Intent本身是一个类,其方法putExtra用于向另一个组件发送数据。从该方法可以看出,任何组件的反射都将在该组件中进行仅针对应用。此处,Intent反射本身将被视为类和方法反射,并相应地进行插桩。

4 评估

我们使用来自基准测试的开源应用以及从PlayStore和VirusShare获取的字节码格式的APK文件对EspyDroid进行评估。实验数据集中反射的主要用途识别如下:
1. 通过反射实例化类来隐藏敏感信息泄露。
2. 通过反射实例化构造函数来隐藏存在于构造函数中的泄露。
3. 通过反射调用方法来隐藏被调用的恶意方法。
4. 通过反射访问字段,以将恶意信息设置到字段中进行泄露,或从字段中获取恶意信息。
5. 为进一步增加分析难度,使用继承特性,其中被实例化的类是派生类,而对字段/方法的访问则来自基类。
6. 以上所有情况中,泄露分布在多个组件中。
7. 反射调用Intent以隐藏组件之间的通信。
8. 对反射API使用混淆或依赖运行时的参数,使得即使基于静态分析的反射感知技术也无法成功分析。

此外,在实验数据集中,泄露也分布在应用的多个组件中。在基于多个组件的泄露中,两个或更多组件通过ICC机制进行通信。

4.1 开源应用

从DroidBench基准测试、领域内最相近的研究工作DroidRA以及一些修改版的DroidRA应用中选取了开源应用,这些修改版应用包含了加密/混淆技术。DroidBench是一个用于评估静态和动态工具在Android应用程序上有效性的公开测试套件。该基准被包括近期研究工作在内的多篇学术论文用于[21,24,26,27]评估。

我们使用FlowDroid[8]静态分析器来查找启用和未启用EspyDroid的应用中的源、汇聚点以及泄漏路径。表1展示了EspyDroid对开源应用的分析结果,突出显示了已识别的源和汇聚点。结果表明,FlowDroid在存在反射的原始应用中未能识别出部分源、汇聚点和路径,但该工具在插桩后的应用中成功识别了这些遗漏的泄露。在原始代表性数据集中,FlowDroid能检测到19条泄漏路径,而在由EspyDroid生成的已插桩应用中,该工具能检测到51条泄漏路径。不仅泄漏路径数量增加,检测到的源和汇聚点数量也显著提升。FlowDroid能检测到108个源和35个汇聚点,而结合EspyDroid后,FlowDroid能检测到130个源和42个汇聚点。DroidRA能检测到119个源、39个汇聚点和38条泄漏路径。这些数据表明,DroidRA的精确度相较于EspyDroid较低。由于这些应用的源代码可用,我们可以验证EspyDroid检测到了DroidBench应用中的所有源、汇聚点和路径。FlowDroid在分析原始应用时遗漏了这些信息,导致用户私密数据通过短信和日志等接收器发生泄露。泄露的数据可能进一步包含用户的敏感信息,如财务详情、位置等,一旦被利用,可能导致数据外泄和经济损失。除了一款在循环中调用反射API的单个应用外,EspyDroid捕获了DroidBench数据集中的所有泄露。

表1. 包含确认反射的开源应用的结果

序号 #应用仓 FlowDroid EspyDroid + FlowDroid
汇聚点 路径 汇聚点 路径
1 18 DroidBench 73 21 16 92 28 37
2 9 DroidRA 23 10 1 26 10 10
3 2 DroidRA with 加密 12 4 2 12 4 4
总计 总计 总计 108 35 19 130 42 51

4.2 APK文件中的字节码

我们从PlayStore随机下载了75个应用,供EspyDroid进行分析。EspyDroid发现了两个应用,如表2所示,FlowDroid在插桩后的应用中捕获到了额外的泄露。EspyDroid在VirusShare应用上的结果表现出改进。在分析的277个应用中,有167个应用被调查,这些应用使用了反射。尽管由于复杂的混淆、多层加密和反射,这些应用在源、接收器和路径的泄露检测结果上未显示出改进,但FlowDroid在EspyDroid插桩后的三个应用的调用图的前向边、后向边和路径方面观察到了显著改进。FlowDroid使用IFDS框架[22]将程序分析问题简化为图可达性问题。IFDS框架首先将应用转化为调用图,计算前向边和后向边,然后构建源与汇聚点之间的路径。表3展示了结果的改进情况。

表2. PlayStore应用上的结果

序号 应用名称 FlowDroid EspyDroid + FlowDroid
汇聚点 路径 汇聚点 路径
1 air.com.productmadness.atlas 119 59 23 119 59 25
2 com.productmadness.hovmobile 95 62 62 95 62 72

表3. 来自VirusShare应用的评估结果

应用MD5 FlowDroid EspyDroid + FlowDroid
前向边 后向边 前向边 后向边
0fa1d7a9ef7011ca8976910b07347732 311748 115400 460679 181660
eedaf39b21aca987b315f1e5d0e4cba6 108015 29017 110693 29441
ddc75a9aea5ac4933bcdf6001c0ef817 323104 123781 343234 128386

该应用3通过反射实例化类doom.androidquickfaster849.R$layout并访问其字段where,其中类名是动态构建的。这种类名的运行时构建需要采用类似EspyDroid结合动态分析的方法。FlowDroid未能检测到从源getDeviceId()和getCountry()到接收器StartActivity()的数据流泄露,而EspyDroid能够识别该泄露。在原始应用中,FlowDroid构建了20条源与接收点之间的连接,而在EspyDroid的已插桩应用中,FlowDroid构建了22条连接。结果表明,借助EspyDroid,静态分析工具在使用反射的应用中的精度得到了提升。

5 EspyDroid的局限性

尽管EspyDroid能够通过避免因反射引起的问题来提升现有静态分析器的性能,但该技术仍存在某些局限性。所提出的自动动态分析模块可能会遗漏对一些复杂视图的覆盖,例如安卓为丰富图形用户界面所提供的自定义操作栏、自定义视图等。因此,我们的方法可能无法检测到隐藏在这些视图背后的某些反射使用情况。在未来的工作中,我们将开发并集成更先进的智能技术,以实现更高的代码覆盖率。在某些情况下,不同的运行可能导致反射API的某些参数产生不同的运行时值。然而,实际上可能无法通过动态方式获取这些参数的所有可能值。另一个局限性是,目前EspyDroid无法解析基于循环的反射API调用。

6 相关工作

截至目前,大多数高性能的静态分析器在处理反射方面已显现出其局限性。Bodden等人在[9]中提出了针对Java应用程序的反射感知分析方法。然而,该方案无法直接应用于Android应用程序,因为他们的方法基于加载时插桩,而安卓平台目前不支持这一机制。DroidRA[17]通过COAL声明式语言将反射调用的识别建模为复合常量传播问题[19]。然而,当反射API的参数存在运行时依赖时,例如间接传递getDeviceId作为dIeciveDteg.reverse()时,依赖常量字符串推断会使该方法失效,导致DroidRA未能识别出泄露。

涟漪[28]是一种感知反射的分析技术,通过在DroidRA中添加类型推断,以在反射参数的直接字符串分析不充分的情况下获得更精确的结果。然而,由于其本质上是静态的,当反射与参数的运行时依赖结合时,涟漪也会失效。

近年来,已有一些研究采用混合分析方法来处理安卓中的反射问题。StaDyna[29]的作者们专注于通过混合方法解决动态代码加载和反射问题。该方法首先通过静态分析构建应用程序的方法调用图(MCG),然后利用运行时捕获的附加信息对其进行扩展。然而,其评估仅限于节点和边数量的增加,并未关注隐私泄露问题。此外,该方法需要修改安卓操作系统,导致安装和使用较为复杂。目前的实现仅针对安卓操作系统版本4.1.2 r2,限制了其可扩展性。它并未提供一种方式使现有的静态分析器直接受益,即无法支持它们执行感知反射的分析。BPS罗查等人提出了用于信息流控制的轻量级混合静态‐运行时机制[23]。

拉斯托弗等人在[21]中提出了基于混合方法的harvester工具,用于从安卓应用程序中自动提取运行时值。首先,它通过静态反向切片生成一个简化的APK,并在模拟器上执行该简化后的APK。在动态执行过程中解析出的反射调用目标的运行时值,会在应用程序的字节码中表现为普通的方法调用。其主要局限在于当前的切片实现仅限于单个安卓组件,因此任何使用组件间通信(ICC)的样本都无法被分析。相比之下,Espy‐Droid还能够处理使用ICC的恶意软件。由于harvester工具的源代码不可获取,我们无法实际使用Harvester4。

本文是我们之前在ASIACCS[12]上发表的海报工作的扩展,具有显著改进。首先,我们引入了基于HashMap的数据结构和前向数据流分析,以确保交错API插桩的准确性。其次,我们增加了App钩子模块,该模块可确保属于特定类和方法的反射调用仅在该类和方法中进行非反射式插桩。第三,我们将评估数据集扩展至包含PlayStore和VirusShare应用。

7 结论

本文中,我们提出了EspyDroid,一种面向安卓应用分析的反射感知混合分析技术。通过实验评估,我们证明了EspyDroid能够有效抵御加密、混淆或反射参数的任何运行时依赖。该方案还可检测利用组件间通信在单个应用程序的多个组件中分布泄露的恶意软件。结果表明,在存在反射的情况下,静态分析器会产生大量误报。EspyDroid通过捕获仅靠静态分析器遗漏的泄露,提高了精确度。我们计划将EspyDroid作为开源工具连同基准测试结果一并发布。在未来的工作中,我们计划开发并集成更先进的智能技术,以提高代码覆盖率,从而减少恶意应用造成敏感信息泄露时的误报。

【电能质量扰动】基于ML和DWT的电能质量扰动分类方法研究(Matlab实现)内容概要:本文研究了一种基于机器学习(ML)和离散小波变换(DWT)的电能质量扰动分类方法,并提供了Matlab实现方案。首先利用DWT对电能质量信号进行多尺度分解,提取信号的时频域特征,有效捕捉电压暂降、暂升、中断、谐波、闪变等常见扰动的关键信息;随后结合机器学习分类器(如SVM、BP神经网络等)对提取的特征进行训练与分类,实现对不同类型扰动的自动识别与准确区分。该方法充分发挥DWT在信号去噪与特征提取方面的优势,结合ML强大的模式识别能力,提升了分类精度与鲁棒性,具有较强的实用价值。; 适合人群:电气工程、自动化、电力系统及其自动化等相关专业的研究生、科研人员及从事电能质量监测与分析的工程技术人员;具备一定的信号处理基础和Matlab编程能力者更佳。; 使用场景及目标:①应用于智能电网中的电能质量在线监测系统,实现扰动类型的自动识别;②作为高校或科研机构在信号处理、模式识别、电力系统分析等课程的教学案例或科研实验平台;③目标是提高电能质量扰动分类的准确性与效率,为后续的电能治理与设备保护提供决策依据。; 阅读建议:建议读者结合Matlab代码深入理解DWT的实现过程与特征提取步骤,重点关注小波基选择、分解层数设定及特征向量构造对分类性能的影响,并尝试对比不同机器学习模型的分类效果,以全面掌握该方法的核心技术要点。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值