Repository: wulio/Coeus Branch: master Commit: 0a4276ff9143 Files: 91 Total size: 48.4 MB Directory structure: gitextract_wrb45nhy/ ├── .gitattributes ├── LICENSE ├── README.md ├── coeus.py ├── config.py ├── report.xml ├── result/ │ └── 20191224-11-28-55/ │ ├── info.log │ └── report.xml ├── scanner/ │ ├── __init__.py │ ├── base.py │ ├── dynamic.py │ ├── dynamicscanner/ │ │ └── __init__.py │ ├── fuzz/ │ │ └── __init__.py │ ├── static.py │ └── staticscanner/ │ ├── __init__.py │ ├── api.py │ ├── info.py │ └── policy.py ├── script/ │ ├── __init__.py │ ├── exploit_api.json │ ├── hiddenapi-flags.csv │ ├── policy_api.json │ └── policy_permission.json ├── test/ │ ├── bugly_crash_release.jar │ ├── getui_2.13.3.0-gisdk_3.1.9.1-gssdk_2.3.0.0.aar │ ├── gisdk-2.13.3.0.aar │ ├── gisdk-2.9.3.0.aar │ └── glide-4.10.0.aar ├── tools/ │ ├── aapt │ ├── adb/ │ │ ├── linux/ │ │ │ ├── adb │ │ │ ├── api/ │ │ │ │ └── api-versions.xml │ │ │ ├── dmtracedump │ │ │ ├── etc1tool │ │ │ ├── fastboot │ │ │ ├── hprof-conv │ │ │ ├── source.properties │ │ │ ├── sqlite3 │ │ │ └── systrace/ │ │ │ ├── AUTHORS │ │ │ ├── LICENSE │ │ │ ├── NOTICE │ │ │ ├── UPSTREAM_REVISION │ │ │ ├── prefix.html │ │ │ ├── script.js │ │ │ ├── style.css │ │ │ ├── suffix.html │ │ │ ├── systrace-legacy.py │ │ │ └── systrace.py │ │ ├── mac/ │ │ │ ├── adb │ │ │ ├── api/ │ │ │ │ └── api-versions.xml │ │ │ ├── dmtracedump │ │ │ ├── etc1tool │ │ │ ├── fastboot │ │ │ ├── hprof-conv │ │ │ ├── source.properties │ │ │ ├── sqlite3 │ │ │ └── systrace/ │ │ │ ├── AUTHORS │ │ │ ├── LICENSE │ │ │ ├── NOTICE │ │ │ ├── UPSTREAM_REVISION │ │ │ ├── prefix.html │ │ │ ├── script.js │ │ │ ├── style.css │ │ │ ├── suffix.html │ │ │ ├── systrace-legacy.py │ │ │ └── systrace.py │ │ └── windows/ │ │ ├── api/ │ │ │ └── api-versions.xml │ │ ├── source.properties │ │ └── systrace/ │ │ ├── AUTHORS │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── UPSTREAM_REVISION │ │ ├── prefix.html │ │ ├── script.js │ │ ├── style.css │ │ ├── suffix.html │ │ ├── systrace-legacy.py │ │ └── systrace.py │ ├── apktool.jar │ ├── baksmali.jar │ ├── cfr_0_96.jar │ ├── dx.jar │ ├── jad │ └── jad_mac ├── update-info.txt └── utils/ ├── __init__.py ├── fileutils.py ├── manager.py ├── md5.py ├── sdkinfo.py ├── tool.py └── ziputils.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ *.js linguist-language=python *.css linguist-language=python *.html linguist-language=python ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ # Coeus Coeus: Coeus was one of the Titans, son of Uranus and Gaia. His name means questioning. if we need import android sdk,we maybe have some questions about the sdk,like sercurity/permissions/policy/info Coeus project will help you do this . you can see report.xml in report dir. # Try Try your first Coeus scan: python coeus.py xxx.aar # CH ## 0x01 项目地址 项目地址: https://github.com/wulio/Coeus ## 0x02 依赖环境 ​ python 3.x / java ## 0x03 安装使用教程 - 安装 : git clone https://github.com/wulio/Coeus.git - 一键扫描: python coeus.py xxx.aar ## 0x04 相关说明 - 相关政策代码及隐私代码检测策略,均在scrpit文件夹中,json格式便于添加与修改 - 相应的工具也存储在tool文件夹下 - 具体代码逻辑均可在项目组查看。 - 生成的扫描文件,输出在result文件夹下,分别有对应的log文件和输出的report.xml文件。 ## 0x05 使用示例 python ceous.py ./test/getui_2.13.3.0-gisdk_3.1.9.1-gssdk_2.3.0.0.aar # Authors - deff # License Coeus support [Apache License 2.0](https://github.com/baidu/AdvBox/blob/master/LICENSE) # Email deffingh@gmail.com # Issues welcome star or issues! # Plan - [x] - more-sdk-info 2019.12.30 - [ ] - script-update 2019.1.15 - [ ] - apk-support 2019.2.7 - [ ] - dynamicscannner 2019.3 - [ ] - fuzz 2020.4 - [ ] - - [ ] - - [ ] - cause of work-transform pasued plan # Project version : v1.0.1 time :2019-12-30 1. 更新部分script规则 2. 更新支持输入文件为相对路径 3. 更新url展示,过滤其中相同url地址 4. 添加部分工具,如adb/dex2jar等工具 由于工作转化,暂停计划。 ================================================ FILE: coeus.py ================================================ # coding: utf-8 from utils.manager import Manager __author__ = 'deff' import sys import os if len(sys.argv) < 1: print("usage:python coeus.py sdk_path [-d]") print("-d means delete temp file.") print("sdk_path: aar or jar or apk") sys.exit(0) sdk_path = sys.argv[1] if not os.path.exists(sdk_path): sdk_path = os.path.join(os.curdir, sdk_path) if not os.path.exists(sdk_path): print("please input correct sdk_path.") sys.exit(0) m = Manager(sdk_path) m.start() if len(sys.argv) > 2 and sys.argv[2] == "-d": m.delete() ================================================ FILE: config.py ================================================ # coding: utf-8 __author__ = 'deff' import os class Config: RESULT_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "result") TEMP_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "temp") # 工作目录 TOOL_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "tools") SCRIPT_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "script") POLICY_PERMISSION_PATH = os.path.join(SCRIPT_PATH, "policy_permission.json") POLICY_API_PATH = os.path.join(SCRIPT_PATH, "policy_api.json") EXPLOIT_API_PATH = os.path.join(SCRIPT_PATH, "exploit_api.json") def __init__(self): self.sdk_path = "" self.result_path = "" self.temp_path = "" self.unzip_path = "" self.decompile_path = "" self.java_path = "" self.smali_path = "" self.jar_path = "" self.so_path = "" self.xml_path = "" self.res_path = "" self.assets_path = "" self.libs_path = "" self.jni_path = "" config = Config() ================================================ FILE: report.xml ================================================ getui_2.13.3.0-gisdk_3.1.9.1-gssdk_2.3.0.0 com.getui.onesdk onesdk-1.0.0 798KB e98e661ec3804cf3c9ed21a17fa9584b targetSdkVersion 22 minSdkVersion 14 android.permission.INTERNET android.permission.READ_PHONE_STATE android.permission.ACCESS_NETWORK_STATE android.permission.CHANGE_WIFI_STATE android.permission.ACCESS_WIFI_STATE android.permission.RECEIVE_BOOT_COMPLETED android.permission.WRITE_EXTERNAL_STORAGE android.permission.VIBRATE android.permission.GET_TASKS getui.permission.GetuiService.${applicationId} android.permission.WRITE_EXTERNAL_STORAGE android.permission.READ_PHONE_STATE android.permission.READ_EXTERNAL_STORAGE android.permission.SYSTEM_ALERT_WINDOW 22 当前sdkversoin为22 电信终端产业协会(TAF)发布的《移动应用软件高 API 等级预置与分发自律公约》要求,截止到2019年5月1日所有新发布的应用 API 必须为26或更高,2019年8月1日现有应用 API 必须升级为26或更高。2019-11-1之后,上架谷歌Play商店要求应用的TargetSdkVersion>=28 2 联系sdk开发者,修改sdk版本号 android.permission.READ_PHONE_STATE 读取手机状态和身份 工信部要求不可获取,其次是andoridQ版本将限制应用访问不可重设的设备识别码,如 IMEI、序列号等,所有获取设备识别码的接口都增加了新的权限:READ_PRIVILEGED_PHONE_STATE,该权限需要系统签名的应用才能申请,意味着三方应用无法获取设备识别码。 2 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.RECEIVE_BOOT_COMPLETED 开机时自动启动 允许应用程序在系统完成启动后即自行启动。这样会延长手机的启动时间,而且如果应用程序一直运行,会降低手机的整体速度。 1 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.WRITE_EXTERNAL_STORAGE 修改/删除SD卡中的内容 允许应用程序写入SD卡。需用户授权,且不授权不能导致app失败,注意是否做好缺省。 2 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.GET_TASKS 检索当前运行的应用程序 允许应用程序检索有关当前和最近运行的任务的信息。注意该项可能违反工信部要求,个人隐私部分,且不授权不能影响用户使用。 1 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.WRITE_EXTERNAL_STORAGE 修改/删除SD卡中的内容 允许应用程序写入SD卡。需用户授权,且不授权不能导致app失败,注意是否做好缺省。 2 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.READ_PHONE_STATE 读取手机状态和身份 工信部要求不可获取,其次是andoridQ版本将限制应用访问不可重设的设备识别码,如 IMEI、序列号等,所有获取设备识别码的接口都增加了新的权限:READ_PRIVILEGED_PHONE_STATE,该权限需要系统签名的应用才能申请,意味着三方应用无法获取设备识别码。 2 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.READ_EXTERNAL_STORAGE 读取外存 允许应用程序读SD卡,目前应工信部要求,需用户授权,且不授权不能导致app失败,注意是否做好缺省。 2 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.SYSTEM_ALERT_WINDOW 显示系统级警报 允许应用程序显示系统警报窗口。恶意应用程序可借此掌控整个手机屏幕。 1 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 获取imei sdk获取imei信息,需谨慎处理,否则APP可能被要求整改 1.工信部要求2.android10及以上获取不到了3.imei权限部分需要注意兼容 invoke-virtual {v0}, Landroid/telephony/TelephonyManager;-&lt;getDeviceId()Ljava/lang/String; invoke-virtual {v0}, Landroid/telephony/TelephonyManager;-&lt;getDeviceId()Ljava/lang/String; invoke-virtual {v1}, Landroid/telephony/TelephonyManager;-&lt;getDeviceId()Ljava/lang/String; \com\getui\gis\sdk\e\m.smali \com\getui\gs\ias\e\x.smali \com\getui\gtc\d\a\d.smali 2 联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。 获取imsi sdk获取imsi信息,需谨慎处理,否则APP可能被要求整改 工信部要求,不得向第三方提供用户设备IMEI号、地理位置、imsi等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。 invoke-virtual {v0}, Landroid/telephony/TelephonyManager;-&lt;getSubscriberId()Ljava/lang/String; invoke-virtual {v0}, Landroid/telephony/TelephonyManager;-&lt;getSubscriberId()Ljava/lang/String; invoke-virtual {v0}, Landroid/telephony/TelephonyManager;-&lt;getSubscriberId()Ljava/lang/String; invoke-virtual {v1}, Landroid/telephony/TelephonyManager;-&lt;getSubscriberId()Ljava/lang/String; \com\getui\gis\sdk\e\m.smali \com\getui\gs\ias\e\ac.smali \com\getui\gs\ias\e\x.smali \com\getui\gtc\d\a\d.smali 1 联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。 获取mac sdk获取mac信息,需谨慎处理,否则APP可能被要求整改 1.工信部要求,mac也属于个人信息,2.android9及以上系统会随机生成不同的 MAC invoke-virtual {v0}, Landroid/net/wifi/WifiInfo;-&lt;getMacAddress()Ljava/lang/String; invoke-virtual {v0}, Landroid/net/wifi/WifiInfo;-&lt;getMacAddress()Ljava/lang/String; invoke-virtual {v0}, Landroid/net/wifi/WifiInfo;-&lt;getMacAddress()Ljava/lang/String; \com\getui\gis\sdk\e\m.smali \com\getui\gs\ias\e\x.smali \com\getui\gtc\e\l.smali 1 联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。 获取已安装程序列表 sdk尝试获取已安装程序列表 1.该信息属于个人隐私信息 2.工信部要求 sdk获取app列表,极有可能导致被整改 invoke-virtual {v0, p0, v1}, Landroid/content/pm/PackageManager;-&lt;queryIntentActivities(Landroid/content/Intent;I)Ljava/util/List; invoke-virtual {v4, v0}, Landroid/content/pm/PackageManager;-&lt;getInstalledPackages(I)Ljava/util/List; invoke-virtual {v4, v0}, Landroid/content/pm/PackageManager;-&lt;getInstalledPackages(I)Ljava/util/List; \com\getui\gs\ias\e\u.smali \com\getui\gs\ias\e\x.smali \com\getui\gs\ias\e\x.smali 2 联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。 动态注册Receiver权限设置漏洞风险 动态注册Receiver权限设置漏洞风险 Receiver权限未设置,恶意程序可以发送相应的action广播危害应用安全 invoke-virtual {v0, v1, v2}, Landroid/content/Context;-&lt;registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent; invoke-virtual {p0, v1, v0}, Landroid/content/Context;-&lt;registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent; \com\getui\gis\sdk\c.smali \com\getui\gs\sdk\b.smali 2 使用registerReceiver(BroadcastReceiver, IntentFilter, broadcastPermission, Handler)替代 广播信息泄露风险 广播信息泄露风险 广播信息泄露风险 invoke-virtual {p1, v0}, Landroid/content/Context;-&lt;sendBroadcast(Landroid/content/Intent;)V invoke-virtual {v1, v6}, Landroid/content/Context;-&lt;sendBroadcast(Landroid/content/Intent;)V invoke-virtual {v0, v2}, Landroid/content/Context;-&lt;sendBroadcast(Landroid/content/Intent;)V \com\getui\gis\sdk\a\a.smali \com\getui\gtc\a\e$a.smali \com\getui\gtc\d\a\d.smali 2 建议使用显式调用方式发送Intent;进程内发送消息建议使用LocalBroadcastManager; 弱随机数密钥 sdk弱随机数密钥 4.4以下存在随机数破解漏洞风险 invoke-direct {v3}, Ljava/security/SecureRandom;-&lt;&gt;init&lt;()V invoke-direct {v3}, Ljava/security/SecureRandom;-&lt;&gt;init&lt;()V \com\getui\gis\sdk\e\f.smali \com\getui\gs\ias\b\a.smali 1 建议复查下调用,避免使用弱随机数密钥 日志信息泄露风险 日志信息泄露风险 日志信息泄露风险,建议去除日志信息 invoke-static {v0, v1}, Landroid/util/Log;-&lt;d(Ljava/lang/String;Ljava/lang/String;)I invoke-static {v0, v1}, Landroid/util/Log;-&lt;d(Ljava/lang/String;Ljava/lang/String;)I invoke-static {v0, v1}, Landroid/util/Log;-&lt;d(Ljava/lang/String;Ljava/lang/String;)I invoke-static {v0, v1}, Landroid/util/Log;-&lt;d(Ljava/lang/String;Ljava/lang/String;)I invoke-static {v0, v1}, Landroid/util/Log;-&lt;d(Ljava/lang/String;Ljava/lang/String;)I invoke-static {v0, v1}, Landroid/util/Log;-&lt;d(Ljava/lang/String;Ljava/lang/String;)I \com\getui\gs\ias\e\m.smali \com\getui\gs\ias\e\m.smali \com\getui\gs\ias\floatwindow\k.smali \com\getui\gs\ias\floatwindow\k.smali \com\getui\gs\ias\floatwindow\k.smali \com\getui\gs\ias\floatwindow\k.smali 1 日志信息泄露,可能威胁用户敏感隐私数据安全。 动态加载其他程序 sdk动态加载其他程序 sdk尝试进行动态加载其他程序 invoke-direct {v2, v1, v4, v5, v6}, Ldalvik/system/DexClassLoader;-&lt;&gt;init&lt;(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V \com\getui\gtc\b\c.smali 2 加载的APK、DEX文件时要进行合理的校验;动态加载的文件应该了解其加载的内容 http://%s/bd http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://c-gtc.getui.com/api.php?format=json&t=1 http://b-gtc.getui.com/api.php?format=json&t=1 http://sdk.open.phone.igexin.com/api/addr.htm ================================================ FILE: result/20191224-11-28-55/info.log ================================================ 2019-12-24 11:28:55 manager.py[line:32] INFO start sdk scan.. 2019-12-24 11:28:55 manager.py[line:46] INFO start unzip.. 2019-12-24 11:28:55 manager.py[line:61] INFO unzip success. 2019-12-24 11:28:55 manager.py[line:66] INFO start decompile java. 2019-12-24 11:28:55 manager.py[line:101] INFO totalfiles:310 2019-12-24 11:29:00 manager.py[line:69] INFO decompile java success. 2019-12-24 11:29:00 manager.py[line:73] INFO start decompile smali. 2019-12-24 11:29:03 manager.py[line:75] INFO decompile smali success. 2019-12-24 11:29:03 manager.py[line:84] INFO start scan.. 2019-12-24 11:29:03 base.py[line:14] INFO InfoScanner start. 2019-12-24 11:29:03 base.py[line:29] INFO InfoScanner end. 2019-12-24 11:29:03 base.py[line:14] INFO PolicyScanner start. 2019-12-24 11:29:03 policy.py[line:81] INFO permission in policy_permission_json not find:getui.permission.GetuiService.${applicationId} 2019-12-24 11:29:03 base.py[line:29] INFO PolicyScanner end. 2019-12-24 11:29:03 base.py[line:14] INFO ApiScanner start. 2019-12-24 11:29:04 base.py[line:29] INFO ApiScanner end. 2019-12-24 11:29:04 manager.py[line:96] INFO scan success. ================================================ FILE: result/20191224-11-28-55/report.xml ================================================ getui_2.13.3.0-gisdk_3.1.9.1-gssdk_2.3.0.0 com.getui.onesdk onesdk-1.0.0 798KB e98e661ec3804cf3c9ed21a17fa9584b targetSdkVersion 22 minSdkVersion 14 android.permission.INTERNET android.permission.READ_PHONE_STATE android.permission.ACCESS_NETWORK_STATE android.permission.CHANGE_WIFI_STATE android.permission.ACCESS_WIFI_STATE android.permission.RECEIVE_BOOT_COMPLETED android.permission.WRITE_EXTERNAL_STORAGE android.permission.VIBRATE android.permission.GET_TASKS getui.permission.GetuiService.${applicationId} android.permission.WRITE_EXTERNAL_STORAGE android.permission.READ_PHONE_STATE android.permission.READ_EXTERNAL_STORAGE android.permission.SYSTEM_ALERT_WINDOW 22 当前sdkversoin为22 电信终端产业协会(TAF)发布的《移动应用软件高 API 等级预置与分发自律公约》要求,截止到2019年5月1日所有新发布的应用 API 必须为26或更高,2019年8月1日现有应用 API 必须升级为26或更高。2019-11-1之后,上架谷歌Play商店要求应用的TargetSdkVersion>=28 2 联系sdk开发者,修改sdk版本号 android.permission.READ_PHONE_STATE 读取手机状态和身份 工信部要求不可获取,其次是andoridQ版本将限制应用访问不可重设的设备识别码,如 IMEI、序列号等,所有获取设备识别码的接口都增加了新的权限:READ_PRIVILEGED_PHONE_STATE,该权限需要系统签名的应用才能申请,意味着三方应用无法获取设备识别码。 2 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.RECEIVE_BOOT_COMPLETED 开机时自动启动 允许应用程序在系统完成启动后即自行启动。这样会延长手机的启动时间,而且如果应用程序一直运行,会降低手机的整体速度。 1 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.WRITE_EXTERNAL_STORAGE 修改/删除SD卡中的内容 允许应用程序写入SD卡。需用户授权,且不授权不能导致app失败,注意是否做好缺省。 2 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.GET_TASKS 检索当前运行的应用程序 允许应用程序检索有关当前和最近运行的任务的信息。注意该项可能违反工信部要求,个人隐私部分,且不授权不能影响用户使用。 1 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.WRITE_EXTERNAL_STORAGE 修改/删除SD卡中的内容 允许应用程序写入SD卡。需用户授权,且不授权不能导致app失败,注意是否做好缺省。 2 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.READ_PHONE_STATE 读取手机状态和身份 工信部要求不可获取,其次是andoridQ版本将限制应用访问不可重设的设备识别码,如 IMEI、序列号等,所有获取设备识别码的接口都增加了新的权限:READ_PRIVILEGED_PHONE_STATE,该权限需要系统签名的应用才能申请,意味着三方应用无法获取设备识别码。 2 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.READ_EXTERNAL_STORAGE 读取外存 允许应用程序读SD卡,目前应工信部要求,需用户授权,且不授权不能导致app失败,注意是否做好缺省。 2 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 android.permission.SYSTEM_ALERT_WINDOW 显示系统级警报 允许应用程序显示系统警报窗口。恶意应用程序可借此掌控整个手机屏幕。 1 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。 获取imei sdk获取imei信息,需谨慎处理,否则APP可能被要求整改 1.工信部要求2.android10及以上获取不到了3.imei权限部分需要注意兼容 invoke-virtual {v0}, Landroid/telephony/TelephonyManager;-&lt;getDeviceId()Ljava/lang/String; invoke-virtual {v0}, Landroid/telephony/TelephonyManager;-&lt;getDeviceId()Ljava/lang/String; invoke-virtual {v1}, Landroid/telephony/TelephonyManager;-&lt;getDeviceId()Ljava/lang/String; \com\getui\gis\sdk\e\m.smali \com\getui\gs\ias\e\x.smali \com\getui\gtc\d\a\d.smali 2 联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。 获取imsi sdk获取imsi信息,需谨慎处理,否则APP可能被要求整改 工信部要求,不得向第三方提供用户设备IMEI号、地理位置、imsi等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。 invoke-virtual {v0}, Landroid/telephony/TelephonyManager;-&lt;getSubscriberId()Ljava/lang/String; invoke-virtual {v0}, Landroid/telephony/TelephonyManager;-&lt;getSubscriberId()Ljava/lang/String; invoke-virtual {v0}, Landroid/telephony/TelephonyManager;-&lt;getSubscriberId()Ljava/lang/String; invoke-virtual {v1}, Landroid/telephony/TelephonyManager;-&lt;getSubscriberId()Ljava/lang/String; \com\getui\gis\sdk\e\m.smali \com\getui\gs\ias\e\ac.smali \com\getui\gs\ias\e\x.smali \com\getui\gtc\d\a\d.smali 1 联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。 获取mac sdk获取mac信息,需谨慎处理,否则APP可能被要求整改 1.工信部要求,mac也属于个人信息,2.android9及以上系统会随机生成不同的 MAC invoke-virtual {v0}, Landroid/net/wifi/WifiInfo;-&lt;getMacAddress()Ljava/lang/String; invoke-virtual {v0}, Landroid/net/wifi/WifiInfo;-&lt;getMacAddress()Ljava/lang/String; invoke-virtual {v0}, Landroid/net/wifi/WifiInfo;-&lt;getMacAddress()Ljava/lang/String; \com\getui\gis\sdk\e\m.smali \com\getui\gs\ias\e\x.smali \com\getui\gtc\e\l.smali 1 联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。 获取已安装程序列表 sdk尝试获取已安装程序列表 1.该信息属于个人隐私信息 2.工信部要求 sdk获取app列表,极有可能导致被整改 invoke-virtual {v4, v0}, Landroid/content/pm/PackageManager;-&lt;getInstalledPackages(I)Ljava/util/List; \com\getui\gs\ias\e\x.smali 2 联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。 动态注册Receiver权限设置漏洞风险 动态注册Receiver权限设置漏洞风险 Receiver权限未设置,恶意程序可以发送相应的action广播危害应用安全 invoke-virtual {v0, v1, v2}, Landroid/content/Context;-&lt;registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent; invoke-virtual {p0, v1, v0}, Landroid/content/Context;-&lt;registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent; \com\getui\gis\sdk\c.smali \com\getui\gs\sdk\b.smali 2 使用registerReceiver(BroadcastReceiver, IntentFilter, broadcastPermission, Handler)替代 广播信息泄露风险 广播信息泄露风险 广播信息泄露风险 invoke-virtual {p1, v0}, Landroid/content/Context;-&lt;sendBroadcast(Landroid/content/Intent;)V invoke-virtual {v1, v6}, Landroid/content/Context;-&lt;sendBroadcast(Landroid/content/Intent;)V invoke-virtual {v0, v2}, Landroid/content/Context;-&lt;sendBroadcast(Landroid/content/Intent;)V \com\getui\gis\sdk\a\a.smali \com\getui\gtc\a\e$a.smali \com\getui\gtc\d\a\d.smali 2 建议使用显式调用方式发送Intent;进程内发送消息建议使用LocalBroadcastManager; 弱随机数密钥 sdk弱随机数密钥 4.4以下存在随机数破解漏洞风险 invoke-direct {v3}, Ljava/security/SecureRandom;-&lt;&gt;init&lt;()V invoke-direct {v3}, Ljava/security/SecureRandom;-&lt;&gt;init&lt;()V \com\getui\gis\sdk\e\f.smali \com\getui\gs\ias\b\a.smali 1 建议复查下调用,避免使用弱随机数密钥 动态加载其他程序 sdk动态加载其他程序 sdk尝试进行动态加载其他程序 invoke-direct {v2, v1, v4, v5, v6}, Ldalvik/system/DexClassLoader;-&lt;&gt;init&lt;(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V \com\getui\gtc\b\c.smali 2 加载的APK、DEX文件时要进行合理的校验;动态加载的文件应该了解其加载的内容 http://%s/bd http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://%s/api.php?format=json&t=1 https://%s/encryption/key/fetch http://%s/geshu/smartStatistics/upe http://%s/geshu/sdkStatistics/ubi http://%s/geshu/sdkStatistics/bd http://%s/geshu/sdk/getBaseConfs http://%s/geshu/sdk/getCompleteConfs http://%s/geshu/sdk/getAccessToken http://%s/geshu/sdk/uConfs http://%s/geshu/sdkStatistics/ued http://%s/geshu/sdkStatistics/uud http://c-gtc.getui.com/api.php?format=json&t=1 http://b-gtc.getui.com/api.php?format=json&t=1 http://c-gtc.getui.com/api.php?format=json&t=1 http://b-gtc.getui.com/api.php?format=json&t=1 http://%s/api.php?format=json&t=1 http://%s/api.php?format=json&t=1 http://%s/api.php?format=json&t=1 http://%s/api.php?format=json&t=1 http://sdk.open.phone.igexin.com/api/addr.htm ================================================ FILE: scanner/__init__.py ================================================ # coding: utf-8 __author__ = 'deff' ================================================ FILE: scanner/base.py ================================================ # coding: utf-8 import logging __author__ = 'deff' class BaseScanner: def __init__(self): pass # 做初始化操作 def init_tag(self): logging.info(self.__class__.__name__ + " start.") # 静态扫描 def scan(self): pass # 输出报告 def report(self): pass # 结束操作 def delete(self): pass def end_tag(self): logging.info(self.__class__.__name__ + " end.") # 可单独直接开始 def start(self): pass ================================================ FILE: scanner/dynamic.py ================================================ # coding: utf-8 __author__ = 'deff' from scanner.base import BaseScanner ##动态信息 class DynamicScanner(BaseScanner): def __init__(self): super().__init__() ##可单独直接开始 def start(self): return "" # 做初始化操作 def init(self): pass # 扫描 def scan(self): pass # 输出报告 def report(self): pass # 结束操作 def delete(self): pass def __del__(self): pass ================================================ FILE: scanner/dynamicscanner/__init__.py ================================================ # coding: utf-8 __author__ = 'deff' ================================================ FILE: scanner/fuzz/__init__.py ================================================ # coding: utf-8 __author__ = 'deff' # Andoid-afl.https://github.com/ele7enxxh/android-afl # Fuzzing with libFuzzer. # Droid: Android application fuzzing framework.https://github.com/ajinabraham/Droid-Application-Fuzz-Framework # Writing the worlds worst Android fuzzer, and then improving it, by Gamozo 2018. # Fuzzing Android: a recipe for uncovering vulnerabilities inside system components in Android, by Alexandru Blanda (BlackHat'15). # DoApp (Denial of App): A smart Android Fuzzer for the future.http://www.iswatlab.eu/security-projects/doapp-denial-of-app-a-smart-android-fuzzer-for-the-future/ # Droid-FF.https://github.com/antojoseph/droid-ff ================================================ FILE: scanner/static.py ================================================ # coding: utf-8 from scanner.staticscanner.policy import PolicyScanner from scanner.base import BaseScanner from scanner.staticscanner.api import ApiScanner from scanner.staticscanner.info import InfoScanner __author__ = 'deff' # 静态 class StaticScanner(BaseScanner): def __init__(self, is_aar): super().__init__() # 此处可以添加不同的规则扫描器 self.static_scanners = [] self.is_aar = is_aar self.init() # 做初始化操作 def init(self): pass # 扫描 def scan(self): pass # 输出报告 def report(self): pass # 结束操作 def delete(self): pass def __del__(self): pass # 可单独直接开始 def start(self): if self.is_aar: self.static_scanners = [InfoScanner(), PolicyScanner(), ApiScanner()] else: self.static_scanners = [InfoScanner(), ApiScanner()] report = "" for scanner in self.static_scanners: scanner.init_tag() scanner.init() scanner.scan() report += scanner.report() scanner.delete() scanner.end_tag() return report ================================================ FILE: scanner/staticscanner/__init__.py ================================================ # coding: utf-8 __author__ = 'deff' ================================================ FILE: scanner/staticscanner/api.py ================================================ # coding: utf-8 import os import re from utils.tool import Tools __author__ = 'deff' from scanner.base import BaseScanner import json from utils.sdkinfo import sdkinfo from config import config # api审计 # 0. 隐私信息api :手机号/imei/imsi/mac/android id/gps/通讯录/应用程序列表/网页浏览记录(静态检测,后续动态可以进行hook对应函数检测) # 0.1 http url链接检测 # 1. 调用非SDK接口,带来兼容性问题。(原理一致)https://developer.android.google.cn/distribute/best-practices/develop/restrictions-non-sdk-interfaces # 2. 存在安全漏洞 # jar -> dex -> smali # jar -> java (java备份,后续做函数逻辑处理) # 本打算用jieba或用gensim来匹配,目前简单粗暴正则即可 # 缓存-一个文件一个文件扫-添加-输出报告 class ApiScanner(BaseScanner): def __init__(self): super().__init__() self.policy_api = {} self.exploit_api = {} self.report_policy_list = [] self.report_exploit_list = [] self.report_url_http = [] # 做初始化操作 def init(self): with open(config.POLICY_API_PATH, 'r', encoding="utf-8") as f: self.policy_api = json.load(f) with open(config.EXPLOIT_API_PATH, 'r', encoding="utf-8") as f2: self.exploit_api = json.load(f2) # 静态扫描 def scan(self): for root, dirs, files in os.walk(config.smali_path): for file_name in files: if str(file_name).endswith(".smali"): file_path = os.path.join(root, file_name) class_name = file_path.split(config.smali_path)[1] with open(file_path, 'r', encoding="utf-8") as smali_f: lines = smali_f.readlines() for line in lines: line = line.strip() if line.find('http:') > -1 or line.find('https:') > -1: self.gethttp(file_path) self._in_file_(line, class_name) def gethttp(self, file_path): java_path = file_path.replace("smali", "java") if os.path.exists(java_path): with open(java_path, 'r', encoding="utf-8") as java_f: lines = java_f.readlines() for line in lines: line = line.strip() if line.find("http:") < 0 and line.find("https:") < 0: continue urls = self.getmsg(line) for url in urls: if url not in self.report_url_http: self.report_url_http.append(url) # 正则搞定 def getmsg(self, line): pattern = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+') # 匹配模式 url = re.findall(pattern, line) return url def _in_file_(self, line, class_name): for p_a in self.policy_api: for smalicode in p_a["smalicode"].values(): if line.find(smalicode) > -1: flag = False for r in self.report_policy_list: if r["name"] == p_a["name"]: flag = True r["classname"].append(class_name) r["smalicode"].append(line) if not flag: classn = [class_name] sn = [line] pa_report = { "name": p_a["name"], "summary": p_a["summary"], "desc": p_a["desc"], "smalicode": sn, "classname": classn, "level": p_a["level"], "sol": p_a["sol"], } self.report_policy_list.append(pa_report) for e_a in self.exploit_api: if line.find(e_a["smalicode"]) > -1: flag = False for r in self.report_exploit_list: if r["name"] == e_a["name"]: flag = True r["classname"].append(class_name) r["smalicode"].append(line) if not flag: classn = [class_name] sn = [line] ea_report = { "name": e_a["name"], "summary": e_a["summary"], "desc": e_a["desc"], "smalicode": sn, "classname": classn, "level": e_a["level"], "slu": e_a["sol"], } self.report_exploit_list.append(ea_report) # 输出报告 def report(self): report = "" for report_policy in self.report_policy_list: report += "" + "" + report_policy["name"] + "" + \ "" + report_policy["summary"] + "" + \ "" + report_policy["desc"] + "" for sm in report_policy["smalicode"]: report += "" + Tools.xml_assent(sm) + "" for cm in report_policy["classname"]: report += "" + cm + "" report += "" + report_policy["level"] + "" + \ "" + report_policy["sol"] + "" + \ "" report += "" report += "" if sdkinfo.allow_back_up: report += "" + \ "" + "allowBackup标志为true" + "" + \ "" + "请将allowBackup设定为false,存在非法备份泄露等安全风险。" + "" + \ "" if sdkinfo.debuggable: report += "" + \ "" + "debuggable标志为true" + "" + \ "" + "请将debuggable设定为false,存在非法调试等安全风险。" + "" + \ "" for report_exploit in self.report_exploit_list: report += "" + "" + report_exploit["name"] + "" + \ "" + report_exploit["summary"] + "" + \ "" + report_exploit["desc"] + "" for sm in report_exploit["smalicode"]: report += "" + Tools.xml_assent(sm) + "" for cm in report_exploit["classname"]: report += "" + cm + "" report += "" + report_exploit["level"] + "" + \ "" + report_exploit["slu"] + "" + \ "" report += "" report += "" for url in self.report_url_http: report += "" + Tools.xml_assent(url) + "" report += "" return report # 结束操作 def delete(self): del self.report_policy_list del self.report_exploit_list del self.policy_api del self.exploit_api def __del__(self): pass if __name__ == '__main__': sdkinfo.sdk_path = r"E:\work\workPython\sdkscan\test\getui_2.13.3.0-gisdk_3.1.9.1-gssdk_2.3.0.0.aar" config.smali_path = r"E:\work\workPython\sdkscan\temp\20191223-21-14-19\decompile\smali" info = ApiScanner() info.init() info.scan() info.report() ================================================ FILE: scanner/staticscanner/info.py ================================================ # coding: utf-8 import re import os from utils.fileutils import FileUtils from utils.md5 import Md5 from scanner.base import BaseScanner from utils.sdkinfo import sdkinfo from config import config __author__ = 'deff' ##基础信息,权限,包名 class InfoScanner(BaseScanner): def __init__(self): super().__init__() # 做初始化操作 def init(self): pass # 静态扫描 def scan(self): sdkinfo.sdk_md5 = Md5.md5_file(sdkinfo.sdk_path) self.get_info() self.get_soname() self.get_other_libs() def get_info(self): sdkinfo.sdk_name = os.path.splitext(os.path.basename(sdkinfo.sdk_path))[0] sdkinfo.sdk_size = str(int(os.path.getsize(sdkinfo.sdk_path) / 1024)) if not FileUtils.is_file_exit(config.xml_path): return with open(config.xml_path, 'r', encoding='utf-8') as file: lines = file.readlines() for line in lines: if line.find('package=') > -1: re_name = re.compile(r"package=\"(.*?)\"\s") sdkinfo.package_name = re_name.findall(line)[0] if line.find('versionName') > -1: re_version = re.compile(r"versionName=\"(.*?)\"\s") sdkinfo.version_name = re_version.findall(line)[0] if line.find('uses-permission') > -1: re_per = re.compile(r"android:name=\"(.*?)\"\s") permission = re_per.findall(line)[0] sdkinfo.permissions.append(permission) if line.find('minSdkVersion') > -1: re_min = re.compile(r"android:minSdkVersion=\"(.*?)\"\s") sdkinfo.min_sdk_version = re_min.findall(line)[0] if line.find('targetSdkVersion') > -1: re_target = re.compile(r"android:targetSdkVersion=\"(.*?)\"\s") sdkinfo.target_sdk_version = re_target.findall(line)[0] if line.find("android:allowBackup") > -1: re_allow = re.compile(r"android:allowBackup=\"(.*?)\"\s") sdkinfo.allow_back_up = re_allow.findall(line)[0].lower() == "true" if line.find("android:debuggable") > -1: re_debug = re.compile(r"android:debuggable=\"(.*?)\"\s") sdkinfo.debuggable = re_debug.findall(line)[0].lower() == "true" # /jni/abi_name/name.so(其中“abi_name”是 Android 支持的 ABI 之一) def get_soname(self): if FileUtils.is_file_exit(config.jni_path): for dirpath, dirnames, filenames in os.walk(config.unzip_path): for filename in filenames: if filename.endswith(".so"): sdkinfo.sdk_soname = filename # libs def get_other_libs(self): if FileUtils.is_file_exit(config.libs_path): for home, dir, filenames in os.walk(config.libs_path): for filename in filenames: sdkinfo.other_libs.append(filename) # /assets/ def get_assets(self): if FileUtils.is_file_exit(config.assets_path): for home, dir, filenames in os.walk(config.libs_path): for filename in filenames: sdkinfo.assets_files.append(filename) # 输出报告,xml格式(方便单独展示),json格式 def report(self): report = "" + \ "" + sdkinfo.sdk_name + "" + \ "" + sdkinfo.package_name + "" + \ "" + sdkinfo.version_name + "" + \ "" + sdkinfo.sdk_size + "KB" + "" + \ "" + sdkinfo.sdk_md5 + "" + \ "" + "targetSdkVersion " + sdkinfo.target_sdk_version + "" + \ "" + "minSdkVersion " + sdkinfo.min_sdk_version + "" for permisson in sdkinfo.permissions: report += "" + permisson + "" report += "" return report # 结束操作 def delete(self): pass def __del__(self): pass if __name__ == '__main__': sdkinfo.sdk_path = r"E:\work\workPython\sdkscan\test\spartasdk-2.0.0.aar" config.xml_path = r"E:\work\workPython\sdkscan\temp\20191223-10-41-40\unzip\AndroidManifest.xml" info = InfoScanner() info.init() info.scan() info.report() ================================================ FILE: scanner/staticscanner/policy.py ================================================ # coding: utf-8 import linecache import logging import os import json from scanner.staticscanner.info import InfoScanner from utils.fileutils import FileUtils from scanner.base import BaseScanner from utils.sdkinfo import sdkinfo from config import config __author__ = 'deff' ## 政策信息,权限,target api class PolicyScanner(BaseScanner): def __init__(self): super().__init__() self.target_sdk = False self.so_64 = False self.policy = [] self.permissions_policy = {} # 做初始化操作 def init(self): with open(config.POLICY_PERMISSION_PATH, "r", encoding="utf-8") as f: self.permissions_policy = json.load(f) # 静态扫描 def scan(self): if not FileUtils.is_file_exit(config.POLICY_PERMISSION_PATH): logging.error("POLICY_TXT not in.") return if FileUtils.is_file_exit(config.xml_path): self.find_permission_policy() if int(sdkinfo.target_sdk_version) < 28: self.target_sdk = True else: logging.info("no xml") self.so_policy() self.find_api_policy() def so_policy(self): if FileUtils.is_dir_exit(config.jni_path): arm_64 = os.path.join(config.jni_path, "arm64-v8a") x86_64 = os.path.join(config.jni_path, "x86_64") if not FileUtils.is_dir_exit(arm_64) and not FileUtils.is_dir_exit(x86_64): self.so_64 = True else: if FileUtils.is_dir_exit(config.unzip_path): arm_64_2 = os.path.join(config.unzip_path, "arm64-v8a") x86_64_2 = os.path.join(config.unzip_path, "x86_64") self.so_64 = FileUtils.is_dir_empty(arm_64_2) and FileUtils.is_dir_empty(x86_64_2) def find_permission_policy(self): for permission in sdkinfo.permissions: find_flag = False for pe_policy in self.permissions_policy.values(): if pe_policy["name"] == permission: find_flag = True summary = pe_policy["summary"] desc = pe_policy["desc"] level = pe_policy["level"] if int(level) > 0: p = { "name": permission, "summary": summary, "desc": desc, "level": level } self.policy.append(p) break if not find_flag: logging.info("permission in policy_permission_json not find:" + permission) # print("permission in policy_permission_json not find:" + permission) # 检测特殊api # 放置apiscanner中处理 def find_api_policy(self): pass def get_msg(self, line): message = linecache.getline(config.POLICY_PERMISSION_PATH, line) return message[(message.find('\"') + 1):message.rfind('\"')] # 输出报告 def report(self): report = "" if self.target_sdk: report += "" + \ "" + sdkinfo.target_sdk_version + "" + \ "" + "当前sdkversoin为" + sdkinfo.target_sdk_version + "" + \ "" + "电信终端产业协会(TAF)发布的《移动应用软件高 API 等级预置与分发自律公约》要求,截止到2019年5月1日所有新发布的应用 API 必须为26或更高,2019年8月1日现有应用 API 必须升级为26或更高。2019-11-1之后,上架谷歌Play商店要求应用的TargetSdkVersion>=28 " + "" + \ "" + " 2 " + "" + \ "" + "联系sdk开发者,修改sdk版本号" + "" + \ "" if self.so_64: report += "" + \ "" + "缺少64位so,google上架有要求,国内似乎暂无影响" + "" + \ "" + "存在so但缺乏64位架构" + "" + \ "" + "目前谷歌要求应用必须支持64位才能上架play商店,OEM厂商为了降低芯片的成本,可能只提供支持64位的版本,不考虑向下兼容。如果应用不适配支持64位,在后面的一些手机上将会无法运行。" + "" + \ "" + " 0 " + "" + \ "" + "联系sdk开发者,修改sdk版本号" + "" + \ "" for polic in self.policy: report += "" report += "" + polic["name"] + "" + \ "" + polic["summary"] + "" + \ "" + polic["desc"] + "" + \ "" + polic["level"] + "" + \ "" + " 请仔细查看该sdk用途和说明,如必须该权限需在app中保证用户同意,且隐私数据做匿名化处理,以此符合中央网信办、工信部、公安部、市场监管总局要求。" + "" report += "" report += "" return report # 结束操作 def delete(self): del self.permissions_policy def __del__(self): pass if __name__ == '__main__': sdkinfo.sdk_path = r"E:\work\workPython\sdkscan\test\getui_2.13.3.0-gisdk_3.1.9.1-gssdk_2.3.0.0.aar" config.xml_path = r"E:\work\workPython\sdkscan\temp\20191223-10-41-40\unzip\AndroidManifest.xml" info = InfoScanner() info.init() info.scan() info.report() polic = PolicyScanner() polic.init() polic.scan() polic.report() ================================================ FILE: script/__init__.py ================================================ # coding: utf-8 __author__ = 'deff' ================================================ FILE: script/exploit_api.json ================================================ [ { "name": "webView绕过证书校验漏洞", "summary": "webView绕过证书校验漏洞", "desc": "webView绕过证书校验漏洞实现调用了handler.proceed()来忽略该证书错误,则会受到中间人攻击的威胁,可能导致隐私泄露", "javacode": "", "smalicode": "Landroid/webkit/SslErrorHandler;->proceed()V", "level": "2", "sol": "当发生证书认证错误时,采用默认的处理方法handler.cancel(),停止加载问题页面" }, { "name": "忽略证书错误", "summary": "sdk忽略证书错误", "desc": "checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;)V", "javacode": "", "smalicode": "application/vnd.android.package-archive", "level": "2", "sol": "忽略证书错误继续加载和信任所有证书,将导致中间人攻击等严重安全隐患。" }, { "name": "弱随机数密钥", "summary": "sdk弱随机数密钥", "desc": "4.4以下存在随机数破解漏洞风险", "javacode": "", "smalicode": "Ljava/security/SecureRandom;->()V", "level": "1", "sol": "建议复查下调用,避免使用弱随机数密钥" }, { "name": "动态加载其他程序", "summary": "sdk动态加载其他程序", "desc": "sdk尝试进行动态加载其他程序", "javacode": "", "smalicode": "Ldalvik/system/DexClassLoader;->(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V", "level": "2", "sol": "加载的APK、DEX文件时要进行合理的校验;动态加载的文件应该了解其加载的内容" }, { "name": "运行其它可执行程序风险", "summary": "sdk运行其它可执行程序风险", "desc": "sdk运行其它可执行程序风险", "javacode": "", "smalicode": "Ljava/lang/ProcessBuilder;->start()Ljava/lang/Process;", "level": "2", "sol": "运行其它可执行程序风险,需要确认执行内容" }, { "name": "动态注册Receiver权限设置漏洞风险", "summary": "动态注册Receiver权限设置漏洞风险", "desc": "Receiver权限未设置,恶意程序可以发送相应的action广播危害应用安全", "javacode": "", "smalicode": ";->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;", "level": "2", "sol": "使用registerReceiver(BroadcastReceiver, IntentFilter, broadcastPermission, Handler)替代" }, { "name": "广播信息泄露风险", "summary": "广播信息泄露风险", "desc": "广播信息泄露风险", "javacode": "", "smalicode": "sendBroadcast(Landroid/content/Intent;)V", "level": "2", "sol": "建议使用显式调用方式发送Intent;进程内发送消息建议使用LocalBroadcastManager;" }, { "name": "顺网后台发送安全漏洞", "summary": "sdk包含顺网后台发送安全漏洞", "desc": "sdk包含顺网后台网址http://mbl.shunwang.com/cfg", "javacode": "", "smalicode": "http://mbl.shunwang.com/cfg", "level": "2", "sol": "立即反馈,顺网网址说明存在漏洞后门" }, { "name": "webview明文漏洞风险", "summary": "需要显式禁用setSavePassword(false),否则存在泄漏密码的风险", "desc": "使用webview时,要显式调用setSavePassword(false),禁止明文密码存储", "javacode": "", "smalicode": "Landroid/webkit/WebSettings;->setSavePassword(Z)V", "level": "2", "sol": "建议复查该api,若未显式调用setSavePassword(false),禁止明文密码存储。" }, { "name": "日志信息泄露风险", "summary": "日志信息泄露风险", "desc": "日志信息泄露风险,建议去除日志信息", "javacode": "", "smalicode": "Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I", "level": "1", "sol": "日志信息泄露,可能威胁用户敏感隐私数据安全。" }, { "name": "日志信息泄露风险", "summary": "日志信息泄露风险", "desc": "日志信息泄露风险,建议去除日志信息", "javacode": "", "smalicode": "Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I", "level": "1", "sol": "日志信息泄露,可能威胁用户敏感隐私数据安全。" } ] ================================================ FILE: script/hiddenapi-flags.csv ================================================ [File too large to display: 38.8 MB] ================================================ FILE: script/policy_api.json ================================================ [ { "name": "获取imei", "summary": "sdk获取imei信息,需谨慎处理,否则APP可能被要求整改", "desc": "1.工信部要求2.android10及以上获取不到了3.imei权限部分需要注意兼容", "javacode": "", "smalicode": { "0": "Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String", "1": "Landroid/telephony/TelephonyManager;->getImei(I)Ljava/lang/String", "2": "Landroid/telephony/TelephonyManager;->getDeviceId(I)Ljava/lang/String" }, "level": "2", "sol": "联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。" }, { "name": "获取imsi", "summary": "sdk获取imsi信息,需谨慎处理,否则APP可能被要求整改", "desc": "工信部要求,不得向第三方提供用户设备IMEI号、地理位置、imsi等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。", "javacode": "", "smalicode": { "0": "Landroid/telephony/TelephonyManager;->getSubscriberId()Ljava/lang/String", "1": "Landroid/telephony/TelephonyManager;->getSubscriberId(I)Ljava/lang/String" }, "level": "1", "sol": "联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。" }, { "name": "获取mac", "summary": "sdk获取mac信息,需谨慎处理,否则APP可能被要求整改", "desc": "1.工信部要求,mac也属于个人信息,2.android9及以上系统会随机生成不同的 MAC", "javacode": "", "smalicode": { "0": "Landroid/net/wifi/WifiInfo;->getMacAddress()Ljava/lang/String;" }, "level": "1", "sol": "联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。" }, { "name": "获取android id", "summary": "sdk获取android id信息,需谨慎处理,否则APP可能被要求整改", "desc": "1.工信部要求,android id也属于个人信息,2.厂商定制系统的Bug:不同的设备可能会产生相同的ANDROID_ID 3.厂商定制系统的Bug:有些设备返回的值为null。 设备差异:对于CDMA设备,ANDROID_ID和TelephonyManager.getDeviceId() 返回相同的值。", "javacode": "", "smalicode": { "0": "Landroid/provider/Settings$Secure;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String" }, "level": "1", "sol": "联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。" }, { "name": "获取短信信息", "summary": "sdk尝试获取短信", "desc": "获取短信属于高危安全部分,建议重点知悉", "javacode": "", "smalicode": { "0": "content://sms/" }, "level": "2", "sol": "联系sdk开发负责人或针对此进行处理,说明使用原因。在申请可收集个人信息的权限时,同步告知用户其目的" }, { "name": "获取联系人信息", "summary": "sdk尝试获取联系人", "desc": "获取联系人信息属于高危安全部分,建议重点知悉", "javacode": "", "smalicode": { "0": "content://com.android.contacts/raw_contacts" }, "level": "2", "sol": "联系sdk开发负责人或针对此进行处理,说明使用原因。在申请可收集个人信息的权限时,同步告知用户其目的" }, { "name": "获取通讯信息", "summary": "sdk尝试获取通讯信息", "desc": "通讯信息属于高危安全部分,建议重点知悉", "javacode": "", "smalicode": { "0": "CallLog.Calls.CONTENT_URI|content://call_log/calls" }, "level": "", "sol": "联系sdk开发负责人或针对此进行处理,说明使用原因。" }, { "name": "获取已安装程序列表", "summary": "sdk尝试获取已安装程序列表 1.该信息属于个人隐私信息 2.工信部要求", "desc": "sdk获取app列表,极有可能导致被整改", "javacode": "", "smalicode": { "0": "Landroid/content/pm/PackageManager;->getInstalledPackages(I)Ljava/util/List;" }, "level": "2", "sol": "联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。" }, { "name": "获取已安装程序列表", "summary": "sdk尝试获取已安装程序列表 1.该信息属于个人隐私信息 2.工信部要求", "desc": "sdk获取app列表,极有可能导致被整改", "javacode": "", "smalicode": { "0": "Landroid/content/pm/PackageManager;->getInstalledPackages(I)Ljava/util/List;", "1": "Landroid/content/pm/PackageManager;->queryIntentActivities(Landroid/content/Intent;I)Ljava/util/List", "2": "Landroid/content/pm/PackageManager;->getPackagesForUid(I)Ljava/util/List" }, "level": "2", "sol": "联系sdk开发负责人或针对此进行处理,说明使用原因。工信部要求,不得向第三方提供用户设备IMEI号、地理位置等个人信息,及sdk不得私自传输。若必须,请经用户同意,且做匿名化处理,并附有隐私政策说明。且若用户拒绝,不能影响app正常业务使用。" } ] ================================================ FILE: script/policy_permission.json ================================================ { "1": { "name": "android.permission.READ_PHONE_STATE", "summary": "读取手机状态和身份", "desc": "工信部要求不可获取,其次是andoridQ版本将限制应用访问不可重设的设备识别码,如 IMEI、序列号等,所有获取设备识别码的接口都增加了新的权限:READ_PRIVILEGED_PHONE_STATE,该权限需要系统签名的应用才能申请,意味着三方应用无法获取设备识别码。", "level": "2" }, "2": { "name": "android.permission.BRICK", "summary": "永久停用手机", "desc": "允许应用程序永久停用整个手机,属于工信部要求范围。", "level": "2" }, "3": { "name": "android.permission.BROADCAST_SMS", "summary": "发送短信收到的广播", "desc": "允许应用程序广播已收到短信的通知。请确认该sdk能使用该功能,否则违反工信部要求。", "level": "2" }, "4": { "name": "android.permission.CALL_PHONE", "summary": "直接拨打电话号码", "desc": "允许应用程序在您不介入的情况下拨打电话,注意该项可能违反工信部要求。", "level": "2" }, "5": { "name": "android.permission.CALL_PRIVILEGED", "summary": "直接呼叫任何电话号码", "desc": "允许应用程序在您不介入的情况下拨打任何电话(包括紧急呼救),注意该项可能违反工信部要求。", "level": "2" }, "6": { "name": "android.permission.DELETE_CACHE_FILES", "summary": "删除其他应用程序的缓存", "desc": "允许应用程序删除缓存文件。注意该项可能违反工信部要求。", "level": "2" }, "7": { "name": "android.permission.DEVICE_POWER", "summary": "开机或关机", "desc": "允许应用程序打开或关闭手机。注意该项可能违反工信部要求。", "level": "2" }, "8": { "name": "android.permission.DIAGNOSTIC", "summary": "读取/写入诊断所拥有的资源", "desc": "允许应用程序读取/写入诊断组所拥有的任何资源(例如,/dev 中的文件)。这可能会影响系统稳定性和安全性。此权限仅供制造商或运营商诊断硬件问题。", "level": "2" }, "9": { "name": "android.permission.INJECT_EVENTS", "summary": "按键和控制按钮", "desc": "允许应用程序将其自己的输入活动(按键等)提供给其他应用程序。恶意应用程序可借此掌控手机。注意该项可能违反工信部要求", "level": "2" }, "10": { "name": "android.permission.MASTER_CLEAR", "summary": "恢复出厂设置", "desc": "允许应用程序将系统恢复为出厂设置,即清除所有数据、配置以及所安装的应用程序。", "level": "2" }, "11": { "name": "android.permission.MOUNT_FORMAT_FILESYSTEMS", "summary": "格式化外部存储设备", "desc": "允许应用程序格式化可移除的存储设备。注意该项可能违反工信部要求", "level": "2" }, "12": { "name": "android.permission.PROCESS_OUTGOING_CALLS", "summary": "拦截外拨电话", "desc": "允许应用程序处理外拨电话或更改要拨打的号码。注意该项可能违反工信部要求。", "level": "2" }, "13": { "name": "android.permission.READ_CALL_LOG", "summary": "读取通话记录", "desc": "允许应用程序读取通话记录。此为高危风险,注意该项可能违反工信部要求", "level": "2" }, "14": { "name": "android.permission.READ_CONTACTS", "summary": "读取联系人数据", "desc": "允许应用程序读取您手机上存储的所有联系人(地址)数据。注意该项可能违反工信部要求", "level": "2" }, "15": { "name": "android.permission.READ_EXTERNAL_STORAGE", "summary": "读取外存", "desc": "允许应用程序读SD卡,目前应工信部要求,需用户授权,且不授权不能导致app失败,注意是否做好缺省。", "level": "2" }, "16": { "name": "android.permission.READ_INPUT_STATE", "summary": "记录您键入的内容和执行的操作", "desc": "允许应用程序查看您按的键,即使在与其他应用程序交互(例如输入密码)时也不例外。普通应用程序从不需要使用此权限。", "level": "2" }, "17": { "name": "android.permission.READ_SMS", "summary": "读取短信或彩信", "desc": "允许应用程序读取您的手机或 SIM 卡中存储的短信。注意该项可能违反工信部要求", "level": "2" }, "18": { "name": "android.permission.READ_USER_DICTIONARY", "summary": "读取用户定义的词典", "desc": "允许应用程序读取用户在用户词典中存储的任意私有字词、名称和短语。注意该项可能违反工信部要求", "level": "2" }, "19": { "name": "android.permission.RECEIVE_MMS", "summary": "接收彩信", "desc": "允许应用程序接收和处理彩信。注意该项可能违反工信部要求", "level": "2" }, "20": { "name": "android.permission.RECEIVE_SMS", "summary": "接收短信", "desc": "允许应用程序接收和处理短信。注意该项可能违反工信部要求", "level": "2" }, "21": { "name": "android.permission.RECEIVE_WAP_PUSH", "summary": "接收 WAP", "desc": "允许应用程序接收和处理 WAP 信息。注意该项可能违反工信部要求", "level": "2" }, "22": { "name": "android.permission.RECORD_AUDIO", "summary": "录音", "desc": "允许应用程序访问录音路径。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "23": { "name": "android.permission.SEND_SMS", "summary": "发送短信", "desc": "允许应用程序发送短信。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "24": { "name": "android.permission.WRITE_CALENDAR", "summary": "添加或修改日历活动以及向邀请对象发送电子邮件", "desc": "允许应用程序添加或更改日历中的活动,这可能会向邀请对象发送电子邮件。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "25": { "name": "android.permission.WRITE_CALL_LOG", "summary": "写入通话记录", "desc": "允许应用程序写 contacts data.注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "26": { "name": "android.permission.WRITE_CONTACTS", "summary": "写入联系人数据", "desc": "允许应用程序修改您手机上存储的联系人(地址)数据。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "27": { "name": "android.permission.WRITE_EXTERNAL_STORAGE", "summary": "修改/删除SD卡中的内容", "desc": "允许应用程序写入SD卡。需用户授权,且不授权不能导致app失败,注意是否做好缺省。", "level": "2" }, "28": { "name": "android.permission.WRITE_SECURE_SETTINGS", "summary": "修改安全系统设置", "desc": "允许应用程序修改系统的安全设置数据。普通应用程序不能使用此权限。", "level": "2" }, "29": { "name": "android.permission.WRITE_SETTINGS", "summary": "修改全局系统设置", "desc": "允许应用程序修改系统设置方面的数据。恶意应用程序可借此破坏您的系统配置。", "level": "2" }, "30": { "name": "android.permission.WRITE_SMS", "summary": "编辑短信或彩信", "desc": "允许应用程序写入手机或 SIM 卡中存储的短信。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "31": { "name": "com.android.browser.permission.READ_HISTORY_BOOKMARKS", "summary": "", "desc": "允许应用程序读取浏览器历史记录。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "32": { "name": "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS", "summary": "写入浏览器历史和书签记录", "desc": "允许应用程序写入浏览器历史和书签记录。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "33": { "name": "com.android.voicemail.permission.ADD_VOICEMAIL", "summary": "", "desc": "允许应用程序增加语音邮件。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "34": { "name": "android.permission.ADD_SYSTEM_SERVICE", "summary": "", "desc": "允许程序发布系统级服务。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "35": { "name": "android.permission.READ_OWNER_DATA", "summary": "读取基本信息", "desc": "允许程序读取所有者数据。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "36": { "name": "com.android.voicemail.permission.ADD_VOICEMAIL", "summary": "", "desc": "允许应用程序增加语音邮件。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "37": { "name": "android.permission.ACCESS_COARSE_LOCATION", "summary": "大概位置", "desc": "访问大概的位置源(例如蜂窝网络数据库)以确定手机的大概位置(如果可以)。注意该项可能违反工信部要求,个人隐私部分,且高版本存在其他定位要求。", "level": "2" }, "38": { "name": "android.permission.ACCESS_FINE_LOCATION", "summary": "精准的(GPS)位置", "desc": "访问精准的位置源,例如手机上的全球定位系统(如果有)。注意该项可能违反工信部要求,个人隐私部分,且高版本存在其他定位要求。", "level": "2" }, "39": { "name": "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS", "summary": "访问额外的位置信息提供程序命令", "desc": "访问额外的位置信息提供程序命令。注意该项可能违反工信部要求,个人隐私部分,且高版本存在其他定位要求。", "level": "2" }, "40": { "name": "android.permission.ACCESS_MOCK_LOCATION", "summary": "使用模拟地点来源进行测试", "desc": "创建模拟地点来源进行测试。注意该项可能违反工信部要求,个人隐私部分,且高版本存在其他定位要求。", "level": "1" }, "41": { "name": "android.permission.BATTERY_STATS", "summary": "修改电池统计信息", "desc": "允许修改收集的电池使用情况统计信息。普通应用程序不能使用此权限。", "level": "1" }, "42": { "name": "android.permission.BLUETOOTH", "summary": "创建蓝牙连接", "desc": "允许应用程序查看本地蓝牙手机的配置,以及建立或接受与配对设备的连接。注意该项可能违反工信部要求,个人隐私部分。", "level": "2" }, "43": { "name": "android.permission.BROADCAST_PACKAGE_REMOVED", "summary": "发送包删除的广播", "desc": "允许应用程序广播已删除某应用程序包的通知。恶意应用程序可借此终止任何正在运行的其他应用程序。", "level": "1" }, "44": { "name": "android.permission.BROADCAST_STICKY", "summary": "发送置顶广播", "desc": "允许应用程序发送顽固广播,这些广播在结束后仍会保留。恶意应用程序可能会借此使手机耗用太多内存,从而降低其速度或稳定性。", "level": "1" }, "45": { "name": "android.permission.CAMERA", "summary": "拍照", "desc": "允许应用程序使用相机拍照,注意该项可能违反工信部要求,个人隐私部分,且不授权不能影响用户使用。", "level": "2" }, "46": { "name": "android.permission.CHANGE_COMPONENT_ENABLED_STATE", "summary": "启用或停用应用程序组件", "desc": "允许应用程序更改是否启用其他应用程序的组件。恶意应用程序可借此停用重要的手机功能。使用此权限时务必谨慎,因为这可能导致应用程序组件进入不可用、不一致或不稳定的状态。", "level": "1" }, "47": { "name": "android.permission.CHANGE_WIFI_MULTICAST_STATE", "summary": "允许接收WLAN多播", "desc": "允许应用程序接收并非直接向您的设备发送的数据包。这样在查找附近提供的服务时很有用。这种操作所耗电量大于非多播模式。", "level": "1" }, "48": { "name": "android.permission.CLEAR_APP_USER_DATA", "summary": "删除其他应用程序的数据", "desc": "允许应用程序清除用户数据。注意该项可能违反工信部要求,个人隐私部分,且不授权不能影响用户使用。", "level": "1" }, "49": { "name": "android.permission.CONTROL_LOCATION_UPDATES", "summary": "控制位置更新通知", "desc": "允许启用/停用来自收音机的位置更新通知。普通应用程序不能使用此权限。", "level": "1" }, "50": { "name": "android.permission.GET_TASKS", "summary": "检索当前运行的应用程序", "desc": "允许应用程序检索有关当前和最近运行的任务的信息。注意该项可能违反工信部要求,个人隐私部分,且不授权不能影响用户使用。", "level": "1" }, "51": { "name": "android.permission.INSTALL_LOCATION_PROVIDER", "summary": "允许安装位置信息提供程序", "desc": "创建模拟地点来源进行测试。恶意应用程序可能利用此选项覆盖由真实地点来源(如 GPS 或网络提供商)所传回的地点和/或状态,或者监视您的位置并将其提供给外部来源。", "level": "1" }, "52": { "name": "android.permission.INSTALL_PACKAGES", "summary": "直接安装应用程序", "desc": "允许应用程序安装全新的或更新的 Android 包。注意该项可能违反工信部要求,请谨慎处理。", "level": "2" }, "53": { "name": "android.permission.MODIFY_PHONE_STATE", "summary": "修改手机状态", "desc": "允许应用程序控制设备的电话功能。拥有此权限的应用程序可自行切换网络、打开和关闭无线通信等,而不会通知您。", "level": "2" }, "54": { "name": "android.permission.READ_CALENDAR", "summary": "读取日历活动", "desc": "允许应用程序读取您手机上存储的所有日历活动。恶意应用程序可借此将您的日历活动发送给其他人。", "level": "2" }, "55": { "name": "android.permission.ACCESS_CHECKIN_PROPERTIES", "summary": "访问检入属性", "desc": "允许对检入服务上传的属性进行读/写访问。普通应用程序不能使用此权限。", "level": "0" }, "56": { "name": "android.permission.ACCESS_NETWORK_STATE", "summary": "查看网络状态", "desc": "允许应用程序查看所有网络的状态。", "level": "0" }, "57": { "name": "android.permission.ACCESS_SURFACE_FLINGER", "summary": "访问 SurfaceFlinger", "desc": "允许应用程序使用 SurfaceFlinger 低级别功能。", "level": "0" }, "58": { "name": "android.permission.ACCESS_WIFI_STATE", "summary": "查看 WLAN 状态", "desc": "允许应用程序查看有关 WLAN 状态的信息。", "level": "0" }, "59": { "name": "android.permission.ACCOUNT_MANAGER", "summary": "作为帐户身份验证程序", "desc": "允许应用程序使用 AccountManager 的帐户身份验证程序功能,包括创建帐户以及获取和设置其密码。", "level": "0" }, "60": { "name": "android.permission.AUTHENTICATE_ACCOUNTS", "summary": "作为帐户身份验证程序", "desc": "允许应用程序使用 AccountManager 的帐户身份验证程序功能,包括创建帐户以及获取和设置其密码。", "level": "0" }, "61": { "name": "android.permission.BIND_ACCESSIBILITY_SERVICE", "summary": "", "desc": "Must be required by an AccessibilityService, to ensure that only the system can bind to it.", "level": "0" }, "62": { "name": "android.permission.BIND_APPWIDGET", "summary": "选择窗口小部件", "desc": "允许应用程序告诉系统哪个应用程序可以使用哪些窗口小部件。具有该权限的应用程序可以允许其他应用程序访问个人数据。普通应用程序不能使用此权限。", "level": "0" }, "63": { "name": "android.permission.BIND_DEVICE_ADMIN", "summary": "与设备管理器交互", "desc": "允许持有对象将意向发送到设备管理器。普通的应用程序一律无需此权限。", "level": "0" }, "64": { "name": "android.permission.BIND_INPUT_METHOD", "summary": "绑定至输入法", "desc": "允许手机用户绑定至输入法的顶级界面。普通应用程序从不需要使用此权限。", "level": "0" }, "65": { "name": "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE", "summary": "", "desc": "Must be required by an NotificationListenerService, to ensure that only the system can bind to it.", "level": "0" }, "66": { "name": "android.permission.BIND_REMOTEVIEWS", "summary": "", "desc": "Must be required by a RemoteViewsService, to ensure that only the system can bind to it.", "level": "0" }, "67": { "name": "android.permission.BIND_TEXT_SERVICE", "summary": "", "desc": "Must be required by a TextService (e.g.", "level": "0" }, "68": { "name": "android.permission.BIND_VPN_SERVICE", "summary": "", "desc": "Must be required by an VpnService, to ensure that only the system can bind to it.", "level": "0" }, "69": { "name": "android.permission.BIND_WALLPAPER", "summary": "绑定到壁纸", "desc": "允许手机用户绑定到壁纸的顶级界面。应该从不需要将此权限授予普通应用程序。", "level": "0" }, "70": { "name": "android.permission.BLUETOOTH_ADMIN", "summary": "蓝牙管理", "desc": "允许应用程序配置本地蓝牙手机,以及发现远程设备并与其配对。", "level": "0" }, "71": { "name": "android.permission.BROADCAST_WAP_PUSH", "summary": "", "desc": "Allows an application to broadcast a WAP PUSH receipt notification.", "level": "0" }, "72": { "name": "android.permission.CHANGE_CONFIGURATION", "summary": "更改用户界面设置", "desc": "允许应用程序更改当前配置,例如语言设置或整体的字体大小。", "level": "0" }, "73": { "name": "android.permission.CHANGE_NETWORK_STATE", "summary": "更改网络连接性", "desc": "允许应用程序更改网络连接的状态。", "level": "0" }, "74": { "name": "android.permission.CHANGE_WIFI_STATE", "summary": "更改 WLAN 状态", "desc": "允许应用程序连接到 WLAN 接入点以及与 WLAN 接入点断开连接,并对配置的 WLAN 网络进行更改。", "level": "0" }, "75": { "name": "android.permission.CLEAR_APP_CACHE", "summary": "删除所有应用程序缓存数据", "desc": "允许应用程序通过删除应用程序缓存目录中的文件释放手机存储空间。通常此权限只适用于系统进程。", "level": "0" }, "76": { "name": "android.permission.DELETE_CACHE_FILES", "summary": "删除其他应用程序的缓存", "desc": "允许应用程序删除缓存文件。", "level": "2" }, "77": { "name": "android.permission.DEVICE_POWER", "summary": "开机或关机", "desc": "允许应用程序打开或关闭手机。", "level": "2" }, "78": { "name": "android.permission.DIAGNOSTIC", "summary": "读取/写入诊断所拥有的资源", "desc": "允许应用程序读取/写入诊断组所拥有的任何资源(例如,/dev 中的文件)。这可能会影响系统稳定性和安全性。此权限仅供制造商或运营商诊断硬件问题。", "level": "2" }, "79": { "name": "android.permission.DISABLE_KEYGUARD", "summary": "停用键锁", "desc": "允许应用程序停用键锁和任何关联的密码安全设置。例如,在手机上接听电话时停用键锁,在通话结束后重新启用键锁。", "level": "0" }, "80": { "name": "android.permission.DUMP", "summary": "检索系统内部状态", "desc": "允许应用程序检索系统的内部状态。恶意应用程序可借此检索它们本不需要的各种保密信息和安全信息。", "level": "0" }, "81": { "name": "android.permission.EXPAND_STATUS_BAR", "summary": "展开/收拢状态栏", "desc": "允许应用程序展开或收拢状态栏。", "level": "0" }, "82": { "name": "android.permission.FACTORY_TEST", "summary": "在出厂测试模式下运行", "desc": "作为一项低级制造商测试来运行,从而允许对手机硬件进行完全访问。此权限仅当手机在制造商测试模式下运行时才可用。", "level": "0" }, "83": { "name": "android.permission.FLASHLIGHT", "summary": "控制闪光灯", "desc": "允许应用程序控制闪光灯。", "level": "0" }, "84": { "name": "android.permission.FORCE_BACK", "summary": "强制应用程序关闭", "desc": "允许应用程序强制前端的任何活动关闭并重新开始。普通应用程序从不需要使用此权限。", "level": "0" }, "85": { "name": "android.permission.GET_ACCOUNTS", "summary": "发现已知帐户", "desc": "允许应用程序获取手机已知的帐户列表。", "level": "0" }, "86": { "name": "android.permission.GET_PACKAGE_SIZE", "summary": "计算应用程序存储空间", "desc": "允许应用程序检索其代码、数据和缓存大小", "level": "0" }, "87": { "name": "android.permission.GET_TOP_ACTIVITY_INFO", "summary": "", "desc": "Allows an application to retrieve private information about the current top activity, such as any assist context it can provide.", "level": "0" }, "88": { "name": "android.permission.GLOBAL_SEARCH", "summary": "全局搜索", "desc": "允许应用程序使用全局搜索。", "level": "0" }, "89": { "name": "android.permission.HARDWARE_TEST", "summary": "测试硬件", "desc": "允许应用程序控制各外围设备以进行硬件测试。", "level": "0" }, "90": { "name": "android.permission.INTERNAL_SYSTEM_WINDOW", "summary": "显示未授权的窗口", "desc": "允许创建专用于内部系统用户界面的窗口。普通应用程序不能使用此权限。", "level": "0" }, "91": { "name": "android.permission.INTERNET", "summary": "访问网络", "desc": "允许程序访问网络.", "level": "0" }, "92": { "name": "android.permission.KILL_BACKGROUND_PROCESSES", "summary": "结束后台进程", "desc": "无论内存资源是否紧张,都允许应用程序结束其他应用程序的后台进程。", "level": "0" }, "93": { "name": "android.permission.LOCATION_HARDWARE", "summary": "", "desc": "允许用户使用位置信息,甚至包括一些api the geofencing api.", "level": "0" }, "94": { "name": "android.permission.MANAGE_ACCOUNTS", "summary": "管理帐户列表", "desc": "允许应用程序执行添加、删除帐户及删除其密码之类的操作。", "level": "0" }, "95": { "name": "android.permission.MANAGE_APP_TOKENS", "summary": "管理应用程序令牌", "desc": "允许应用程序创建和管理自己的令牌,从而绕开其常规的 Z 方向。普通应用程序从不需要使用此权限。", "level": "0" }, "96": { "name": "android.permission.MODIFY_AUDIO_SETTINGS", "summary": "更改您的音频设置", "desc": "允许应用程序修改整个系统的音频设置,如音量和路由。", "level": "0" }, "97": { "name": "android.permission.MOUNT_UNMOUNT_FILESYSTEMS", "summary": "装载和卸载文件系统", "desc": "允许应用程序装载和卸载可移动存储器的文件系统。", "level": "0" }, "98": { "name": "android.permission.NFC", "summary": "", "desc": "使用NFC功能", "level": "0" }, "99": { "name": "android.permission.READ_LOGS", "summary": "读取系统日志文件", "desc": "允许应用程序从系统的各日志文件中读取信息。这样应用程序可以发现您的手机使用情况,但这些信息不应包含任何个人信息或保密信息。", "level": "0" }, "100": { "name": "android.permission.READ_PROFILE", "summary": "", "desc": "允许应用程序读 personal profile data.", "level": "0" }, "101": { "name": "android.permission.READ_SOCIAL_STREAM", "summary": "", "desc": "允许应用程序读 social stream.", "level": "0" }, "102": { "name": "android.permission.READ_SYNC_SETTINGS", "summary": "读取同步设置", "desc": "允许应用程序读取同步设置,例如是否为联系人启用同步。", "level": "0" }, "103": { "name": "android.permission.READ_SYNC_STATS", "summary": "读取同步统计信息", "desc": "允许应用程序读取同步统计信息;例如已发生的同步历史记录。", "level": "0" }, "104": { "name": "android.permission.REBOOT", "summary": "强行重新启动手机", "desc": "允许应用程序强行重新启动手机。", "level": "1" }, "105": { "name": "android.permission.RECEIVE_BOOT_COMPLETED", "summary": "开机时自动启动", "desc": "允许应用程序在系统完成启动后即自行启动。这样会延长手机的启动时间,而且如果应用程序一直运行,会降低手机的整体速度。", "level": "1" }, "106": { "name": "android.permission.REORDER_TASKS", "summary": "对正在运行的应用程序重新排序", "desc": "允许应用程序将任务移至前端和后台。恶意应用程序可借此强行进入前端,而不受您的控制。", "level": "1" }, "107": { "name": "android.permission.RESTART_PACKAGES", "summary": "重启程序", "desc": "允许程序自己重启或重启其他程序", "level": "0" }, "108": { "name": "android.permission.SEND_RESPOND_VIA_MESSAGE", "summary": "", "desc": "Allows an application (Phone) to send a request to other applications to handle the respond-via-message action during incoming calls.", "level": "0" }, "109": { "name": "android.permission.SET_ACTIVITY_WATCHER", "summary": "监控所有应用程序的启动", "desc": "允许应用程序监控系统启动活动的方式。恶意应用程序可借此彻底损坏系统。此权限仅在开发时才需要,普通的手机应用不需要。", "level": "1" }, "110": { "name": "android.permission.SET_ALWAYS_FINISH", "summary": "关闭所有后台应用程序", "desc": "允许应用程序控制活动是否始终是一转至后台就完成。普通应用程序从不需要使用此权限。", "level": "0" }, "111": { "name": "android.permission.SET_ANIMATION_SCALE", "summary": "修改全局动画速度", "desc": "允许应用程序随时更改全局动画速度(加快或放慢动画)。", "level": "0" }, "112": { "name": "android.permission.SET_DEBUG_APP", "summary": "启用应用程序调试", "desc": "允许应用程序启动对其他应用程序的调试。恶意应用程序可借此终止其他应用程序。", "level": "1" }, "113": { "name": "android.permission.SET_ORIENTATION", "summary": "更改屏幕显示方向", "desc": "允许应用程序随时更改屏幕的旋转方向。普通应用程序从不需要使用此权限。", "level": "0" }, "114": { "name": "android.permission.SET_POINTER_SPEED", "summary": "", "desc": "Allows low-level access to setting the pointer speed.", "level": "0" }, "115": { "name": "android.permission.SET_PREFERRED_APPLICATIONS", "summary": "设置首选应用程序", "desc": "允许应用程序修改首选的应用程序。这样恶意应用程序可能会暗中更改运行的应用程序,从而骗过您的现有应用程序来收集您的保密数据。", "level": "1" }, "116": { "name": "android.permission.SET_PROCESS_LIMIT", "summary": "限制运行的进程个数", "desc": "允许应用程序控制将运行的进程数上限。普通应用程序从不需要使用此权限。", "level": "0" }, "117": { "name": "android.permission.SET_TIME", "summary": "设置时间", "desc": "允许应用程序更改手机的时间。", "level": "0" }, "118": { "name": "android.permission.SET_TIME_ZONE", "summary": "设置时区", "desc": "允许应用程序更改手机的时区。", "level": "0" }, "119": { "name": "android.permission.SET_WALLPAPER", "summary": "设置壁纸", "desc": "允许应用程序设置系统壁纸。", "level": "0" }, "120": { "name": "android.permission.SET_WALLPAPER_HINTS", "summary": "设置壁纸大小提示", "desc": "允许应用程序设置有关壁纸大小的提示。", "level": "0" }, "121": { "name": "android.permission.SIGNAL_PERSISTENT_PROCESSES", "summary": "向应用程序发送 Linux 信号", "desc": "允许应用程序请求将所提供的信号发送给所有持久进程。", "level": "0" }, "122": { "name": "android.permission.STATUS_BAR", "summary": "停用或修改状态栏", "desc": "允许应用程序停用状态栏或者增删系统图标。", "level": "0" }, "123": { "name": "android.permission.SUBSCRIBED_FEEDS_READ", "summary": "读取订阅的供稿", "desc": "允许应用程序获取有关当前同步的供稿的详细信息。", "level": "0" }, "124": { "name": "android.permission.SUBSCRIBED_FEEDS_WRITE", "summary": "写入订阅的供稿", "desc": "允许应用程序修改您当前同步的供稿。恶意应用程序可借此更改您同步的供稿。", "level": "1" }, "125": { "name": "android.permission.SYSTEM_ALERT_WINDOW", "summary": "显示系统级警报", "desc": "允许应用程序显示系统警报窗口。恶意应用程序可借此掌控整个手机屏幕。", "level": "1" }, "126": { "name": "android.permission.UPDATE_DEVICE_STATS", "summary": "更新设备状态", "desc": "允许应用程序更新设备状态。", "level": "0" }, "127": { "name": "android.permission.USE_CREDENTIALS", "summary": "使用帐户的身份验证凭据", "desc": "允许应用程序请求身份验证标记。", "level": "0" }, "128": { "name": "android.permission.USE_SIP", "summary": "", "desc": "Allows an application to use SIP service", "level": "0" }, "129": { "name": "android.permission.VIBRATE", "summary": "控制振动器", "desc": "允许应用程序控制振动器。", "level": "0" }, "130": { "name": "android.permission.WAKE_LOCK", "summary": "防止手机休眠", "desc": "允许应用程序防止手机进入休眠状态。", "level": "0" }, "131": { "name": "android.permission.WRITE_APN_SETTINGS", "summary": "写入接入点名称设置", "desc": "允许应用程序修改 APN 设置,例如任何 APN 的代理和端口。", "level": "0" }, "132": { "name": "android.permission.WRITE_GSERVICES", "summary": "修改 Google 地图", "desc": "允许应用程序修改 Google 服务地图。普通应用程序不能使用此权限。", "level": "0" }, "133": { "name": "android.permission.WRITE_PROFILE", "summary": "", "desc": "允许应用程序写 personal profile data.", "level": "0" }, "134": { "name": "android.permission.WRITE_SOCIAL_STREAM", "summary": "", "desc": "允许应用程序写 social stream data.", "level": "0" }, "135": { "name": "android.permission.WRITE_SYNC_SETTINGS", "summary": "写入同步设置", "desc": "允许应用程序修改同步设置,例如是否为联系人启用同步。", "level": "1" }, "136": { "name": "android.permission.WRITE_USER_DICTIONARY", "summary": "写入用户定义的词典", "desc": "允许应用程序向用户词典中写入新词。", "level": "1" }, "137": { "name": "com.android.alarm.permission.SET_ALARM", "summary": "", "desc": "允许应用程序广播Intent来设置闹铃。", "level": "0" }, "138": { "name": "com.android.launcher.permission.INSTALL_SHORTCUT", "summary": "", "desc": "允许应用程序创建快捷方式。", "level": "0" }, "139": { "name": "android.permission.SET_PROCESS_FOREGROUND", "summary": "", "desc": "允许程序当前运行程序强行到前台。", "level": "1" } } ================================================ FILE: tools/adb/linux/api/api-versions.xml ================================================ ================================================ FILE: tools/adb/linux/source.properties ================================================ Pkg.UserSrc=false Pkg.Revision=22.0.0 ================================================ FILE: tools/adb/linux/systrace/AUTHORS ================================================ # Names should be added to this file with this pattern: # # For individuals: # Name # # For organizations: # Organization # # See python fnmatch module documentation for more information. The Chromium Authors <*@chromium.org> Google Inc. <*@google.com> ================================================ FILE: tools/adb/linux/systrace/LICENSE ================================================ // Copyright (c) 2010 The Chromium Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: tools/adb/linux/systrace/NOTICE ================================================ // Copyright (c) 2012 The Chromium Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS ================================================ FILE: tools/adb/linux/systrace/UPSTREAM_REVISION ================================================ 775 ================================================ FILE: tools/adb/linux/systrace/prefix.html ================================================ Android System Trace %s %s
%s
< / html >; ================================================ FILE: tools/adb/linux/systrace/systrace-legacy.py ================================================ #!/usr/bin/env python # Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Android system-wide tracing utility. This is a tool for capturing a trace that includes data from both userland and the kernel. It creates an HTML file for visualizing the trace. """ import optparse import os import select import subprocess import sys import zlib # This list is based on the tags in frameworks/native/include/utils/Trace.h. trace_tag_bits = { 'gfx': 1 << 1, 'input': 1 << 2, 'view': 1 << 3, 'webview': 1 << 4, 'wm': 1 << 5, 'am': 1 << 6, 'sync': 1 << 7, 'audio': 1 << 8, 'video': 1 << 9, 'camera': 1 << 10, } flattened_css_file = 'style.css' flattened_js_file = 'script.js' def add_adb_serial(command, serial): if serial != None: command.insert(1, serial) command.insert(1, '-s') def main(): parser = optparse.OptionParser() parser.add_option('-o', dest='output_file', help='write HTML to FILE', default='trace.html', metavar='FILE') parser.add_option('-t', '--time', dest='trace_time', type='int', help='trace for N seconds', metavar='N') parser.add_option('-b', '--buf-size', dest='trace_buf_size', type='int', help='use a trace buffer size of N KB', metavar='N') parser.add_option('-d', '--disk', dest='trace_disk', default=False, action='store_true', help='trace disk I/O (requires root)') parser.add_option('-f', '--cpu-freq', dest='trace_cpu_freq', default=False, action='store_true', help='trace CPU frequency changes') parser.add_option('-i', '--cpu-idle', dest='trace_cpu_idle', default=False, action='store_true', help='trace CPU idle events') parser.add_option('-l', '--cpu-load', dest='trace_cpu_load', default=False, action='store_true', help='trace CPU load') parser.add_option('-s', '--no-cpu-sched', dest='trace_cpu_sched', default=True, action='store_false', help='inhibit tracing CPU ' + 'scheduler (allows longer trace times by reducing data ' + 'rate into buffer)') parser.add_option('-u', '--bus-utilization', dest='trace_bus_utilization', default=False, action='store_true', help='trace bus utilization (requires root)') parser.add_option('-w', '--workqueue', dest='trace_workqueue', default=False, action='store_true', help='trace the kernel workqueues ' + '(requires root)') parser.add_option('--set-tags', dest='set_tags', action='store', help='set the enabled trace tags and exit; set to a ' + 'comma separated list of: ' + ', '.join(trace_tag_bits.iterkeys())) parser.add_option('--link-assets', dest='link_assets', default=False, action='store_true', help='link to original CSS or JS resources ' 'instead of embedding them') parser.add_option('--from-file', dest='from_file', action='store', help='read the trace from a file rather than running a live trace') parser.add_option('--asset-dir', dest='asset_dir', default='trace-viewer', type='string', help='') parser.add_option('-e', '--serial', dest='device_serial', type='string', help='adb device serial number') options, args = parser.parse_args() if options.set_tags: flags = 0 tags = options.set_tags.split(',') for tag in tags: try: flags |= trace_tag_bits[tag] except KeyError: parser.error('unrecognized tag: %s\nknown tags are: %s' % (tag, ', '.join(trace_tag_bits.iterkeys()))) atrace_args = ['adb', 'shell', 'setprop', 'debug.atrace.tags.enableflags', hex(flags)] add_adb_serial(atrace_args, options.device_serial) try: subprocess.check_call(atrace_args) except subprocess.CalledProcessError, e: print >> sys.stderr, 'unable to set tags: %s' % e print '\nSet enabled tags to: %s\n' % ', '.join(tags) print('You will likely need to restart the Android framework for this to ' + 'take effect:\n\n adb shell stop\n adb shell ' + 'start\n') return atrace_args = ['adb', 'shell', 'atrace', '-z'] add_adb_serial(atrace_args, options.device_serial) if options.trace_disk: atrace_args.append('-d') if options.trace_cpu_freq: atrace_args.append('-f') if options.trace_cpu_idle: atrace_args.append('-i') if options.trace_cpu_load: atrace_args.append('-l') if options.trace_cpu_sched: atrace_args.append('-s') if options.trace_bus_utilization: atrace_args.append('-u') if options.trace_workqueue: atrace_args.append('-w') if options.trace_time is not None: if options.trace_time > 0: atrace_args.extend(['-t', str(options.trace_time)]) else: parser.error('the trace time must be a positive number') if options.trace_buf_size is not None: if options.trace_buf_size > 0: atrace_args.extend(['-b', str(options.trace_buf_size)]) else: parser.error('the trace buffer size must be a positive number') if options.from_file is not None: atrace_args = ['cat', options.from_file] script_dir = os.path.dirname(os.path.abspath(sys.argv[0])) if options.link_assets: src_dir = os.path.join(script_dir, options.asset_dir, 'src') build_dir = os.path.join(script_dir, options.asset_dir, 'build') js_files, js_flattenizer, css_files, templates = get_assets(src_dir, build_dir) css = '\n'.join(linked_css_tag % (os.path.join(src_dir, f)) for f in css_files) js = '\n' % js_flattenizer js += '\n'.join(linked_js_tag % (os.path.join(src_dir, f)) for f in js_files) else: css_filename = os.path.join(script_dir, flattened_css_file) js_filename = os.path.join(script_dir, flattened_js_file) css = compiled_css_tag % (open(css_filename).read()) js = compiled_js_tag % (open(js_filename).read()) templates = '' html_filename = options.output_file trace_started = False leftovers = '' adb = subprocess.Popen(atrace_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) dec = zlib.decompressobj() while True: ready = select.select([adb.stdout, adb.stderr], [], [adb.stdout, adb.stderr]) if adb.stderr in ready[0]: err = os.read(adb.stderr.fileno(), 4096) sys.stderr.write(err) sys.stderr.flush() if adb.stdout in ready[0]: out = leftovers + os.read(adb.stdout.fileno(), 4096) if options.from_file is None: out = out.replace('\r\n', '\n') if out.endswith('\r'): out = out[:-1] leftovers = '\r' else: leftovers = '' if not trace_started: lines = out.splitlines(True) out = '' for i, line in enumerate(lines): if line == 'TRACE:\n': sys.stdout.write("downloading trace...") sys.stdout.flush() out = ''.join(lines[i + 1:]) html_prefix = read_asset(script_dir, 'prefix.html') html_file = open(html_filename, 'w') html_file.write(html_prefix % (css, js, templates)) trace_started = True break elif 'TRACE:'.startswith(line) and i == len(lines) - 1: leftovers = line + leftovers else: sys.stdout.write(line) sys.stdout.flush() if len(out) > 0: out = dec.decompress(out) html_out = out.replace('\n', '\\n\\\n') if len(html_out) > 0: html_file.write(html_out) result = adb.poll() if result is not None: break if result != 0: print >> sys.stderr, 'adb returned error code %d' % result elif trace_started: html_out = dec.flush().replace('\n', '\\n\\\n').replace('\r', '') if len(html_out) > 0: html_file.write(html_out) html_suffix = read_asset(script_dir, 'suffix.html') html_file.write(html_suffix) html_file.close() print " done\n\n wrote file://%s\n" % (os.path.abspath(options.output_file)) else: print >> sys.stderr, ('An error occured while capturing the trace. Output ' + 'file was not written.') def read_asset(src_dir, filename): return open(os.path.join(src_dir, filename)).read() def get_assets(src_dir, build_dir): sys.path.append(build_dir) gen = __import__('generate_standalone_timeline_view', {}, {}) parse_deps = __import__('parse_deps', {}, {}) gen_templates = __import__('generate_template_contents', {}, {}) filenames = gen._get_input_filenames() load_sequence = parse_deps.calc_load_sequence(filenames, src_dir) js_files = [] js_flattenizer = "window.FLATTENED = {};\n" js_flattenizer += "window.FLATTENED_RAW_SCRIPTS = {};\n" css_files = [] for module in load_sequence: js_files.append(os.path.relpath(module.filename, src_dir)) js_flattenizer += "window.FLATTENED['%s'] = true;\n" % module.name for dependent_raw_script_name in module.dependent_raw_script_names: js_flattenizer += ( "window.FLATTENED_RAW_SCRIPTS['%s'] = true;\n" % dependent_raw_script_name) for style_sheet in module.style_sheets: css_files.append(os.path.relpath(style_sheet.filename, src_dir)) templates = gen_templates.generate_templates() sys.path.pop() return (js_files, js_flattenizer, css_files, templates) compiled_css_tag = """""" compiled_js_tag = """""" linked_css_tag = """""" linked_js_tag = """""" if __name__ == '__main__': main() ================================================ FILE: tools/adb/linux/systrace/systrace.py ================================================ #!/usr/bin/env python # Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Android system-wide tracing utility. This is a tool for capturing a trace that includes data from both userland and the kernel. It creates an HTML file for visualizing the trace. """ import optparse import os import re import select import subprocess import sys import zlib flattened_css_file = 'style.css' flattened_js_file = 'script.js' class OptionParserIgnoreErrors(optparse.OptionParser): def error(self, msg): pass def exit(self): pass def print_usage(self): pass def print_help(self): pass def print_version(self): pass def get_device_sdk_version(): getprop_args = ['adb', 'shell', 'getprop', 'ro.build.version.sdk'] parser = OptionParserIgnoreErrors() parser.add_option('-e', '--serial', dest='device_serial', type='string') options, args = parser.parse_args() if options.device_serial is not None: getprop_args[1:1] = ['-s', options.device_serial] adb = subprocess.Popen(getprop_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = adb.communicate() if adb.returncode != 0: print >> sys.stderr, 'Error querying device SDK-version:' print >> sys.stderr, err sys.exit(1) version = int(out) return version def add_adb_serial(command, serial): if serial is not None: command.insert(1, serial) command.insert(1, '-s') def main(): device_sdk_version = get_device_sdk_version() if device_sdk_version < 18: legacy_script = os.path.join(os.path.dirname(sys.argv[0]), 'systrace-legacy.py') os.execv(legacy_script, sys.argv) usage = "Usage: %prog [options] [category1 [category2 ...]]" desc = "Example: %prog -b 32768 -t 15 gfx input view sched freq" parser = optparse.OptionParser(usage=usage, description=desc) parser.add_option('-o', dest='output_file', help='write HTML to FILE', default='trace.html', metavar='FILE') parser.add_option('-t', '--time', dest='trace_time', type='int', help='trace for N seconds', metavar='N') parser.add_option('-b', '--buf-size', dest='trace_buf_size', type='int', help='use a trace buffer size of N KB', metavar='N') parser.add_option('-k', '--ktrace', dest='kfuncs', action='store', help='specify a comma-separated list of kernel functions to trace') parser.add_option('-l', '--list-categories', dest='list_categories', default=False, action='store_true', help='list the available categories and exit') parser.add_option('-a', '--app', dest='app_name', default=None, type='string', action='store', help='enable application-level tracing for comma-separated ' + 'list of app cmdlines') parser.add_option('--no-fix-threads', dest='fix_threads', default=True, action='store_false', help='don\'t fix missing or truncated thread names') parser.add_option('--link-assets', dest='link_assets', default=False, action='store_true', help='link to original CSS or JS resources ' 'instead of embedding them') parser.add_option('--from-file', dest='from_file', action='store', help='read the trace from a file (compressed) rather than running a live trace') parser.add_option('--asset-dir', dest='asset_dir', default='trace-viewer', type='string', help='') parser.add_option('-e', '--serial', dest='device_serial', type='string', help='adb device serial number') options, args = parser.parse_args() if options.list_categories: atrace_args = ['adb', 'shell', 'atrace', '--list_categories'] expect_trace = False elif options.from_file is not None: atrace_args = ['cat', options.from_file] expect_trace = True else: atrace_args = ['adb', 'shell', 'atrace', '-z'] expect_trace = True if options.trace_time is not None: if options.trace_time > 0: atrace_args.extend(['-t', str(options.trace_time)]) else: parser.error('the trace time must be a positive number') if options.trace_buf_size is not None: if options.trace_buf_size > 0: atrace_args.extend(['-b', str(options.trace_buf_size)]) else: parser.error('the trace buffer size must be a positive number') if options.app_name is not None: atrace_args.extend(['-a', options.app_name]) if options.kfuncs is not None: atrace_args.extend(['-k', options.kfuncs]) atrace_args.extend(args) if options.fix_threads: atrace_args.extend([';', 'ps', '-t']) if atrace_args[0] == 'adb': add_adb_serial(atrace_args, options.device_serial) script_dir = os.path.dirname(os.path.abspath(sys.argv[0])) if options.link_assets: src_dir = os.path.join(script_dir, options.asset_dir, 'src') build_dir = os.path.join(script_dir, options.asset_dir, 'build') js_files, js_flattenizer, css_files, templates = get_assets(src_dir, build_dir) css = '\n'.join(linked_css_tag % (os.path.join(src_dir, f)) for f in css_files) js = '\n' % js_flattenizer js += '\n'.join(linked_js_tag % (os.path.join(src_dir, f)) for f in js_files) else: css_filename = os.path.join(script_dir, flattened_css_file) js_filename = os.path.join(script_dir, flattened_js_file) css = compiled_css_tag % (open(css_filename).read()) js = compiled_js_tag % (open(js_filename).read()) templates = '' html_filename = options.output_file adb = subprocess.Popen(atrace_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) result = None data = [] # Read the text portion of the output and watch for the 'TRACE:' marker that # indicates the start of the trace data. while result is None: ready = select.select([adb.stdout, adb.stderr], [], [adb.stdout, adb.stderr]) if adb.stderr in ready[0]: err = os.read(adb.stderr.fileno(), 4096) sys.stderr.write(err) sys.stderr.flush() if adb.stdout in ready[0]: out = os.read(adb.stdout.fileno(), 4096) parts = out.split('\nTRACE:', 1) txt = parts[0].replace('\r', '') if len(parts) == 2: # The '\nTRACE:' match stole the last newline from the text, so add it # back here. txt += '\n' sys.stdout.write(txt) sys.stdout.flush() if len(parts) == 2: data.append(parts[1]) sys.stdout.write("downloading trace...") sys.stdout.flush() break result = adb.poll() # Read and buffer the data portion of the output. while True: ready = select.select([adb.stdout, adb.stderr], [], [adb.stdout, adb.stderr]) keepReading = False if adb.stderr in ready[0]: err = os.read(adb.stderr.fileno(), 4096) if len(err) > 0: keepReading = True sys.stderr.write(err) sys.stderr.flush() if adb.stdout in ready[0]: out = os.read(adb.stdout.fileno(), 4096) if len(out) > 0: keepReading = True data.append(out) if result is not None and not keepReading: break result = adb.poll() if result == 0: if expect_trace: data = ''.join(data) # Collapse CRLFs that are added by adb shell. if data.startswith('\r\n'): data = data.replace('\r\n', '\n') # Skip the initial newline. data = data[1:] if not data: print >> sys.stderr, ('No data was captured. Output file was not ' + 'written.') sys.exit(1) else: # Indicate to the user that the data download is complete. print " done\n" # Extract the thread list dumped by ps. threads = {} if options.fix_threads: parts = data.split('USER PID PPID VSIZE RSS WCHAN PC NAME', 1) if len(parts) == 2: data = parts[0] for line in parts[1].splitlines(): cols = line.split(None, 8) if len(cols) == 9: tid = int(cols[1]) name = cols[8] threads[tid] = name # Decompress and preprocess the data. out = zlib.decompress(data) if options.fix_threads: def repl(m): tid = int(m.group(2)) if tid > 0: name = threads.get(tid) if name is None: name = m.group(1) if name == '<...>': name = '<' + str(tid) + '>' threads[tid] = name return name + '-' + m.group(2) else: return m.group(0) out = re.sub(r'^\s*(\S+)-(\d+)', repl, out, flags=re.MULTILINE) html_prefix = read_asset(script_dir, 'prefix.html') html_suffix = read_asset(script_dir, 'suffix.html') html_file = open(html_filename, 'w') html_file.write(html_prefix % (css, js, templates)) html_out = out.replace('\n', '\\n\\\n') html_file.write(html_out) html_file.write(html_suffix) html_file.close() print "\n wrote file://%s\n" % os.path.abspath(options.output_file) else: # i.e. result != 0 print >> sys.stderr, 'adb returned error code %d' % result sys.exit(1) def read_asset(src_dir, filename): return open(os.path.join(src_dir, filename)).read() def get_assets(src_dir, build_dir): sys.path.append(build_dir) gen = __import__('generate_standalone_timeline_view', {}, {}) parse_deps = __import__('parse_deps', {}, {}) gen_templates = __import__('generate_template_contents', {}, {}) filenames = gen._get_input_filenames() load_sequence = parse_deps.calc_load_sequence(filenames, src_dir) js_files = [] js_flattenizer = "window.FLATTENED = {};\n" js_flattenizer += "window.FLATTENED_RAW_SCRIPTS = {};\n" css_files = [] for module in load_sequence: js_files.append(os.path.relpath(module.filename, src_dir)) js_flattenizer += "window.FLATTENED['%s'] = true;\n" % module.name for dependent_raw_script_name in module.dependent_raw_script_names: js_flattenizer += ( "window.FLATTENED_RAW_SCRIPTS['%s'] = true;\n" % dependent_raw_script_name) for style_sheet in module.style_sheets: css_files.append(os.path.relpath(style_sheet.filename, src_dir)) templates = gen_templates.generate_templates() sys.path.pop() return (js_files, js_flattenizer, css_files, templates) compiled_css_tag = """""" compiled_js_tag = """""" linked_css_tag = """""" linked_js_tag = """""" if __name__ == '__main__': main() ================================================ FILE: tools/adb/mac/api/api-versions.xml ================================================ ================================================ FILE: tools/adb/mac/source.properties ================================================ ### Android Tool: Source of this archive. #Wed Jan 14 20:00:14 GMT+05:30 2015 Archive.HostOs=macosx Pkg.License=To get started with the Android SDK, you must agree to the following terms and conditions.\n\nThis is the Android SDK License Agreement (the "License Agreement").\n\n1. Introduction\n\n1.1 The Android SDK (referred to in the License Agreement as the "SDK" and specifically including the Android system files, packaged APIs, and SDK library files and tools , if and when they are made available) is licensed to you subject to the terms of the License Agreement. The License Agreement forms a legally binding contract between you and Google in relation to your use of the SDK.\n\n1.2 "Android" means the Android software stack for devices, as made available under the Android Open Source Project, which is located at the following URL\: http\://source.android.com/, as updated from time to time.\n\n1.3 "Google" means Google Inc., a Delaware corporation with principal place of business at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States.\n\n2. Accepting the License Agreement\n\n2.1 In order to use the SDK, you must first agree to the License Agreement. You may not use the SDK if you do not accept the License Agreement.\n\n2.2 By clicking to accept and/or using the SDK, you hereby agree to the terms of the License Agreement.\n\n2.3 You may not use the SDK and may not accept the License Agreement if you are a person barred from receiving the SDK under the laws of the United States or other countries including the country in which you are resident or from which you use the SDK.\n\n2.4 If you will use the SDK internally within your company or organization you agree to be bound by the License Agreement on behalf of your employer or other entity, and you represent and warrant that you have full legal authority to bind your employer or such entity to the License Agreement. If you do not have the requisite authority, you may not accept the License Agreement or use the SDK on behalf of your employer or other entity.\n\n3. SDK License from Google\n\n3.1 Subject to the terms of the License Agreement, Google grants you a royalty-free, non-assignable, non-exclusive, non-sublicensable, limited, revocable license to use the SDK, personally or internally within your company or organization, solely to develop and distribute applications to run on the Android platform.\n\n3.2 You agree that Google or third parties own all legal right, title and interest in and to the SDK, including any Intellectual Property Rights that subsist in the SDK. "Intellectual Property Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law, and any and all other proprietary rights. Google reserves all rights not expressly granted to you.\n\n3.3 You may not use the SDK for any purpose not expressly permitted by the License Agreement. Except to the extent required by applicable third party licenses, you may not\: (a) copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the SDK or any part of the SDK; or (b) load any part of the SDK onto a mobile handset or any other hardware device except a personal computer, combine any part of the SDK with other software, or distribute any software or device incorporating a part of the SDK.\n\n3.4 You agree that you will not take any actions that may cause or result in the fragmentation of Android, including but not limited to distributing, participating in the creation of, or promoting in any way a software development kit derived from the SDK.\n\n3.5 Use, reproduction and distribution of components of the SDK licensed under an open source software license are governed solely by the terms of that open source software license and not the License Agreement. You agree to remain a licensee in good standing in regard to such open source software licenses under all the rights granted and to refrain from any actions that may terminate, suspend, or breach such rights.\n\n3.6 You agree that the form and nature of the SDK that Google provides may change without prior notice to you and that future versions of the SDK may be incompatible with applications developed on previous versions of the SDK. You agree that Google may stop (permanently or temporarily) providing the SDK (or any features within the SDK) to you or to users generally at Google's sole discretion, without prior notice to you.\n\n3.7 Nothing in the License Agreement gives you a right to use any of Google's trade names, trademarks, service marks, logos, domain names, or other distinctive brand features.\n\n3.8 You agree that you will not remove, obscure, or alter any proprietary rights notices (including copyright and trademark notices) that may be affixed to or contained within the SDK.\n\n4. Use of the SDK by You\n\n4.1 Google agrees that nothing in the License Agreement gives Google any right, title or interest from you (or your licensors) under the License Agreement in or to any software applications that you develop using the SDK, including any intellectual property rights that subsist in those applications.\n\n4.2 You agree to use the SDK and write applications only for purposes that are permitted by (a) the License Agreement, and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).\n\n4.3 You agree that if you use the SDK to develop applications, you will protect the privacy and legal rights of users. If users provide you with user names, passwords, or other login information or personal information, you must make the users aware that the information will be available to your application, and you must provide legally adequate privacy notice and protection for those users. If your application stores personal or sensitive information provided by users, it must do so securely. If users provide you with Google Account information, your application may only use that information to access the user's Google Account when, and for the limited purposes for which, each user has given you permission to do so.\n\n4.4 You agree that you will not engage in any activity with the SDK, including the development or distribution of an application, that interferes with, disrupts, damages, or accesses in an unauthorized manner the servers, networks, or other properties or services of Google or any third party.\n\n4.5 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any data, content, or resources that you create, transmit or display through Android and/or applications for Android, and for the consequences of your actions (including any loss or damage which Google may suffer) by doing so.\n\n4.6 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any breach of your obligations under the License Agreement, any applicable third party contract or Terms of Service, or any applicable law or regulation, and for the consequences (including any loss or damage which Google or any third party may suffer) of any such breach.\n\n5. Your Developer Credentials\n\n5.1 You agree that you are responsible for maintaining the confidentiality of any developer credentials that may be issued to you by Google or which you may choose yourself and that you will be solely responsible for all applications that are developed under your developer credentials.\n\n6. Privacy and Information\n\n6.1 In order to continually innovate and improve the SDK, Google may collect certain usage statistics from the software including but not limited to a unique identifier, associated IP address, version number of the software, and information on which tools and/or services in the SDK are being used and how they are being used. Before any of this information is collected, the SDK will notify you and seek your consent. If you withhold consent, the information will not be collected.\n\n6.2 The data collected is examined in the aggregate to improve the SDK and is maintained in accordance with Google's Privacy Policy located at http\://www.google.com/policies/privacy/.\n\n7. Third Party Applications\n\n7.1 If you use the SDK to run applications developed by a third party or that access data, content or resources provided by a third party, you agree that Google is not responsible for those applications, data, content, or resources. You understand that all data, content or resources which you may access through such third party applications are the sole responsibility of the person from which they originated and that Google is not liable for any loss or damage that you may experience as a result of the use or access of any of those third party applications, data, content, or resources.\n\n7.2 You should be aware the data, content, and resources presented to you through such a third party application may be protected by intellectual property rights which are owned by the providers (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on these data, content, or resources (either in whole or in part) unless you have been specifically given permission to do so by the relevant owners.\n\n7.3 You acknowledge that your use of such third party applications, data, content, or resources may be subject to separate terms between you and the relevant third party.\n\n8. Using Google APIs\n\n8.1 Google APIs\n\n8.1.1 If you use any API to retrieve data from Google, you acknowledge that the data may be protected by intellectual property rights which are owned by Google or those parties that provide the data (or by other persons or companies on their behalf). Your use of any such API may be subject to additional Terms of Service. You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this data (either in whole or in part) unless allowed by the relevant Terms of Service.\n\n8.1.2 If you use any API to retrieve a user's data from Google, you acknowledge and agree that you shall retrieve data only with the user's explicit consent and only when, and for the limited purposes for which, the user has given you permission to do so.\n\n9. Terminating the License Agreement\n\n9.1 The License Agreement will continue to apply until terminated by either you or Google as set out below.\n\n9.2 If you want to terminate the License Agreement, you may do so by ceasing your use of the SDK and any relevant developer credentials.\n\n9.3 Google may at any time, terminate the License Agreement, with or without cause, upon notice to you.\n\n9.4 The License Agreement will automatically terminate without notice or other action when Google ceases to provide the SDK or certain parts of the SDK to users in the country in which you are resident or from which you use the service.\n\n9.5 When the License Agreement is terminated, the license granted to you in the License Agreement will terminate, you will immediately cease all use of the SDK, and the provisions of paragraphs 10, 11, 12 and 14 shall survive indefinitely.\n\n10. DISCLAIMERS\n\n10.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE SDK IS AT YOUR SOLE RISK AND THAT THE SDK IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND FROM GOOGLE.\n\n10.2 YOUR USE OF THE SDK AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE SDK IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA THAT RESULTS FROM SUCH USE. WITHOUT LIMITING THE FOREGOING, YOU UNDERSTAND THAT THE SDK MAY CONTAIN ERRORS, DEFECTS AND SECURITY VULNERABILITIES THAT CAN RESULT IN SIGNIFICANT DAMAGE, INCLUDING THE COMPLETE, IRRECOVERABLE LOSS OF USE OF YOUR COMPUTER SYSTEM OR OTHER DEVICE.\n\n10.3 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\n\n11. LIMITATION OF LIABILITY\n\n11.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER OR NOT GOOGLE OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.\n\n12. Indemnification\n\n12.1 To the maximum extent permitted by law, you agree to defend, indemnify and hold harmless Google, its affiliates and their respective directors, officers, employees and agents from and against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses (including reasonable attorneys\u2019 fees) arising out of or accruing from (a) your use of the SDK, (b) any application you develop on the SDK that infringes any Intellectual Property Rights of any person or defames any person or violates their rights of publicity or privacy, and (c) any non-compliance by you of the License Agreement.\n\n13. Changes to the License Agreement\n\n13.1 Google may make changes to the License Agreement as it distributes new versions of the SDK. When these changes are made, Google will make a new version of the License Agreement available on the website where the SDK is made available.\n\n14. General Legal Terms\n\n14.1 The License Agreement constitutes the whole legal agreement between you and Google and governs your use of the SDK (excluding any services which Google may provide to you under a separate written agreement), and completely replaces any prior agreements between you and Google in relation to the SDK.\n\n14.2 You agree that if Google does not exercise or enforce any legal right or remedy which is contained in the License Agreement (or which Google has the benefit of under any applicable law), this will not be taken to be a formal waiver of Google's rights and that those rights or remedies will still be available to Google.\n\n14.3 If any court of law, having the jurisdiction to decide on this matter, rules that any provision of the License Agreement is invalid, then that provision will be removed from the License Agreement without affecting the rest of the License Agreement. The remaining provisions of the License Agreement will continue to be valid and enforceable.\n\n14.4 You acknowledge and agree that each member of the group of companies of which Google is the parent shall be third party beneficiaries to the License Agreement and that such other companies shall be entitled to directly enforce, and rely upon, any provision of the License Agreement that confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to the License Agreement.\n\n14.5 EXPORT RESTRICTIONS. THE SDK IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS. YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND REGULATIONS THAT APPLY TO THE SDK. THESE LAWS INCLUDE RESTRICTIONS ON DESTINATIONS, END USERS AND END USE.\n\n14.6 The License Agreement may not be assigned or transferred by you without the prior written approval of Google, and any attempted assignment without such approval will be void. You shall not delegate your responsibilities or obligations under the License Agreement without the prior written approval of Google.\n\n14.7 The License Agreement, and your relationship with Google under the License Agreement, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from the License Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.\n\nJune 2014.\n Pkg.LicenseRef=android-sdk-license Pkg.Revision=21 Pkg.SourceUrl=https\://dl-ssl.google.com/android/repository/repository-10.xml ================================================ FILE: tools/adb/mac/systrace/AUTHORS ================================================ # Names should be added to this file with this pattern: # # For individuals: # Name # # For organizations: # Organization # # See python fnmatch module documentation for more information. The Chromium Authors <*@chromium.org> Google Inc. <*@google.com> ================================================ FILE: tools/adb/mac/systrace/LICENSE ================================================ // Copyright (c) 2010 The Chromium Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: tools/adb/mac/systrace/NOTICE ================================================ // Copyright (c) 2012 The Chromium Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS ================================================ FILE: tools/adb/mac/systrace/UPSTREAM_REVISION ================================================ 775 ================================================ FILE: tools/adb/mac/systrace/prefix.html ================================================ Android System Trace %s %s
%s
< / html >; ================================================ FILE: tools/adb/mac/systrace/systrace-legacy.py ================================================ #!/usr/bin/env python # Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Android system-wide tracing utility. This is a tool for capturing a trace that includes data from both userland and the kernel. It creates an HTML file for visualizing the trace. """ import optparse import os import select import subprocess import sys import zlib # This list is based on the tags in frameworks/native/include/utils/Trace.h. trace_tag_bits = { 'gfx': 1 << 1, 'input': 1 << 2, 'view': 1 << 3, 'webview': 1 << 4, 'wm': 1 << 5, 'am': 1 << 6, 'sync': 1 << 7, 'audio': 1 << 8, 'video': 1 << 9, 'camera': 1 << 10, } flattened_css_file = 'style.css' flattened_js_file = 'script.js' def add_adb_serial(command, serial): if serial != None: command.insert(1, serial) command.insert(1, '-s') def main(): parser = optparse.OptionParser() parser.add_option('-o', dest='output_file', help='write HTML to FILE', default='trace.html', metavar='FILE') parser.add_option('-t', '--time', dest='trace_time', type='int', help='trace for N seconds', metavar='N') parser.add_option('-b', '--buf-size', dest='trace_buf_size', type='int', help='use a trace buffer size of N KB', metavar='N') parser.add_option('-d', '--disk', dest='trace_disk', default=False, action='store_true', help='trace disk I/O (requires root)') parser.add_option('-f', '--cpu-freq', dest='trace_cpu_freq', default=False, action='store_true', help='trace CPU frequency changes') parser.add_option('-i', '--cpu-idle', dest='trace_cpu_idle', default=False, action='store_true', help='trace CPU idle events') parser.add_option('-l', '--cpu-load', dest='trace_cpu_load', default=False, action='store_true', help='trace CPU load') parser.add_option('-s', '--no-cpu-sched', dest='trace_cpu_sched', default=True, action='store_false', help='inhibit tracing CPU ' + 'scheduler (allows longer trace times by reducing data ' + 'rate into buffer)') parser.add_option('-u', '--bus-utilization', dest='trace_bus_utilization', default=False, action='store_true', help='trace bus utilization (requires root)') parser.add_option('-w', '--workqueue', dest='trace_workqueue', default=False, action='store_true', help='trace the kernel workqueues ' + '(requires root)') parser.add_option('--set-tags', dest='set_tags', action='store', help='set the enabled trace tags and exit; set to a ' + 'comma separated list of: ' + ', '.join(trace_tag_bits.iterkeys())) parser.add_option('--link-assets', dest='link_assets', default=False, action='store_true', help='link to original CSS or JS resources ' 'instead of embedding them') parser.add_option('--from-file', dest='from_file', action='store', help='read the trace from a file rather than running a live trace') parser.add_option('--asset-dir', dest='asset_dir', default='trace-viewer', type='string', help='') parser.add_option('-e', '--serial', dest='device_serial', type='string', help='adb device serial number') options, args = parser.parse_args() if options.set_tags: flags = 0 tags = options.set_tags.split(',') for tag in tags: try: flags |= trace_tag_bits[tag] except KeyError: parser.error('unrecognized tag: %s\nknown tags are: %s' % (tag, ', '.join(trace_tag_bits.iterkeys()))) atrace_args = ['adb', 'shell', 'setprop', 'debug.atrace.tags.enableflags', hex(flags)] add_adb_serial(atrace_args, options.device_serial) try: subprocess.check_call(atrace_args) except subprocess.CalledProcessError, e: print >> sys.stderr, 'unable to set tags: %s' % e print '\nSet enabled tags to: %s\n' % ', '.join(tags) print('You will likely need to restart the Android framework for this to ' + 'take effect:\n\n adb shell stop\n adb shell ' + 'start\n') return atrace_args = ['adb', 'shell', 'atrace', '-z'] add_adb_serial(atrace_args, options.device_serial) if options.trace_disk: atrace_args.append('-d') if options.trace_cpu_freq: atrace_args.append('-f') if options.trace_cpu_idle: atrace_args.append('-i') if options.trace_cpu_load: atrace_args.append('-l') if options.trace_cpu_sched: atrace_args.append('-s') if options.trace_bus_utilization: atrace_args.append('-u') if options.trace_workqueue: atrace_args.append('-w') if options.trace_time is not None: if options.trace_time > 0: atrace_args.extend(['-t', str(options.trace_time)]) else: parser.error('the trace time must be a positive number') if options.trace_buf_size is not None: if options.trace_buf_size > 0: atrace_args.extend(['-b', str(options.trace_buf_size)]) else: parser.error('the trace buffer size must be a positive number') if options.from_file is not None: atrace_args = ['cat', options.from_file] script_dir = os.path.dirname(os.path.abspath(sys.argv[0])) if options.link_assets: src_dir = os.path.join(script_dir, options.asset_dir, 'src') build_dir = os.path.join(script_dir, options.asset_dir, 'build') js_files, js_flattenizer, css_files, templates = get_assets(src_dir, build_dir) css = '\n'.join(linked_css_tag % (os.path.join(src_dir, f)) for f in css_files) js = '\n' % js_flattenizer js += '\n'.join(linked_js_tag % (os.path.join(src_dir, f)) for f in js_files) else: css_filename = os.path.join(script_dir, flattened_css_file) js_filename = os.path.join(script_dir, flattened_js_file) css = compiled_css_tag % (open(css_filename).read()) js = compiled_js_tag % (open(js_filename).read()) templates = '' html_filename = options.output_file trace_started = False leftovers = '' adb = subprocess.Popen(atrace_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) dec = zlib.decompressobj() while True: ready = select.select([adb.stdout, adb.stderr], [], [adb.stdout, adb.stderr]) if adb.stderr in ready[0]: err = os.read(adb.stderr.fileno(), 4096) sys.stderr.write(err) sys.stderr.flush() if adb.stdout in ready[0]: out = leftovers + os.read(adb.stdout.fileno(), 4096) if options.from_file is None: out = out.replace('\r\n', '\n') if out.endswith('\r'): out = out[:-1] leftovers = '\r' else: leftovers = '' if not trace_started: lines = out.splitlines(True) out = '' for i, line in enumerate(lines): if line == 'TRACE:\n': sys.stdout.write("downloading trace...") sys.stdout.flush() out = ''.join(lines[i + 1:]) html_prefix = read_asset(script_dir, 'prefix.html') html_file = open(html_filename, 'w') html_file.write(html_prefix % (css, js, templates)) trace_started = True break elif 'TRACE:'.startswith(line) and i == len(lines) - 1: leftovers = line + leftovers else: sys.stdout.write(line) sys.stdout.flush() if len(out) > 0: out = dec.decompress(out) html_out = out.replace('\n', '\\n\\\n') if len(html_out) > 0: html_file.write(html_out) result = adb.poll() if result is not None: break if result != 0: print >> sys.stderr, 'adb returned error code %d' % result elif trace_started: html_out = dec.flush().replace('\n', '\\n\\\n').replace('\r', '') if len(html_out) > 0: html_file.write(html_out) html_suffix = read_asset(script_dir, 'suffix.html') html_file.write(html_suffix) html_file.close() print " done\n\n wrote file://%s\n" % (os.path.abspath(options.output_file)) else: print >> sys.stderr, ('An error occured while capturing the trace. Output ' + 'file was not written.') def read_asset(src_dir, filename): return open(os.path.join(src_dir, filename)).read() def get_assets(src_dir, build_dir): sys.path.append(build_dir) gen = __import__('generate_standalone_timeline_view', {}, {}) parse_deps = __import__('parse_deps', {}, {}) gen_templates = __import__('generate_template_contents', {}, {}) filenames = gen._get_input_filenames() load_sequence = parse_deps.calc_load_sequence(filenames, src_dir) js_files = [] js_flattenizer = "window.FLATTENED = {};\n" js_flattenizer += "window.FLATTENED_RAW_SCRIPTS = {};\n" css_files = [] for module in load_sequence: js_files.append(os.path.relpath(module.filename, src_dir)) js_flattenizer += "window.FLATTENED['%s'] = true;\n" % module.name for dependent_raw_script_name in module.dependent_raw_script_names: js_flattenizer += ( "window.FLATTENED_RAW_SCRIPTS['%s'] = true;\n" % dependent_raw_script_name) for style_sheet in module.style_sheets: css_files.append(os.path.relpath(style_sheet.filename, src_dir)) templates = gen_templates.generate_templates() sys.path.pop() return (js_files, js_flattenizer, css_files, templates) compiled_css_tag = """""" compiled_js_tag = """""" linked_css_tag = """""" linked_js_tag = """""" if __name__ == '__main__': main() ================================================ FILE: tools/adb/mac/systrace/systrace.py ================================================ #!/usr/bin/env python # Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Android system-wide tracing utility. This is a tool for capturing a trace that includes data from both userland and the kernel. It creates an HTML file for visualizing the trace. """ import optparse import os import re import select import subprocess import sys import zlib flattened_css_file = 'style.css' flattened_js_file = 'script.js' class OptionParserIgnoreErrors(optparse.OptionParser): def error(self, msg): pass def exit(self): pass def print_usage(self): pass def print_help(self): pass def print_version(self): pass def get_device_sdk_version(): getprop_args = ['adb', 'shell', 'getprop', 'ro.build.version.sdk'] parser = OptionParserIgnoreErrors() parser.add_option('-e', '--serial', dest='device_serial', type='string') options, args = parser.parse_args() if options.device_serial is not None: getprop_args[1:1] = ['-s', options.device_serial] adb = subprocess.Popen(getprop_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = adb.communicate() if adb.returncode != 0: print >> sys.stderr, 'Error querying device SDK-version:' print >> sys.stderr, err sys.exit(1) version = int(out) return version def add_adb_serial(command, serial): if serial is not None: command.insert(1, serial) command.insert(1, '-s') def main(): device_sdk_version = get_device_sdk_version() if device_sdk_version < 18: legacy_script = os.path.join(os.path.dirname(sys.argv[0]), 'systrace-legacy.py') os.execv(legacy_script, sys.argv) usage = "Usage: %prog [options] [category1 [category2 ...]]" desc = "Example: %prog -b 32768 -t 15 gfx input view sched freq" parser = optparse.OptionParser(usage=usage, description=desc) parser.add_option('-o', dest='output_file', help='write HTML to FILE', default='trace.html', metavar='FILE') parser.add_option('-t', '--time', dest='trace_time', type='int', help='trace for N seconds', metavar='N') parser.add_option('-b', '--buf-size', dest='trace_buf_size', type='int', help='use a trace buffer size of N KB', metavar='N') parser.add_option('-k', '--ktrace', dest='kfuncs', action='store', help='specify a comma-separated list of kernel functions to trace') parser.add_option('-l', '--list-categories', dest='list_categories', default=False, action='store_true', help='list the available categories and exit') parser.add_option('-a', '--app', dest='app_name', default=None, type='string', action='store', help='enable application-level tracing for comma-separated ' + 'list of app cmdlines') parser.add_option('--no-fix-threads', dest='fix_threads', default=True, action='store_false', help='don\'t fix missing or truncated thread names') parser.add_option('--link-assets', dest='link_assets', default=False, action='store_true', help='link to original CSS or JS resources ' 'instead of embedding them') parser.add_option('--from-file', dest='from_file', action='store', help='read the trace from a file (compressed) rather than running a live trace') parser.add_option('--asset-dir', dest='asset_dir', default='trace-viewer', type='string', help='') parser.add_option('-e', '--serial', dest='device_serial', type='string', help='adb device serial number') options, args = parser.parse_args() if options.list_categories: atrace_args = ['adb', 'shell', 'atrace', '--list_categories'] expect_trace = False elif options.from_file is not None: atrace_args = ['cat', options.from_file] expect_trace = True else: atrace_args = ['adb', 'shell', 'atrace', '-z'] expect_trace = True if options.trace_time is not None: if options.trace_time > 0: atrace_args.extend(['-t', str(options.trace_time)]) else: parser.error('the trace time must be a positive number') if options.trace_buf_size is not None: if options.trace_buf_size > 0: atrace_args.extend(['-b', str(options.trace_buf_size)]) else: parser.error('the trace buffer size must be a positive number') if options.app_name is not None: atrace_args.extend(['-a', options.app_name]) if options.kfuncs is not None: atrace_args.extend(['-k', options.kfuncs]) atrace_args.extend(args) if options.fix_threads: atrace_args.extend([';', 'ps', '-t']) if atrace_args[0] == 'adb': add_adb_serial(atrace_args, options.device_serial) script_dir = os.path.dirname(os.path.abspath(sys.argv[0])) if options.link_assets: src_dir = os.path.join(script_dir, options.asset_dir, 'src') build_dir = os.path.join(script_dir, options.asset_dir, 'build') js_files, js_flattenizer, css_files, templates = get_assets(src_dir, build_dir) css = '\n'.join(linked_css_tag % (os.path.join(src_dir, f)) for f in css_files) js = '\n' % js_flattenizer js += '\n'.join(linked_js_tag % (os.path.join(src_dir, f)) for f in js_files) else: css_filename = os.path.join(script_dir, flattened_css_file) js_filename = os.path.join(script_dir, flattened_js_file) css = compiled_css_tag % (open(css_filename).read()) js = compiled_js_tag % (open(js_filename).read()) templates = '' html_filename = options.output_file adb = subprocess.Popen(atrace_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) result = None data = [] # Read the text portion of the output and watch for the 'TRACE:' marker that # indicates the start of the trace data. while result is None: ready = select.select([adb.stdout, adb.stderr], [], [adb.stdout, adb.stderr]) if adb.stderr in ready[0]: err = os.read(adb.stderr.fileno(), 4096) sys.stderr.write(err) sys.stderr.flush() if adb.stdout in ready[0]: out = os.read(adb.stdout.fileno(), 4096) parts = out.split('\nTRACE:', 1) txt = parts[0].replace('\r', '') if len(parts) == 2: # The '\nTRACE:' match stole the last newline from the text, so add it # back here. txt += '\n' sys.stdout.write(txt) sys.stdout.flush() if len(parts) == 2: data.append(parts[1]) sys.stdout.write("downloading trace...") sys.stdout.flush() break result = adb.poll() # Read and buffer the data portion of the output. while True: ready = select.select([adb.stdout, adb.stderr], [], [adb.stdout, adb.stderr]) keepReading = False if adb.stderr in ready[0]: err = os.read(adb.stderr.fileno(), 4096) if len(err) > 0: keepReading = True sys.stderr.write(err) sys.stderr.flush() if adb.stdout in ready[0]: out = os.read(adb.stdout.fileno(), 4096) if len(out) > 0: keepReading = True data.append(out) if result is not None and not keepReading: break result = adb.poll() if result == 0: if expect_trace: data = ''.join(data) # Collapse CRLFs that are added by adb shell. if data.startswith('\r\n'): data = data.replace('\r\n', '\n') # Skip the initial newline. data = data[1:] if not data: print >> sys.stderr, ('No data was captured. Output file was not ' + 'written.') sys.exit(1) else: # Indicate to the user that the data download is complete. print " done\n" # Extract the thread list dumped by ps. threads = {} if options.fix_threads: parts = data.split('USER PID PPID VSIZE RSS WCHAN PC NAME', 1) if len(parts) == 2: data = parts[0] for line in parts[1].splitlines(): cols = line.split(None, 8) if len(cols) == 9: tid = int(cols[1]) name = cols[8] threads[tid] = name # Decompress and preprocess the data. out = zlib.decompress(data) if options.fix_threads: def repl(m): tid = int(m.group(2)) if tid > 0: name = threads.get(tid) if name is None: name = m.group(1) if name == '<...>': name = '<' + str(tid) + '>' threads[tid] = name return name + '-' + m.group(2) else: return m.group(0) out = re.sub(r'^\s*(\S+)-(\d+)', repl, out, flags=re.MULTILINE) html_prefix = read_asset(script_dir, 'prefix.html') html_suffix = read_asset(script_dir, 'suffix.html') html_file = open(html_filename, 'w') html_file.write(html_prefix % (css, js, templates)) html_out = out.replace('\n', '\\n\\\n') html_file.write(html_out) html_file.write(html_suffix) html_file.close() print "\n wrote file://%s\n" % os.path.abspath(options.output_file) else: # i.e. result != 0 print >> sys.stderr, 'adb returned error code %d' % result sys.exit(1) def read_asset(src_dir, filename): return open(os.path.join(src_dir, filename)).read() def get_assets(src_dir, build_dir): sys.path.append(build_dir) gen = __import__('generate_standalone_timeline_view', {}, {}) parse_deps = __import__('parse_deps', {}, {}) gen_templates = __import__('generate_template_contents', {}, {}) filenames = gen._get_input_filenames() load_sequence = parse_deps.calc_load_sequence(filenames, src_dir) js_files = [] js_flattenizer = "window.FLATTENED = {};\n" js_flattenizer += "window.FLATTENED_RAW_SCRIPTS = {};\n" css_files = [] for module in load_sequence: js_files.append(os.path.relpath(module.filename, src_dir)) js_flattenizer += "window.FLATTENED['%s'] = true;\n" % module.name for dependent_raw_script_name in module.dependent_raw_script_names: js_flattenizer += ( "window.FLATTENED_RAW_SCRIPTS['%s'] = true;\n" % dependent_raw_script_name) for style_sheet in module.style_sheets: css_files.append(os.path.relpath(style_sheet.filename, src_dir)) templates = gen_templates.generate_templates() sys.path.pop() return (js_files, js_flattenizer, css_files, templates) compiled_css_tag = """""" compiled_js_tag = """""" linked_css_tag = """""" linked_js_tag = """""" if __name__ == '__main__': main() ================================================ FILE: tools/adb/windows/api/api-versions.xml ================================================ ================================================ FILE: tools/adb/windows/source.properties ================================================ ### Android Tool: Source of this archive. #Sat Nov 15 09:12:50 IST 2014 Archive.HostOs=windows Pkg.License=To get started with the Android SDK, you must agree to the following terms and conditions.\n\nThis is the Android SDK License Agreement (the "License Agreement").\n\n1. Introduction\n\n1.1 The Android SDK (referred to in the License Agreement as the "SDK" and specifically including the Android system files, packaged APIs, and SDK library files and tools , if and when they are made available) is licensed to you subject to the terms of the License Agreement. The License Agreement forms a legally binding contract between you and Google in relation to your use of the SDK.\n\n1.2 "Android" means the Android software stack for devices, as made available under the Android Open Source Project, which is located at the following URL\: http\://source.android.com/, as updated from time to time.\n\n1.3 "Google" means Google Inc., a Delaware corporation with principal place of business at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States.\n\n2. Accepting the License Agreement\n\n2.1 In order to use the SDK, you must first agree to the License Agreement. You may not use the SDK if you do not accept the License Agreement.\n\n2.2 By clicking to accept and/or using the SDK, you hereby agree to the terms of the License Agreement.\n\n2.3 You may not use the SDK and may not accept the License Agreement if you are a person barred from receiving the SDK under the laws of the United States or other countries including the country in which you are resident or from which you use the SDK.\n\n2.4 If you will use the SDK internally within your company or organization you agree to be bound by the License Agreement on behalf of your employer or other entity, and you represent and warrant that you have full legal authority to bind your employer or such entity to the License Agreement. If you do not have the requisite authority, you may not accept the License Agreement or use the SDK on behalf of your employer or other entity.\n\n3. SDK License from Google\n\n3.1 Subject to the terms of the License Agreement, Google grants you a royalty-free, non-assignable, non-exclusive, non-sublicensable, limited, revocable license to use the SDK, personally or internally within your company or organization, solely to develop and distribute applications to run on the Android platform.\n\n3.2 You agree that Google or third parties own all legal right, title and interest in and to the SDK, including any Intellectual Property Rights that subsist in the SDK. "Intellectual Property Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law, and any and all other proprietary rights. Google reserves all rights not expressly granted to you.\n\n3.3 You may not use the SDK for any purpose not expressly permitted by the License Agreement. Except to the extent required by applicable third party licenses, you may not\: (a) copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the SDK or any part of the SDK; or (b) load any part of the SDK onto a mobile handset or any other hardware device except a personal computer, combine any part of the SDK with other software, or distribute any software or device incorporating a part of the SDK.\n\n3.4 You agree that you will not take any actions that may cause or result in the fragmentation of Android, including but not limited to distributing, participating in the creation of, or promoting in any way a software development kit derived from the SDK.\n\n3.5 Use, reproduction and distribution of components of the SDK licensed under an open source software license are governed solely by the terms of that open source software license and not the License Agreement. You agree to remain a licensee in good standing in regard to such open source software licenses under all the rights granted and to refrain from any actions that may terminate, suspend, or breach such rights.\n\n3.6 You agree that the form and nature of the SDK that Google provides may change without prior notice to you and that future versions of the SDK may be incompatible with applications developed on previous versions of the SDK. You agree that Google may stop (permanently or temporarily) providing the SDK (or any features within the SDK) to you or to users generally at Google's sole discretion, without prior notice to you.\n\n3.7 Nothing in the License Agreement gives you a right to use any of Google's trade names, trademarks, service marks, logos, domain names, or other distinctive brand features.\n\n3.8 You agree that you will not remove, obscure, or alter any proprietary rights notices (including copyright and trademark notices) that may be affixed to or contained within the SDK.\n\n4. Use of the SDK by You\n\n4.1 Google agrees that nothing in the License Agreement gives Google any right, title or interest from you (or your licensors) under the License Agreement in or to any software applications that you develop using the SDK, including any intellectual property rights that subsist in those applications.\n\n4.2 You agree to use the SDK and write applications only for purposes that are permitted by (a) the License Agreement, and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).\n\n4.3 You agree that if you use the SDK to develop applications, you will protect the privacy and legal rights of users. If users provide you with user names, passwords, or other login information or personal information, you must make the users aware that the information will be available to your application, and you must provide legally adequate privacy notice and protection for those users. If your application stores personal or sensitive information provided by users, it must do so securely. If users provide you with Google Account information, your application may only use that information to access the user's Google Account when, and for the limited purposes for which, each user has given you permission to do so.\n\n4.4 You agree that you will not engage in any activity with the SDK, including the development or distribution of an application, that interferes with, disrupts, damages, or accesses in an unauthorized manner the servers, networks, or other properties or services of Google or any third party.\n\n4.5 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any data, content, or resources that you create, transmit or display through Android and/or applications for Android, and for the consequences of your actions (including any loss or damage which Google may suffer) by doing so.\n\n4.6 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any breach of your obligations under the License Agreement, any applicable third party contract or Terms of Service, or any applicable law or regulation, and for the consequences (including any loss or damage which Google or any third party may suffer) of any such breach.\n\n5. Your Developer Credentials\n\n5.1 You agree that you are responsible for maintaining the confidentiality of any developer credentials that may be issued to you by Google or which you may choose yourself and that you will be solely responsible for all applications that are developed under your developer credentials.\n\n6. Privacy and Information\n\n6.1 In order to continually innovate and improve the SDK, Google may collect certain usage statistics from the software including but not limited to a unique identifier, associated IP address, version number of the software, and information on which tools and/or services in the SDK are being used and how they are being used. Before any of this information is collected, the SDK will notify you and seek your consent. If you withhold consent, the information will not be collected.\n\n6.2 The data collected is examined in the aggregate to improve the SDK and is maintained in accordance with Google's Privacy Policy located at http\://www.google.com/policies/privacy/.\n\n7. Third Party Applications\n\n7.1 If you use the SDK to run applications developed by a third party or that access data, content or resources provided by a third party, you agree that Google is not responsible for those applications, data, content, or resources. You understand that all data, content or resources which you may access through such third party applications are the sole responsibility of the person from which they originated and that Google is not liable for any loss or damage that you may experience as a result of the use or access of any of those third party applications, data, content, or resources.\n\n7.2 You should be aware the data, content, and resources presented to you through such a third party application may be protected by intellectual property rights which are owned by the providers (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on these data, content, or resources (either in whole or in part) unless you have been specifically given permission to do so by the relevant owners.\n\n7.3 You acknowledge that your use of such third party applications, data, content, or resources may be subject to separate terms between you and the relevant third party.\n\n8. Using Google APIs\n\n8.1 Google APIs\n\n8.1.1 If you use any API to retrieve data from Google, you acknowledge that the data may be protected by intellectual property rights which are owned by Google or those parties that provide the data (or by other persons or companies on their behalf). Your use of any such API may be subject to additional Terms of Service. You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this data (either in whole or in part) unless allowed by the relevant Terms of Service.\n\n8.1.2 If you use any API to retrieve a user's data from Google, you acknowledge and agree that you shall retrieve data only with the user's explicit consent and only when, and for the limited purposes for which, the user has given you permission to do so.\n\n9. Terminating the License Agreement\n\n9.1 The License Agreement will continue to apply until terminated by either you or Google as set out below.\n\n9.2 If you want to terminate the License Agreement, you may do so by ceasing your use of the SDK and any relevant developer credentials.\n\n9.3 Google may at any time, terminate the License Agreement, with or without cause, upon notice to you.\n\n9.4 The License Agreement will automatically terminate without notice or other action when Google ceases to provide the SDK or certain parts of the SDK to users in the country in which you are resident or from which you use the service.\n\n9.5 When the License Agreement is terminated, the license granted to you in the License Agreement will terminate, you will immediately cease all use of the SDK, and the provisions of paragraphs 10, 11, 12 and 14 shall survive indefinitely.\n\n10. DISCLAIMERS\n\n10.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE SDK IS AT YOUR SOLE RISK AND THAT THE SDK IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND FROM GOOGLE.\n\n10.2 YOUR USE OF THE SDK AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE SDK IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA THAT RESULTS FROM SUCH USE. WITHOUT LIMITING THE FOREGOING, YOU UNDERSTAND THAT THE SDK MAY CONTAIN ERRORS, DEFECTS AND SECURITY VULNERABILITIES THAT CAN RESULT IN SIGNIFICANT DAMAGE, INCLUDING THE COMPLETE, IRRECOVERABLE LOSS OF USE OF YOUR COMPUTER SYSTEM OR OTHER DEVICE.\n\n10.3 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\n\n11. LIMITATION OF LIABILITY\n\n11.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER OR NOT GOOGLE OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.\n\n12. Indemnification\n\n12.1 To the maximum extent permitted by law, you agree to defend, indemnify and hold harmless Google, its affiliates and their respective directors, officers, employees and agents from and against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses (including reasonable attorneys\u2019 fees) arising out of or accruing from (a) your use of the SDK, (b) any application you develop on the SDK that infringes any Intellectual Property Rights of any person or defames any person or violates their rights of publicity or privacy, and (c) any non-compliance by you of the License Agreement.\n\n13. Changes to the License Agreement\n\n13.1 Google may make changes to the License Agreement as it distributes new versions of the SDK. When these changes are made, Google will make a new version of the License Agreement available on the website where the SDK is made available.\n\n14. General Legal Terms\n\n14.1 The License Agreement constitutes the whole legal agreement between you and Google and governs your use of the SDK (excluding any services which Google may provide to you under a separate written agreement), and completely replaces any prior agreements between you and Google in relation to the SDK.\n\n14.2 You agree that if Google does not exercise or enforce any legal right or remedy which is contained in the License Agreement (or which Google has the benefit of under any applicable law), this will not be taken to be a formal waiver of Google's rights and that those rights or remedies will still be available to Google.\n\n14.3 If any court of law, having the jurisdiction to decide on this matter, rules that any provision of the License Agreement is invalid, then that provision will be removed from the License Agreement without affecting the rest of the License Agreement. The remaining provisions of the License Agreement will continue to be valid and enforceable.\n\n14.4 You acknowledge and agree that each member of the group of companies of which Google is the parent shall be third party beneficiaries to the License Agreement and that such other companies shall be entitled to directly enforce, and rely upon, any provision of the License Agreement that confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to the License Agreement.\n\n14.5 EXPORT RESTRICTIONS. THE SDK IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS. YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND REGULATIONS THAT APPLY TO THE SDK. THESE LAWS INCLUDE RESTRICTIONS ON DESTINATIONS, END USERS AND END USE.\n\n14.6 The License Agreement may not be assigned or transferred by you without the prior written approval of Google, and any attempted assignment without such approval will be void. You shall not delegate your responsibilities or obligations under the License Agreement without the prior written approval of Google.\n\n14.7 The License Agreement, and your relationship with Google under the License Agreement, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from the License Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.\n\nJune 2014.\n Pkg.LicenseRef=android-sdk-license Pkg.Revision=21 Pkg.SourceUrl=https\://dl-ssl.google.com/android/repository/repository-10.xml ================================================ FILE: tools/adb/windows/systrace/AUTHORS ================================================ # Names should be added to this file with this pattern: # # For individuals: # Name # # For organizations: # Organization # # See python fnmatch module documentation for more information. The Chromium Authors <*@chromium.org> Google Inc. <*@google.com> ================================================ FILE: tools/adb/windows/systrace/LICENSE ================================================ // Copyright (c) 2010 The Chromium Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: tools/adb/windows/systrace/NOTICE ================================================ // Copyright (c) 2012 The Chromium Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS ================================================ FILE: tools/adb/windows/systrace/UPSTREAM_REVISION ================================================ 775 ================================================ FILE: tools/adb/windows/systrace/prefix.html ================================================ Android System Trace %s %s
%s
< / html >; ================================================ FILE: tools/adb/windows/systrace/systrace-legacy.py ================================================ #!/usr/bin/env python # Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Android system-wide tracing utility. This is a tool for capturing a trace that includes data from both userland and the kernel. It creates an HTML file for visualizing the trace. """ import optparse import os import select import subprocess import sys import zlib # This list is based on the tags in frameworks/native/include/utils/Trace.h. trace_tag_bits = { 'gfx': 1 << 1, 'input': 1 << 2, 'view': 1 << 3, 'webview': 1 << 4, 'wm': 1 << 5, 'am': 1 << 6, 'sync': 1 << 7, 'audio': 1 << 8, 'video': 1 << 9, 'camera': 1 << 10, } flattened_css_file = 'style.css' flattened_js_file = 'script.js' def add_adb_serial(command, serial): if serial != None: command.insert(1, serial) command.insert(1, '-s') def main(): parser = optparse.OptionParser() parser.add_option('-o', dest='output_file', help='write HTML to FILE', default='trace.html', metavar='FILE') parser.add_option('-t', '--time', dest='trace_time', type='int', help='trace for N seconds', metavar='N') parser.add_option('-b', '--buf-size', dest='trace_buf_size', type='int', help='use a trace buffer size of N KB', metavar='N') parser.add_option('-d', '--disk', dest='trace_disk', default=False, action='store_true', help='trace disk I/O (requires root)') parser.add_option('-f', '--cpu-freq', dest='trace_cpu_freq', default=False, action='store_true', help='trace CPU frequency changes') parser.add_option('-i', '--cpu-idle', dest='trace_cpu_idle', default=False, action='store_true', help='trace CPU idle events') parser.add_option('-l', '--cpu-load', dest='trace_cpu_load', default=False, action='store_true', help='trace CPU load') parser.add_option('-s', '--no-cpu-sched', dest='trace_cpu_sched', default=True, action='store_false', help='inhibit tracing CPU ' + 'scheduler (allows longer trace times by reducing data ' + 'rate into buffer)') parser.add_option('-u', '--bus-utilization', dest='trace_bus_utilization', default=False, action='store_true', help='trace bus utilization (requires root)') parser.add_option('-w', '--workqueue', dest='trace_workqueue', default=False, action='store_true', help='trace the kernel workqueues ' + '(requires root)') parser.add_option('--set-tags', dest='set_tags', action='store', help='set the enabled trace tags and exit; set to a ' + 'comma separated list of: ' + ', '.join(trace_tag_bits.iterkeys())) parser.add_option('--link-assets', dest='link_assets', default=False, action='store_true', help='link to original CSS or JS resources ' 'instead of embedding them') parser.add_option('--from-file', dest='from_file', action='store', help='read the trace from a file rather than running a live trace') parser.add_option('--asset-dir', dest='asset_dir', default='trace-viewer', type='string', help='') parser.add_option('-e', '--serial', dest='device_serial', type='string', help='adb device serial number') options, args = parser.parse_args() if options.set_tags: flags = 0 tags = options.set_tags.split(',') for tag in tags: try: flags |= trace_tag_bits[tag] except KeyError: parser.error('unrecognized tag: %s\nknown tags are: %s' % (tag, ', '.join(trace_tag_bits.iterkeys()))) atrace_args = ['adb', 'shell', 'setprop', 'debug.atrace.tags.enableflags', hex(flags)] add_adb_serial(atrace_args, options.device_serial) try: subprocess.check_call(atrace_args) except subprocess.CalledProcessError, e: print >> sys.stderr, 'unable to set tags: %s' % e print '\nSet enabled tags to: %s\n' % ', '.join(tags) print('You will likely need to restart the Android framework for this to ' + 'take effect:\n\n adb shell stop\n adb shell ' + 'start\n') return atrace_args = ['adb', 'shell', 'atrace', '-z'] add_adb_serial(atrace_args, options.device_serial) if options.trace_disk: atrace_args.append('-d') if options.trace_cpu_freq: atrace_args.append('-f') if options.trace_cpu_idle: atrace_args.append('-i') if options.trace_cpu_load: atrace_args.append('-l') if options.trace_cpu_sched: atrace_args.append('-s') if options.trace_bus_utilization: atrace_args.append('-u') if options.trace_workqueue: atrace_args.append('-w') if options.trace_time is not None: if options.trace_time > 0: atrace_args.extend(['-t', str(options.trace_time)]) else: parser.error('the trace time must be a positive number') if options.trace_buf_size is not None: if options.trace_buf_size > 0: atrace_args.extend(['-b', str(options.trace_buf_size)]) else: parser.error('the trace buffer size must be a positive number') if options.from_file is not None: atrace_args = ['cat', options.from_file] script_dir = os.path.dirname(os.path.abspath(sys.argv[0])) if options.link_assets: src_dir = os.path.join(script_dir, options.asset_dir, 'src') build_dir = os.path.join(script_dir, options.asset_dir, 'build') js_files, js_flattenizer, css_files, templates = get_assets(src_dir, build_dir) css = '\n'.join(linked_css_tag % (os.path.join(src_dir, f)) for f in css_files) js = '\n' % js_flattenizer js += '\n'.join(linked_js_tag % (os.path.join(src_dir, f)) for f in js_files) else: css_filename = os.path.join(script_dir, flattened_css_file) js_filename = os.path.join(script_dir, flattened_js_file) css = compiled_css_tag % (open(css_filename).read()) js = compiled_js_tag % (open(js_filename).read()) templates = '' html_filename = options.output_file trace_started = False leftovers = '' adb = subprocess.Popen(atrace_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) dec = zlib.decompressobj() while True: ready = select.select([adb.stdout, adb.stderr], [], [adb.stdout, adb.stderr]) if adb.stderr in ready[0]: err = os.read(adb.stderr.fileno(), 4096) sys.stderr.write(err) sys.stderr.flush() if adb.stdout in ready[0]: out = leftovers + os.read(adb.stdout.fileno(), 4096) if options.from_file is None: out = out.replace('\r\n', '\n') if out.endswith('\r'): out = out[:-1] leftovers = '\r' else: leftovers = '' if not trace_started: lines = out.splitlines(True) out = '' for i, line in enumerate(lines): if line == 'TRACE:\n': sys.stdout.write("downloading trace...") sys.stdout.flush() out = ''.join(lines[i + 1:]) html_prefix = read_asset(script_dir, 'prefix.html') html_file = open(html_filename, 'w') html_file.write(html_prefix % (css, js, templates)) trace_started = True break elif 'TRACE:'.startswith(line) and i == len(lines) - 1: leftovers = line + leftovers else: sys.stdout.write(line) sys.stdout.flush() if len(out) > 0: out = dec.decompress(out) html_out = out.replace('\n', '\\n\\\n') if len(html_out) > 0: html_file.write(html_out) result = adb.poll() if result is not None: break if result != 0: print >> sys.stderr, 'adb returned error code %d' % result elif trace_started: html_out = dec.flush().replace('\n', '\\n\\\n').replace('\r', '') if len(html_out) > 0: html_file.write(html_out) html_suffix = read_asset(script_dir, 'suffix.html') html_file.write(html_suffix) html_file.close() print " done\n\n wrote file://%s\n" % (os.path.abspath(options.output_file)) else: print >> sys.stderr, ('An error occured while capturing the trace. Output ' + 'file was not written.') def read_asset(src_dir, filename): return open(os.path.join(src_dir, filename)).read() def get_assets(src_dir, build_dir): sys.path.append(build_dir) gen = __import__('generate_standalone_timeline_view', {}, {}) parse_deps = __import__('parse_deps', {}, {}) gen_templates = __import__('generate_template_contents', {}, {}) filenames = gen._get_input_filenames() load_sequence = parse_deps.calc_load_sequence(filenames, src_dir) js_files = [] js_flattenizer = "window.FLATTENED = {};\n" js_flattenizer += "window.FLATTENED_RAW_SCRIPTS = {};\n" css_files = [] for module in load_sequence: js_files.append(os.path.relpath(module.filename, src_dir)) js_flattenizer += "window.FLATTENED['%s'] = true;\n" % module.name for dependent_raw_script_name in module.dependent_raw_script_names: js_flattenizer += ( "window.FLATTENED_RAW_SCRIPTS['%s'] = true;\n" % dependent_raw_script_name) for style_sheet in module.style_sheets: css_files.append(os.path.relpath(style_sheet.filename, src_dir)) templates = gen_templates.generate_templates() sys.path.pop() return (js_files, js_flattenizer, css_files, templates) compiled_css_tag = """""" compiled_js_tag = """""" linked_css_tag = """""" linked_js_tag = """""" if __name__ == '__main__': main() ================================================ FILE: tools/adb/windows/systrace/systrace.py ================================================ #!/usr/bin/env python # Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Android system-wide tracing utility. This is a tool for capturing a trace that includes data from both userland and the kernel. It creates an HTML file for visualizing the trace. """ import optparse import os import re import select import subprocess import sys import zlib flattened_css_file = 'style.css' flattened_js_file = 'script.js' class OptionParserIgnoreErrors(optparse.OptionParser): def error(self, msg): pass def exit(self): pass def print_usage(self): pass def print_help(self): pass def print_version(self): pass def get_device_sdk_version(): getprop_args = ['adb', 'shell', 'getprop', 'ro.build.version.sdk'] parser = OptionParserIgnoreErrors() parser.add_option('-e', '--serial', dest='device_serial', type='string') options, args = parser.parse_args() if options.device_serial is not None: getprop_args[1:1] = ['-s', options.device_serial] adb = subprocess.Popen(getprop_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = adb.communicate() if adb.returncode != 0: print >> sys.stderr, 'Error querying device SDK-version:' print >> sys.stderr, err sys.exit(1) version = int(out) return version def add_adb_serial(command, serial): if serial is not None: command.insert(1, serial) command.insert(1, '-s') def main(): device_sdk_version = get_device_sdk_version() if device_sdk_version < 18: legacy_script = os.path.join(os.path.dirname(sys.argv[0]), 'systrace-legacy.py') os.execv(legacy_script, sys.argv) usage = "Usage: %prog [options] [category1 [category2 ...]]" desc = "Example: %prog -b 32768 -t 15 gfx input view sched freq" parser = optparse.OptionParser(usage=usage, description=desc) parser.add_option('-o', dest='output_file', help='write HTML to FILE', default='trace.html', metavar='FILE') parser.add_option('-t', '--time', dest='trace_time', type='int', help='trace for N seconds', metavar='N') parser.add_option('-b', '--buf-size', dest='trace_buf_size', type='int', help='use a trace buffer size of N KB', metavar='N') parser.add_option('-k', '--ktrace', dest='kfuncs', action='store', help='specify a comma-separated list of kernel functions to trace') parser.add_option('-l', '--list-categories', dest='list_categories', default=False, action='store_true', help='list the available categories and exit') parser.add_option('-a', '--app', dest='app_name', default=None, type='string', action='store', help='enable application-level tracing for comma-separated ' + 'list of app cmdlines') parser.add_option('--no-fix-threads', dest='fix_threads', default=True, action='store_false', help='don\'t fix missing or truncated thread names') parser.add_option('--link-assets', dest='link_assets', default=False, action='store_true', help='link to original CSS or JS resources ' 'instead of embedding them') parser.add_option('--from-file', dest='from_file', action='store', help='read the trace from a file (compressed) rather than running a live trace') parser.add_option('--asset-dir', dest='asset_dir', default='trace-viewer', type='string', help='') parser.add_option('-e', '--serial', dest='device_serial', type='string', help='adb device serial number') options, args = parser.parse_args() if options.list_categories: atrace_args = ['adb', 'shell', 'atrace', '--list_categories'] expect_trace = False elif options.from_file is not None: atrace_args = ['cat', options.from_file] expect_trace = True else: atrace_args = ['adb', 'shell', 'atrace', '-z'] expect_trace = True if options.trace_time is not None: if options.trace_time > 0: atrace_args.extend(['-t', str(options.trace_time)]) else: parser.error('the trace time must be a positive number') if options.trace_buf_size is not None: if options.trace_buf_size > 0: atrace_args.extend(['-b', str(options.trace_buf_size)]) else: parser.error('the trace buffer size must be a positive number') if options.app_name is not None: atrace_args.extend(['-a', options.app_name]) if options.kfuncs is not None: atrace_args.extend(['-k', options.kfuncs]) atrace_args.extend(args) if options.fix_threads: atrace_args.extend([';', 'ps', '-t']) if atrace_args[0] == 'adb': add_adb_serial(atrace_args, options.device_serial) script_dir = os.path.dirname(os.path.abspath(sys.argv[0])) if options.link_assets: src_dir = os.path.join(script_dir, options.asset_dir, 'src') build_dir = os.path.join(script_dir, options.asset_dir, 'build') js_files, js_flattenizer, css_files, templates = get_assets(src_dir, build_dir) css = '\n'.join(linked_css_tag % (os.path.join(src_dir, f)) for f in css_files) js = '\n' % js_flattenizer js += '\n'.join(linked_js_tag % (os.path.join(src_dir, f)) for f in js_files) else: css_filename = os.path.join(script_dir, flattened_css_file) js_filename = os.path.join(script_dir, flattened_js_file) css = compiled_css_tag % (open(css_filename).read()) js = compiled_js_tag % (open(js_filename).read()) templates = '' html_filename = options.output_file adb = subprocess.Popen(atrace_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) result = None data = [] # Read the text portion of the output and watch for the 'TRACE:' marker that # indicates the start of the trace data. while result is None: ready = select.select([adb.stdout, adb.stderr], [], [adb.stdout, adb.stderr]) if adb.stderr in ready[0]: err = os.read(adb.stderr.fileno(), 4096) sys.stderr.write(err) sys.stderr.flush() if adb.stdout in ready[0]: out = os.read(adb.stdout.fileno(), 4096) parts = out.split('\nTRACE:', 1) txt = parts[0].replace('\r', '') if len(parts) == 2: # The '\nTRACE:' match stole the last newline from the text, so add it # back here. txt += '\n' sys.stdout.write(txt) sys.stdout.flush() if len(parts) == 2: data.append(parts[1]) sys.stdout.write("downloading trace...") sys.stdout.flush() break result = adb.poll() # Read and buffer the data portion of the output. while True: ready = select.select([adb.stdout, adb.stderr], [], [adb.stdout, adb.stderr]) keepReading = False if adb.stderr in ready[0]: err = os.read(adb.stderr.fileno(), 4096) if len(err) > 0: keepReading = True sys.stderr.write(err) sys.stderr.flush() if adb.stdout in ready[0]: out = os.read(adb.stdout.fileno(), 4096) if len(out) > 0: keepReading = True data.append(out) if result is not None and not keepReading: break result = adb.poll() if result == 0: if expect_trace: data = ''.join(data) # Collapse CRLFs that are added by adb shell. if data.startswith('\r\n'): data = data.replace('\r\n', '\n') # Skip the initial newline. data = data[1:] if not data: print >> sys.stderr, ('No data was captured. Output file was not ' + 'written.') sys.exit(1) else: # Indicate to the user that the data download is complete. print " done\n" # Extract the thread list dumped by ps. threads = {} if options.fix_threads: parts = data.split('USER PID PPID VSIZE RSS WCHAN PC NAME', 1) if len(parts) == 2: data = parts[0] for line in parts[1].splitlines(): cols = line.split(None, 8) if len(cols) == 9: tid = int(cols[1]) name = cols[8] threads[tid] = name # Decompress and preprocess the data. out = zlib.decompress(data) if options.fix_threads: def repl(m): tid = int(m.group(2)) if tid > 0: name = threads.get(tid) if name is None: name = m.group(1) if name == '<...>': name = '<' + str(tid) + '>' threads[tid] = name return name + '-' + m.group(2) else: return m.group(0) out = re.sub(r'^\s*(\S+)-(\d+)', repl, out, flags=re.MULTILINE) html_prefix = read_asset(script_dir, 'prefix.html') html_suffix = read_asset(script_dir, 'suffix.html') html_file = open(html_filename, 'w') html_file.write(html_prefix % (css, js, templates)) html_out = out.replace('\n', '\\n\\\n') html_file.write(html_out) html_file.write(html_suffix) html_file.close() print "\n wrote file://%s\n" % os.path.abspath(options.output_file) else: # i.e. result != 0 print >> sys.stderr, 'adb returned error code %d' % result sys.exit(1) def read_asset(src_dir, filename): return open(os.path.join(src_dir, filename)).read() def get_assets(src_dir, build_dir): sys.path.append(build_dir) gen = __import__('generate_standalone_timeline_view', {}, {}) parse_deps = __import__('parse_deps', {}, {}) gen_templates = __import__('generate_template_contents', {}, {}) filenames = gen._get_input_filenames() load_sequence = parse_deps.calc_load_sequence(filenames, src_dir) js_files = [] js_flattenizer = "window.FLATTENED = {};\n" js_flattenizer += "window.FLATTENED_RAW_SCRIPTS = {};\n" css_files = [] for module in load_sequence: js_files.append(os.path.relpath(module.filename, src_dir)) js_flattenizer += "window.FLATTENED['%s'] = true;\n" % module.name for dependent_raw_script_name in module.dependent_raw_script_names: js_flattenizer += ( "window.FLATTENED_RAW_SCRIPTS['%s'] = true;\n" % dependent_raw_script_name) for style_sheet in module.style_sheets: css_files.append(os.path.relpath(style_sheet.filename, src_dir)) templates = gen_templates.generate_templates() sys.path.pop() return (js_files, js_flattenizer, css_files, templates) compiled_css_tag = """""" compiled_js_tag = """""" linked_css_tag = """""" linked_js_tag = """""" if __name__ == '__main__': main() ================================================ FILE: update-info.txt ================================================ 2019-12-30 v1.0.1 1.更新部分script规则 2.更新支持输入文件为相对路径 3.更新url展示,过滤其中相同url地址 4.添加部分工具,如adb/dex2jar等工具 ================================================ FILE: utils/__init__.py ================================================ # coding: utf-8 __author__ = 'deff' ================================================ FILE: utils/fileutils.py ================================================ # coding: utf-8 import shutil __author__ = 'deff' import os class FileUtils: def __init__(self): pass @staticmethod def is_file_exit(file_path): return os.path.exists(file_path) @staticmethod def is_dir_exit(dir_path): return os.path.isdir(dir_path) and os.path.exists(dir_path) @staticmethod def is_dir_empty(dir_path): if not FileUtils.is_dir_exit(dir_path): return False return len(os.listdir(dir_path)) == 0 # 创建多级目录,比如c:\\test1\\test2,如果test1 test2都不存在,都将被创建 @staticmethod def create_dir(to_create_path): dirs = to_create_path.split(os.sep) path = '' for di in dirs: di += os.sep path = os.path.join(path, di) if not os.path.exists(path): os.mkdir(path, 0o777) @staticmethod def delete_file(to_del_file): if os.path.exists(to_del_file): os.remove(to_del_file) @staticmethod def delete_dirs(to_del_dirs): if os.path.exists(to_del_dirs): shutil.rmtree(to_del_dirs) ================================================ FILE: utils/manager.py ================================================ # coding: utf-8 import os import shutil import subprocess import logging import time import zipfile from config import config from scanner.dynamic import DynamicScanner from scanner.static import StaticScanner from utils.sdkinfo import sdkinfo from utils.ziputils import ZipUtils from utils.fileutils import FileUtils __author__ = 'deff' class Manager: def __init__(self, sdk_path): self.sdk_path = sdk_path # 时间命名 self.result_dir_name = time.strftime("%Y%m%d-%H-%M-%S") # 初始化地址和log self._init_path() self._init_log() self.report = "" def start(self): # 准备工作,解压反编译 logging.info("start sdk scan..") if not FileUtils.is_file_exit(self.sdk_path): logging.error("sdk文件不存在") return pix = os.path.splitext(self.sdk_path)[1] if not pix == '.aar' and not pix == '.jar': logging.error("sdk文件格式错误") return sdkinfo.sdk_path = self.sdk_path is_aar = pix == '.aar' if is_aar: logging.info("start unzip..") if not ZipUtils.unzip(sdkinfo.sdk_path, config.unzip_path): logging.error("unzip error") return config.jar_path = os.path.join(config.unzip_path, "classes.jar") config.res_path = os.path.join(config.unzip_path, "res") config.xml_path = os.path.join(config.unzip_path, "AndroidManifest.xml") config.jni_path = os.path.join(config.unzip_path, "jni") config.assets_path = os.path.join(config.unzip_path, "assets") config.libs_path = os.path.join(config.unzip_path, "libs") if not FileUtils.is_file_exit(config.jar_path) or not FileUtils.is_file_exit(config.xml_path): logging.info("unzip fail,no jar or xml file.") return logging.info("unzip success.") else: config.jar_path = os.path.join(config.unzip_path, "classes.jar") shutil.copy(config.sdk_path, config.jar_path) logging.info("start decompile java.") count = self.get_class_file(config.jar_path) if self.cfr_decompile(config.jar_path, count): logging.info("decompile java success.") else: logging.info("decompile java error.") logging.info("start decompile smali.") if self.smali_decompile(config.jar_path): logging.info("decompile smali success.") else: logging.info("decompile smali error.") self.scan(is_aar) def scan(self, is_aar): scanners = [StaticScanner(is_aar), DynamicScanner()] logging.info("start scan..") self.report = "\n\n" for scanner in scanners: self.report += scanner.start() self.report += "" self.save_report() def save_report(self): config.report_path = os.path.join(config.result_path, "report.xml") with open(config.report_path, 'w', encoding='utf-8') as f: f.write(self.report) logging.info("scan success.") # 获取jar中类文件数 def get_class_file(self, jar_path): zf = zipfile.ZipFile(jar_path) total_files = len(zf.namelist()) logging.info("totalfiles:%s" % total_files) count = 0 for s in zf.namelist(): if (".class" in s) and ("$" not in s): count += 1 return count # java,默认输入的文件为标准格式 def cfr_decompile(self, jar_path, count): cfr_path = os.path.join(config.TOOL_PATH, "cfr_0_96.jar") starttime = time.time() counter = 0 process = subprocess.Popen(["java", "-jar", cfr_path, jar_path, "--outputdir", config.java_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while True: if (time.time() - starttime) < 2000: line = process.stdout.readline() if not line: return True if str.encode("Processing") in line: counter += 1 else: subprocess.Popen.kill(process) logging.warning(u"超时停止转换,本次仅转换百分之%d.尝试重新转换" % (round(counter * 100 / count))) break return False # smali jar->dex->smali def smali_decompile(self, jar_path): dx_path = os.path.join(config.TOOL_PATH, "dx.jar") dex_path = os.path.join(config.unzip_path, "classes.dex") baksmali_jar_path = os.path.join(config.TOOL_PATH, "baksmali.jar") process = subprocess.Popen(["java", "-jar", dx_path, "--dex", "--output", dex_path, jar_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) process.communicate() if FileUtils.is_file_exit(dex_path): try: command = 'java -jar \"%s\" -o \"%s\" \"%s\"' % (baksmali_jar_path, config.smali_path, dex_path) p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) ret = p.communicate() if FileUtils.is_dir_empty(config.smali_path): logging.error(u"反编译smali失败") return False except Exception as e: logging.error(u"反编译smali失败,原因:%s", e) return False return True def _init_path(self): config.sdk_path = self.sdk_path config.result_path = os.path.join(config.RESULT_PATH, self.result_dir_name) config.temp_path = os.path.join(config.TEMP_PATH, self.result_dir_name) config.unzip_path = os.path.join(config.temp_path, "unzip") config.decompile_path = os.path.join(config.temp_path, "decompile") config.java_path = os.path.join(config.decompile_path, "java") config.smali_path = os.path.join(config.decompile_path, "smali") if not os.path.exists(config.result_path): os.mkdir(config.result_path, 0o777) if not os.path.exists(config.temp_path): os.mkdir(config.temp_path, 0o777) if not os.path.exists(config.decompile_path): os.mkdir(config.decompile_path, 0o777) if not os.path.exists(config.unzip_path): os.mkdir(config.unzip_path, 0o777) def _init_log(self): logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename=r'%s%s%s.log' % ( config.result_path, os.sep, "info"), filemode='a') ################################################################################################# # 定义一个StreamHandler,将INFO级别或更高的日志信息打印到标准错误,并将其添加到当前的日志处理对象# console = logging.StreamHandler() console.setLevel(logging.INFO) formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') console.setFormatter(formatter) logging.getLogger('').addHandler(console) ################################################################################################ # 清空temp目录,可选 def delete(self): FileUtils.delete_dirs(config.temp_path) if __name__ == '__main__': pass ================================================ FILE: utils/md5.py ================================================ # coding: utf-8 __author__ = 'deff' ''' md5相关函数 ''' import hashlib class Md5: def __init__(self): pass @staticmethod def md5(words): m = hashlib.md5() m.update(words.encode(encoding='utf-8')) return m.hexdigest().lower() @staticmethod def md5_file(file_path): with open(file_path, mode="rb") as file: m = hashlib.md5() while True: str_read = file.read(1024 * 1024) if not str_read: break m.update(str_read) return m.hexdigest().lower() if __name__ == "__main__": pass # print(Md5.md5(u"test")) # print(Md5.md5_file(u"d:\\test.txt")) ================================================ FILE: utils/sdkinfo.py ================================================ # coding: utf-8 __author__ = 'deff' class SdkInfo: def __init__(self): self.sdk_name = "" self.sdk_size = "" self.sdk_path = "" self.sdk_md5 = "" self.sdk_soname = "" # 其他三方库包 self.sdk_other_libs = [] self.assets_files = [] self.other_libs = [] self.package_name = "" self.version_name = "" self.permissions = [] self.target_sdk_version = "" self.min_sdk_version = "" self.allow_back_up = False self.debuggable = False sdkinfo = SdkInfo() ================================================ FILE: utils/tool.py ================================================ # coding: utf-8 __author__ = 'deff' import re class Tools: @staticmethod def xml_assent(word): symbola = re.compile('>') word = symbola.sub('<', word) symbolb = re.compile('<') word = symbolb.sub('>', word) symbolc = re.compile('&') word = symbolc.sub('&', word) symbold = re.compile('\'') word = symbold.sub(''', word) symbole = re.compile('\"') word = symbole.sub('"', word) return word ================================================ FILE: utils/ziputils.py ================================================ # coding: utf-8 __author__ = 'deff' import os import os.path import zipfile from utils.fileutils import FileUtils class ZipUtils: @staticmethod def unzip(file_path, dst_path): if not zipfile.is_zipfile(file_path): return False if not os.path.exists(dst_path): os.mkdir(dst_path, 0o777) zfobj = zipfile.ZipFile(file_path) for name in zfobj.namelist(): oriname = name if os.sep == '\\': name = name.replace('/', os.sep) if name.endswith(os.sep): FileUtils.create_dir(os.path.join(dst_path, name)) pass else: filepath = os.path.join(dst_path, name) dir = os.path.dirname(filepath) if not os.path.exists(dir): FileUtils.create_dir(dir) file = open(filepath, 'wb') file.write(zfobj.read(oriname)) file.close() return True