android aapt 用法 -- ApkReader
aapt 是android assert packaging tool的缩写,具体如下:
1. 列出apk包的内容
aapt l[ist] [-v] [-a] file.{zip,jar,apk}
-v 以table形式列出来
-a 详细列出内容
例如:aapt l <你的apk文件>,这个命令就是查看apk内容
2. 查看apk一些信息
aapt d[ump] [--values] WHAT file.{apk} [asset [asset ...]]
badging Print the label and icon for the app declared in APK
permissions Print the permissions from the APK.
resources Print the resource table from the APK.
configurations Print the configurations in the APK.
xmltree Print the compiled xmls in the given assets.
xmlstrings Print the strings of the given compiled xml assets.
例如:aapt d permissions <apk文件>, 这个就是显示这个apk所具有的权限
3. 编译android资源
aapt p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] /
[-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] /
[--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] /
[--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] /
[--rename-manifest-package PACKAGE] /
[--rename-instrumentation-target-package PACKAGE] /
[--utf16] [--auto-add-overlay] /
[--max-res-version VAL] /
[-I base-package [-I base-package ...]] /
[-A asset-source-dir] [-G class-list-file] [-P public-definitions-file] /
[-S resource-sources [-S resource-sources ...]] [-F apk-file] [-J R-file-dir] /
[--product product1,product2,...] /
[raw-files-dir [raw-files-dir] ...]
这个比较复杂,只解释几个关键参数。
-f 如果编译出来的文件已经存在,强制覆盖。
-m 使生成的包的目录放在-J参数指定的目录。
-J 指定生成的R.java的输出目录
-S res文件夹路径
-A assert文件夹的路径
-M AndroidManifest.xml的路径
-I 某个版本平台的android.jar的路径
-F 具体指定apk文件的输出
例如:
一. 将工程的资源编译R.java文件
aapt package -m -J <R.java目录> -S <res目录> -I <android.jar目录> -M <AndroidManifest.xml目录>
二. 将工程的资源编译编译到一个包里
aapt package -f -S <res目录> -I <android.jar目录> -A<assert目录> -M <AndroidManifest.xml目录> -F <输出的包目录>
4. 打包好的apk中移除文件
aapt r[emove] [-v] file.{zip,jar,apk} file1 [file2 ...]
例如:aapt r <你的apk文件> AndroidManifest.xml, 这个就是将apk中的AndroidManifest移除掉
5. 添加文件到打包好的apk中
aapt a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]
例如:aapt a <你的apk文件> <要添加的文件路径>, 这个就是将文件添加到打包好的apk文件中
6. 显示aapt的版本
aapt v[ersion]
例如:aapt v, 就是打印这个结果 Android Asset Packaging Tool, v0.2
aapt简介
aapt即Android Asset Packaging Tool,我们可以在SDK的platform-tools目录下找到该工具。
aapt可以查看、 创建、 更新ZIP格式的文档附件(zip, jar, apk)。 也可将资源文件编译成二进制文件,
尽管你可能没有直接使用过aapt工具,但是build scripts和IDE插件会使用这个工具打包apk文件构成一个Android 应用程序。
主要用法
下面的这个参数列表基本向我们展示了如何使用aapt以及aapt的基本功能了。
aapt l[ist]:列出资源压缩包里的内容。
aapt d[ump]:查看APK包内指定的内容。
aapt p[ackage]:打包生成资源压缩包。
aapt r[emove]:从压缩包中删除指定文件。
aapt a[dd]:向压缩包中添加指定文件。
aapt v[ersion]:打印aapt的版本。
使用aapt
这里我就用一个应用来做测试sample,应用为:应用汇应用市场。
列举出apk中的所有文件
walfred@ubuntu:~/lab$ aapt l yingyonghui.apk
当然这个apk的内容太多,一张纸显示不了所有的内容,你可以将其重定向到一个专门的文件中去,这样查看也方便。
walfred@ubuntu:~/lab$ aapt l yingyonghui.apk > yingyonghui.txt
查看apk的基本信息
aapt最实用的功能,通过d(ump)参数可以查看该apk的基本信息以及权限等,但该参数还有一个value,可以选用的value值如下:
d参数的语法如下:
aapt d[ump] [--values] WHAT file.{apk} [asset [asset ...]]
values:
badging Print the label and icon for the app declared in APK.
permissions Print the permissions from the APK.
resources Print the resource table from the APK.
configurations Print the configurations in the APK.
xmltree Print the compiled xmls in the given assets.
xmlstrings Print the strings of the given compiled xml assets.
查看基本信息
walfred@ubuntu:~/lab$ aapt d badging yingyonghui.apk
查看应用权限
walfred@ubuntu:~/lab$ aapt d permissions yingyonghui.apk
结语
怎么样,aapt这个小工具本领还真不小吧,当我们在判断一个apk是否有恶意行为时,我们第一步可以考虑使用aapt这个tool哦,
我们可以分析这个apk的权限列表,一旦有部分权限过大,比如发送短信、读取联系人信息等权限时,就可以进一步分析这个apk了。
AAPT
aapt即Android Asset Packaging Tool , 在SDK的platform-tools目录下. 该工具可以查看, 创建, 更新ZIP格式的文档附件(zip, jar, apk).
以上是百度百科中的解释,我们可以通过这个Android已经提供好的工具获取App的相关信息。
注:AAPT是一个绿色软件,无外部依赖。
使用aapt d badging *.apk可以查看apk文件的程序名、包名、所用的sdk,程序版本以及权限信息等等。
如果执行如下命令:则可能有如下结果:
aapt d badging qq.apk
package: name='com.tencent.mobileqq' versionCode='66' versionName='4.2.1'
sdkVersion:'7'
uses-permission:'com.android.launcher.permission.INSTALL_SHORTCUT'
uses-permission:'android.permission.INTERNET'
uses-permission:'android.permission.VIBRATE'
uses-permission:'android.permission.ACCESS_NETWORK_STATE'
uses-permission:'android.permission.CHANGE_CONFIGURATION'
uses-permission:'android.permission.RECEIVE_BOOT_COMPLETED'
uses-permission:'android.permission.WAKE_LOCK'
uses-permission:'android.permission.SYSTEM_ALERT_WINDOW'
uses-permission:'android.permission.RECORD_AUDIO'
uses-permission:'com.tencent.msf.permission.account.sync'
uses-permission:'android.permission.MODIFY_AUDIO_SETTINGS'
uses-permission:'android.permission.CAMERA'
uses-permission:'android.permission.CHANGE_WIFI_STATE'
uses-permission:'android.permission.ACCESS_WIFI_STATE'
uses-permission:'android.permission.READ_PHONE_STATE'
uses-permission:'android.permission.KILL_BACKGROUND_PROCESSES'
uses-permission:'android.permission.CALL_PHONE'
uses-permission:'com.android.launcher.permission.READ_SETTINGS'
uses-permission:'com.android.launcher.permission.UNINSTALL_SHORTCUT'
uses-permission:'android.permission.PERSISTENT_ACTIVITY'
uses-permission:'android.permission.WRITE_SETTINGS'
uses-permission:'android.permission.SEND_SMS'
uses-permission:'android.permission.GET_TASKS'
uses-permission:'com.tencent.permission.VIRUS_SCAN'
uses-permission:'android.permission.READ_LOGS'
uses-permission:'android.permission.READ_CONTACTS'
uses-permission:'android.permission.FLASHLIGHT'
uses-permission:'android.permission.DISABLE_KEYGUARD'
uses-feature-not-required:'android.hardware.camera'
uses-feature-not-required:'android.hardware.camera.autofocus'
application-label:'QQ'
application-label-en:'QQ'
application-icon-120:'res/drawable-ldpi/icon.png'
application-icon-160:'res/drawable-hdpi/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application-icon-320:'res/drawable-hdpi/icon.png'
application-icon-480:'res/drawable-hdpi/icon.png'
application-icon-65535:'res/drawable-hdpi/icon.png'
application: label='QQ' icon='res/drawable-hdpi/icon.png'
launchable-activity: name='com.tencent.mobileqq.activity.SplashActivity' label=
'QQ' icon=''
uses-library-not-required:'com.google.android.maps'
uses-library-not-required:'com.google.android.media.effects'
uses-library-not-required:'com.motorola.hardware.frontcamera'
uses-permission:'com.tencent.photos.permission.DATA'
uses-permission:'com.tencent.msf.permission.account.sync'
uses-permission:'com.tencent.msf.permission.ACCOUNT_NOTICE'
uses-permission:'android.permission.CHANGE_WIFI_STATE'
uses-permission:'android.permission.INTERNET'
uses-permission:'android.permission.ACCESS_WIFI_STATE'
uses-permission:'android.permission.ACCESS_NETWORK_STATE'
uses-permission:'android.permission.ACCESS_FINE_LOCATION'
uses-permission:'android.permission.ACCESS_COARSE_LOCATION'
uses-permission:'android.permission.CAMERA'
uses-permission:'android.permission.READ_PHONE_STATE'
uses-permission:'android.permission.WAKE_LOCK'
uses-permission:'com.android.launcher.permission.INSTALL_SHORTCUT'
uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'
uses-permission:'android.permission.RECEIVE_BOOT_COMPLETED'
uses-permission:'com.tencent.msg.permission.pushnotify'
uses-permission:'com.tencent.msf.permission.account.sync'
uses-permission:'android.permission.READ_EXTERNAL_STORAGE'
uses-implied-permission:'android.permission.READ_EXTERNAL_STORAGE','requested WR
ITE_EXTERNAL_STORAGE'
uses-permission:'android.permission.READ_CALL_LOG'
uses-implied-permission:'android.permission.READ_CALL_LOG','targetSdkVersion < 1
6 and requested READ_CONTACTS'
uses-feature:'android.hardware.location'
uses-implied-feature:'android.hardware.location','requested a location access pe
rmission'
uses-feature:'android.hardware.location.gps'
uses-implied-feature:'android.hardware.location.gps','requested android.permissi
on.ACCESS_FINE_LOCATION permission'
uses-feature:'android.hardware.location.network'
uses-implied-feature:'android.hardware.location.network','requested android.perm
ission.ACCESS_COURSE_LOCATION permission'
uses-feature:'android.hardware.microphone'
uses-implied-feature:'android.hardware.microphone','requested android.permission
.RECORD_AUDIO permission'
uses-feature:'android.hardware.wifi'
uses-implied-feature:'android.hardware.wifi','requested android.permission.ACCES
S_WIFI_STATE, android.permission.CHANGE_WIFI_STATE, or android.permission.CHANGE
_WIFI_MULTICAST_STATE permission'
uses-feature:'android.hardware.telephony'
uses-implied-feature:'android.hardware.telephony','requested a telephony-related
permission or feature'
uses-feature:'android.hardware.touchscreen'
uses-implied-feature:'android.hardware.touchscreen','assumed you require a touch
screen unless explicitly made optional'
uses-feature:'android.hardware.screen.landscape'
uses-implied-feature:'android.hardware.screen.landscape','one or more activities
have specified a landscape orientation'
uses-feature:'android.hardware.screen.portrait'
uses-implied-feature:'android.hardware.screen.portrait','one or more activities
have specified a portrait orientation'
main
app-widget
other-activities
search
other-receivers
other-services
supports-screens: 'small' 'normal' 'large'
supports-any-density: 'true'
locales: '--_--' 'en'
densities: '120' '160' '240' '320' '480' '65535'
native-code: 'armeabi'
这么一大堆信息,其实我们需要的也就只有几个。所以我们只需要将这个操作模拟出来并读取控制台的输出流然后解析字符串即可。
ApkReader
注:本项目参考了https://code.google.com/p/cfuture09-apkutil/
ApkReader解决方案包含两个项目:
ApkReader和ApkUtil。
其中ApkReader是展示界面,主要的功能实现在ApkUtil中,
如果要复用功能,只需引用ApkUtil即可(aapt文件也已经以资源文件的形式附着在ApkUtil项目中,无需格外下载)。
通过ApkInfo类型,我们就可以知道可获取的信息有哪些
public class ApkInfo
{
public ApkInfo()
{
UsesPermissions = new List<string>();
ApplicationIcons = new Dictionary<string, string>();
ImpliedFeatures = new List<ImpliedFeature>();
Features = new List<string>();
} /// <summary>
/// 获取或设置 内部版本号
/// </summary>
public String VersionCode { get; set; } /// <summary>
/// 获取或设置 外部版本号
/// </summary>
public String VersionName { get; set; } /// <summary>
/// 获取或设置 包名
/// </summary>
public String PackageName { get; set; } /// <summary>
/// 获取或设置 所需要的权限
/// </summary>
public List<String> UsesPermissions { get; set; } /// <summary>
/// 获取或设置 支持的SDK版本
/// </summary>
public String SdkVersion { get; set; } /// <summary>
/// 获取或设置 建议的SDK版本
/// </summary>
public String TargetSdkVersion { get; set; } /// <summary>
/// 获取或设置 应用程序名
/// </summary>
public String ApplicationLabel { get; set; } /// <summary>
/// 获取或设置 各个分辨率下的图标路径
/// </summary>
public Dictionary<String, String> ApplicationIcons { get; set; } /// <summary>
/// 获取或设置 程序的图标
/// </summary>
public String ApplicationIcon { get; set; } /// <summary>
/// 获取或设置 暗指的特性
/// </summary>
public List<ImpliedFeature> ImpliedFeatures { get; set; } /// <summary>
/// 获取或设置 所需设备特性
/// </summary>
public List<String> Features { get; set; } /// <summary>
/// 获取或设置 启动界面
/// </summary>
public String LaunchableActivity { get; set; } public override string ToString()
{
return "ApkInfo [VersionCode=" + VersionCode + ",\n VersionName="
+ VersionName + ",\n PackageName=" + PackageName
+ ",\n UsesPermissions="
+ UsesPermissions.Count + ",\n SdkVersion=" + SdkVersion
+ ",\n TargetSdkVersion=" + TargetSdkVersion
+ ",\n ApplicationLabel=" + ApplicationLabel
+ ",\n ApplicationIcons=" + ApplicationIcons.Count
+ ",\n ApplicationIcon=" + ApplicationIcon
+ ",\n ImpliedFeatures=" + ImpliedFeatures.Count + ",\n Features="
+ Features.Count + ",\n LaunchableActivity=" + LaunchableActivity + "\n]";
}
}
开源项目
ApkReader目前为1.0版本,现在在此开源。
开发工具:VS2010
.NET 版本:.NET 2.0
后记
随着开源软件的增多和源码的维护升级,做包上传的方式肯定是不能满足需求的。考虑在GitHub或CodePlex中创建开源项目,这样大家就可以及时跟踪代码的更新了。
android aapt 用法 -- ApkReader的更多相关文章
- Android Meun 用法
Android Meun 用法 点击菜单实体键弹出菜单:如下图 main_activity.xml <?xml version="1.0" encoding="ut ...
- Android ViewPager 用法
Android ViewPager 用法 场景:一般第一次打开应用程序时,程序会有一个提示页来给展现应用程序都有哪些功能:或者程序更新时,又更新哪些新特性,都可以使用ViewPager Demo 描述 ...
- Android Intent 用法全面总结
[代码全屏查看]-Android Intent 用法全面总结 // [1].[代码] 调用拨号程序 跳至 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] / ...
- Android GLSurfaceView用法详解(二)
输入如何处理 若是开发一个交互型的应用(如游戏),通常需要子类化 GLSurfaceView,由此可以获取输入事件.下面有个例子: java代码: package eoe.ClearTes ...
- Android ScrollView用法
Android ScrollView用法 今天试着使用了一下Android的滚轮,以下是一个小小的测试,读取测试文件,主要是使用scrollTo函数和getScrollY(),程序点击BUTTON按钮 ...
- Android Service用法知识点的讲解
Android Service 学习Service相关知识点: android service 的基础知识,生命周期,service分类,运行地点(本地服务,远程服务),运行类型(前台服务,后台服务) ...
- Android Fragment用法知识点的讲解
Android Fragment用法的讲解 碎片,它的出现是为了更好展示UI的设计,让程序更加得到充分的展示.Fragment的出现,如微信的额主界面包含多个Fragment,使得微信功能更加简洁明了 ...
- Android spannableStringBuilder用法整理
Android spannableStringBuilder用法整理 分类: Android开发2013-11-29 10:58 5009人阅读 评论(0) 收藏 举报 Androidspannabl ...
- Android Fragment用法详解(2)--动态添加Fragment
在上一篇文章<Android Fragment用法详解(1)--静态使用Fragment>我们讲解了Fragment的最简单的用法.这次我们来说一说Fragment复杂一丢丢的用法.在代码 ...
随机推荐
- UrlRouteModule
一.请求流程 当一个请求发往ASP.net MVC站点时的情景,IIS收到请求并将请求转到ASP.net,然后根据URL,或者更确切来说:被请求文件的扩展名.在IIS7 integrated模式下(默 ...
- laravel 中provider的理解和使用
https://segmentfault.com/q/1010000004640866
- 【前端vue开发】vue项目使用sass less扩展语言所要安装的依赖
1.创建一个基于 webpack 模板的新项目 $ vue init webpack myvue 2.在当前目录下,安装依赖 $ cd myvue $ npm install 3.安装sass的依赖包 ...
- 数据库-mysql索引
MySQL 索引 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索 ...
- python3 安装
Centos7 安装python3 #安装sqlite-devel yum -y install sqlite-devel #安装依赖 yum -y install make zlib zlib-de ...
- Linux基础 - crontab
列出当前用户设置的定时任务 crontab -l 编辑定时任务 crontab -e 用法 m h dom mon dow * * * * * command 字段详解: *:any m: minut ...
- CF1030A 【In Search of an Easy Problem】
题目巨简单,主要是给大家翻译一下 给n个数,其中存在1就输出HARD,否则输出EASY,不区分大小写 #include<iostream> #include<cstdio> u ...
- (三)使用XML配置SQL映射器
SqlSessionFactoryUtil.java package com.javaxk.util; import java.io.IOException; import java.io.Input ...
- Kubernetes 部署kafka ACL(单机版)
一.概述 在Kafka0.9版本之前,Kafka集群时没有安全机制的.Kafka Client应用可以通过连接Zookeeper地址,例如zk1:2181:zk2:2181,zk3:2181等.来获取 ...
- JavaScript中构造函数
构造函数:函数的另一种执行方法,执行后创建对象,并创建原型对象. 原型链:对象访问构造函数的指针. Function函数:函数对象. Object函数:所有创建对象的祖辈对象,也是由Function对 ...