上图是我们熟知的Android系统架构图,分层的结构有利于权限的分级管理,对系统安全提供了一定的保障。Android系统采用分层的架构,由底层到上层依次为Linux内核层、HAL层、Native Lib及Runtime lib层、JNI层、framework层和应用程序层组成。Android应用程序组件是Android应用程序的基本组成单元,组件类型有Activity、Service、Broadcast Receiver、Content Provider等。Android内核本质上是增强版的LInux内核,低内存管理LMK(Low Memory Killer)、匿名共享内存(Ashmem),Binder通信机制等。这些内核增强使得Android在继承LInux内核安全机制的同时,进一步提升了内存管理、进程通信等方面的安全性。
上图是Android系统启动流程图,具体说明如下:Android系统运行于Linux内核之上,init进程是用户空间启动的第一个进程,职责主要为fork出系统关键进(Daemons)、servicemanager、zygote等;提供属性服务管理系统属性等。Zygote由init进程根据init.rc文件配置项创建,Zygote是一个虚拟机进程,同时也是一个虚拟机孵化器。负责虚拟机初始化、预置库的加载及初始化等。每当系统要求执行一个Android应用程序时,Zygote就会创建一个进程来执行该应用程序。SystemSever是Zygote第一个子进程,由Zygote进程孵化出来,作为Android框架的核心,主要负责Android系统初始化并启动其他服务运行于该进程空间。
目前Android系统智能终端设备占据了全球智能终端设备的大部分份额,随之而来安全问题也越来越多,安全问题是Android开发中一个重要的课题。从技术架构角度来看,Android安全模型基于强健的Linux操作系统内核安全性,通过进程沙箱机制、独特的内存管理与安全高效的进程通信机制、应用程序签名机制、应用权限管理机制等进一步提升系统安全性。
Android系统安全机制主要包括以下几方面:
1. 代码安全机制。
2. 进程沙箱机制。
3. 应用权限机制。
4. 应用签名机制。
5. 文件访问控制机制。
6. 其他安全机制。
java不同于C/C++,java是解释性语言,存在代码被反编译的隐患;Android引入了代码混淆技术默认混淆器为proguard, proguard还可用来压缩、优化java字节码,删除无用的类、字段、方法、属性、注释等。配置方法 在Android.mk中设置 LOCAL_PROGUARD_FLAG_FILES := proguard.flags include $(BUILD_PACKAGE) 原则 SDK API相关的不要混淆、native方法不要混淆、model不要混淆其他不需要混淆的类及方法。混淆语法
-keep class com.android.launcher3.CellLayout {
public float getBackgroundAlpha();
public void setBackgroundAlpha(float);
}
-keep class com.android.launcher3.DragLayer$LayoutParams {
public void setWidth(int);
public int getWidth();
public void setHeight(int);
public int getHeight();
public void setX(int);
public int getX();
public void setY(int);
public int getY();
}
混淆之后代码反编译后得到的class文件
Android将linux多用户隔离机制应用到应用程序隔离,一个用户标识(UID)识别一个给定用户,应用程序权限不同允许或者限制了应用程序对设备资源的访问。 应用权限的设置 共享用户ID即共用一个进程 Android源代码树携带的系统证书括“media”、“platform”、“shared”、 “testkey”等,其中“media”证书用于多媒体、下载场景中;“platform”证书用于系统场景中;“shared”证书用于启动器、电话簿场景中;“testkey”证书用于开发场景中,这些证书位于build/target/product/security
目录下;目前支持的“sharedUserId”属性包括“android.uid.system”、 “com.android.uid.test”、“android.uid.calendar” 、“android.media”、“com.android.framework.externalsharedpermstestapp”、“android.uid.shared”、“android.uid.phone”等。常用的包括“android.uid.system”、“android.media”、“android.uid.shared”等。
权限主要用来对应用的操作增加限制,防止恶意应用进行非法操作给用户造成敏感数据泄漏和设备被非法控制,防止恶意收费等。 权限级别如下:Normal权限、 Dangerous权限 、signatureOrSystem权限 、Signature权限 。 框架层权限定义位置
frameworks/base/core/res/ AndroidManifest.xml
<!-- Allows app to write to internal media storage -->
<permission android:name="android.permission.WRITE_MEDIA_STORAGE"
android:permissionGroup="android.permission-group.STORAGE"
android:label="@string/permlab_mediaStorageWrite"
android:description="@string/permdesc_mediaStorageWrite"
android:protectionLevel="signature|system" />
设置应用权限
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
权限验证 Android提供了多个方法可用于验证调用方是否具有相应的权限。如果调用方拥有相应的权限,则权限验证的返回值为PackageManager. PERMISSION_GRANTED
否则返回PackageManager.PERMISSION_DENIED
。
示例代码
if (permission != null) {
if (mContext.checkCallingOrSelfPermission(permission)
!= PackageManager.PERMISSION_GRANTED) {
return WindowManagerGlobal.ADD_PERMISSION_DENIED;
}
}
Android采用的SQLite目前采用明文存储数据;安全涉及加密、读写、搜索等。权限设置 android:permission android:readPermission android:writePermission
<provider android:name="ContactsProvider2"
android:authorities="contacts;com.android.contacts"
android:label="@string/provider_label"
android:multiprocess="false"
android:exported="true"
android:readPermission="android.permission.READ_CONTACTS"
android:writePermission="android.permission.WRITE_CONTACTS">
<path-permission 数据库安全--搜索
android:pathPrefix="/search_suggest_query"
android:readPermission="android.permission.GLOBAL_SEARCH" />
<path-permission
android:pathPrefix="/search_suggest_shortcut"
android:readPermission="android.permission.GLOBAL_SEARCH" />
<path-permission
android:pathPattern="/contacts/.*/photo"
android:readPermission="android.permission.GLOBAL_SEARCH" />
<grant-uri-permission android:pathPattern=".*" />
</provider>
Android签名机制其实是对APK包完整性和发布机构唯一性的一种校验机制。只有同一包名且采用同一数字证书的应用才被认为是同一个应用;数字证书的最大用途是应用升级和设置应用间通信的权限;
Android在权限管理上应用了Linux的ACL(Access Control List)
权限机制。 分区层面 在系统运行时,最外层安全保护是由Linux系统提供的,其中system.img所在的分区是只读的,不允许用户写入,而data.img所在的分区是可读写的,用于存放用户数据。分区的用户权限在init.rc
中定义。 单独文件 单独文件访问权限控制分群组、用户、权限。权限分可读、可写、可执行。命令:chown\chgrp\chmod
。
网络安全 加密算法(敏感数据) DES(对称)、3DES(对称)、RSA(非对称)、MD5、RC2/RC4(对称)、IDEA、AES、BLOWFISH等 Web服务(HTTP层) 三种手段WS-Security、SSL、数字签名。目前ksoap不支持WS-Security TCP层 SSL、TSL 数据链路层 WAPI
SE Android(Security-Enhanced Android)
是Android与SE Linux的结合,由美国NSA在2012年推出的Android os的安全强化套件,以支持在Android平台上使用的SE Linux。 DAC和MAC DAC(Discretionary Access Control)
自主访问控制 进程理论上所拥有的权限与执行它的用户的权限相同。比如,以root用户启动Browser,那么Browser就有root用户的权限,在Linux系统上能干任何事情。
MAC(Mandatory Access Control)
强制访问控制 即任何进程想在SELinux系统中干任何事情,都必须先在安全策略配置文件中赋予权限。凡是没有出现在安全策略配置文件中的权限,进程就没有该权限。
说明:在MAC访问控制下,有root权限并不能读写访问任何文件;任何进程访问特定的资源都需要遵循一定的控制策略。
调试工具 logcat 、adb 、 dumpsys
logcat
logcat [options] [filterspecs] #打印log
选项介绍
-b 查看日志类型,比如radio, main, events等,默认为main
-c 清空日志
-s #设置过滤器
logcat -s callMode:V #tag为callMode,级别为V的log
-f <filename> #输出到文件
-v <format> #设置log的打印格式,<format>是下面的一种:brief process tag thread raw time threadtime long
log format 形式如下:
-v process # D( 4816) volume state changed for /mnt/usbhost3 (unmounted -> removed) (MountService)
-v brief #I/SystemServer( 4816): Entered the Android system server!....
-g #得到环形缓冲区的大小并退出
130|root@mars-200:/ # logcat -g
/dev/log/main: ring buffer is 256Kb (255Kb consumed), max entry is 5120b, max payload is 4076b
/dev/log/system: ring buffer is 256Kb (111Kb consumed), max entry is 5120b, max payload is 4076b
adb常用命令 adb devices adb shell adb install / uninstall adb pull/push adb shell service list
dumpsys介绍 dumpsys
工具用于显示Android系统详细信息,dumpsys
是强大的系统分析工具,可以查看设备信息、进程内存使用信息、应用程序包信息、服务信息、权限设置信息、电源管理状态信息及activity信息。工具格式:dumpsys [option]
dumpsys | grep DUMP 获取dump支持的命令;
dumpsys activity: 显示activity的相关信息,包括任务栈等;
dumpsys window: 显示键盘,窗口和它们的关系;
dumpsys diskstats: 磁盘相关信息
在学习Android开发的过程你,你往往会去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局可能会让你爱不释手,作为一个开发者,你可能会很想知道这些效果界面是怎么去实现的,这时,你便可以对改应用的APK进行反编译查看。
反编译的目的不是去搞破坏,主要目的是为了促进开发者学习,借鉴好的代码,提升自我开发水平。
反编译工具 dex2jar apktool jd-gui
步骤如下:
1. 将apk文件重命名为.zip文件后解压缩提取 classes.dex
2. 通过dex2jar工具将classes.dex文件转成jar包 ./d2j-dex2jar.sh classes.dex
3. apktool还原apk资源文件 ./apktool.sh -d test.apk
可将相关权限加入Android运行时权限管控,根据签名、配置文件等控制使用