android aapt 用法 -- ApkReader

aapt 是android assert packaging tool的缩写,具体如下:

android aapt 用法 -- ApkReader

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项目中,无需格外下载)。

android aapt 用法 -- ApkReader

通过ApkInfo类型,我们就可以知道可获取的信息有哪些

    public class ApkInfo
{
public ApkInfo()
{
UsesPermissions = new List&lt;string&gt;();
ApplicationIcons = new Dictionary&lt;string, string&gt;();
ImpliedFeatures = new List&lt;ImpliedFeature&gt;();
Features = new List&lt;string&gt;();
} /// &lt;summary&gt;
/// 获取或设置 内部版本号
/// &lt;/summary&gt;
public String VersionCode { get; set; } /// &lt;summary&gt;
/// 获取或设置 外部版本号
/// &lt;/summary&gt;
public String VersionName { get; set; } /// &lt;summary&gt;
/// 获取或设置 包名
/// &lt;/summary&gt;
public String PackageName { get; set; } /// &lt;summary&gt;
/// 获取或设置 所需要的权限
/// &lt;/summary&gt;
public List&lt;String&gt; UsesPermissions { get; set; } /// &lt;summary&gt;
/// 获取或设置 支持的SDK版本
/// &lt;/summary&gt;
public String SdkVersion { get; set; } /// &lt;summary&gt;
/// 获取或设置 建议的SDK版本
/// &lt;/summary&gt;
public String TargetSdkVersion { get; set; } /// &lt;summary&gt;
/// 获取或设置 应用程序名
/// &lt;/summary&gt;
public String ApplicationLabel { get; set; } /// &lt;summary&gt;
/// 获取或设置 各个分辨率下的图标路径
/// &lt;/summary&gt;
public Dictionary&lt;String, String&gt; ApplicationIcons { get; set; } /// &lt;summary&gt;
/// 获取或设置 程序的图标
/// &lt;/summary&gt;
public String ApplicationIcon { get; set; } /// &lt;summary&gt;
/// 获取或设置 暗指的特性
/// &lt;/summary&gt;
public List&lt;ImpliedFeature&gt; ImpliedFeatures { get; set; } /// &lt;summary&gt;
/// 获取或设置 所需设备特性
/// &lt;/summary&gt;
public List&lt;String&gt; Features { get; set; } /// &lt;summary&gt;
/// 获取或设置 启动界面
/// &lt;/summary&gt;
public String LaunchableActivity { get; set; } public override string ToString()
{
return &quot;ApkInfo [VersionCode=&quot; + VersionCode + &quot;,\n VersionName=&quot;
+ VersionName + &quot;,\n PackageName=&quot; + PackageName
+ &quot;,\n UsesPermissions=&quot;
+ UsesPermissions.Count + &quot;,\n SdkVersion=&quot; + SdkVersion
+ &quot;,\n TargetSdkVersion=&quot; + TargetSdkVersion
+ &quot;,\n ApplicationLabel=&quot; + ApplicationLabel
+ &quot;,\n ApplicationIcons=&quot; + ApplicationIcons.Count
+ &quot;,\n ApplicationIcon=&quot; + ApplicationIcon
+ &quot;,\n ImpliedFeatures=&quot; + ImpliedFeatures.Count + &quot;,\n Features=&quot;
+ Features.Count + &quot;,\n LaunchableActivity=&quot; + LaunchableActivity + &quot;\n]&quot;;
}
}

开源项目

ApkReader目前为1.0版本,现在在此开源。

开发工具:VS2010

.NET 版本:.NET 2.0

源码下载:百度云网盘 | 360云盘

后记

随着开源软件的增多和源码的维护升级,做包上传的方式肯定是不能满足需求的。考虑在GitHub或CodePlex中创建开源项目,这样大家就可以及时跟踪代码的更新了。

  

上一篇:IIS如何设置可以让.aspx后缀的文件直接下载


下一篇:Apache配置完虚拟主机后,使用Chrome访问localhost还是默认目录htdocs